I'm trying to access my Google Contacts using OAuth 2.0 for Server to Server Applications in a ASP.net MVC application but I'm having some troubles trying to retrieve the token. "test-470272c3a5fa.json" is the file I downloaded from google api console and is currently on my desktop. Any idea?
Here is my code:
public class GoogleContactsApiInterface
{
public GoogleContactsApiInterface()
{
ServiceAccountCredential serviceAccountCredential;
string[] scopes = { "https://www.google.com/m8/feeds/" };
string keyPath = "C:\\Users\\55122545\\Desktop\\test-470272c3a5fa.json";
using (var stream = new FileStream(keyPath, FileMode.Open, FileAccess.Read))
{
serviceAccountCredential = GoogleCredential.FromStream(stream)
.CreateScoped(scopes)
.UnderlyingCredential as ServiceAccountCredential;
OAuth2Parameters parameters = new OAuth2Parameters();
parameters.AccessToken = serviceAccountCredential.Token.AccessToken;
parameters.RefreshToken = serviceAccountCredential.Token.RefreshToken;
RequestSettings rs = new RequestSettings("testApp", parameters);
rs.AutoPaging = true;
ContactsRequest cr = new ContactsRequest(rs);
Feed<Contact> f = cr.GetContacts();
foreach (Contact c in f.Entries)
{
//do something
}
}
}
}
Related
Our code is currently using the old Microsoft.WindowsAzure.Storage libraries for blob storage access in Azure. I am trying to use the new v12 Azure.Storage.Blobs libraries to replace the old ones, however I cannot figure out how to decrypt/encrypt the blobs. The MS docs (https://learn.microsoft.com/en-us/azure/storage/blobs/storage-encrypt-decrypt-blobs-key-vault?tabs=dotnet) helpfully say that the v12 code snippets aren't ready yet, so there are no code examples.
The old code is like this:
var tokenProvider = new AzureServiceTokenProvider();
var cloudResolver = new KeyVaultKeyResolver(
new KeyVaultClient.AuthenticationCallback(_tokenProvider.KeyVaultTokenCallback));
var encryptionThingy = await cloudResolver.ResolveKeyAsync(<Key Vault URL> + "/keys/" + <key name>, CancellationToken.None);
var policy = new BlobEncryptionPolicy(encryptionThingy, cloudResolver);
var options = new BlobRequestOptions() { EncryptionPolicy = policy };
await <ICloudBlob Instance>.DownloadToStreamAsync(<stream>, null, options, null);
So far with the new code I've gotten here:
var azureKeys = new KeyClient(new Uri(<key vault url>), new DefaultAzureCredential());
var encKey = azureKeys.GetKey(<key name>);
ClientSideEncryptionOptions encryptionOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0)
{
KeyEncryptionKey = (IKeyEncryptionKey)key
};
var bsClient = new BlobServiceClient(cStr, new SpecializedBlobClientOptions() { ClientSideEncryption = encryptionOptions });
var containerClient = new BlobContainerClient(cStr, containerName);
bClient = containerClient.GetBlobClient(<blob name>);
Of course this throws an exception because KeyVaultKey cannot be converted to IKeyEncryptionKey. So my questions are
Can the key be converted to an IKeyEncryptionKey easily, and how?
Can a key resolver be easily retrieved from the Azure SDKs, and how so?
I'm presuming there are ways to do this that don't involve creating our own implementations of the interfaces, but MS in their infinite wisdom didn't see fit to add those few lines to their documentation.
I write a simple demo for you. Just try the C# console app below about azure blob client-encryption with azure KeyVault:
using System;
using Azure.Identity;
using Azure.Security.KeyVault.Keys.Cryptography;
using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Specialized;
namespace BlobEncyptionWithBlob
{
class Program
{
static void Main(string[] args)
{
string keyVaultName = "";
string keyName = "";
string kvUri = "https://" + keyVaultName + ".vault.azure.net/keys/" + keyName;
string storageConnStr = "";
string containerName = "";
string encyptBlob = "encypt.txt";
string localblobPath = #"C:\Users\Administrator\Desktop\123.txt";
string localblobPath2 = #"C:\Users\Administrator\Desktop\123-decode.txt";
//Below is to use recommended OAuth2 approach
//string clientID = "<OAuth Client ID>";
//string clientSecret = "<OAuth Secret>";
//string tenant = "<OAuth Tenant ID>";
//var cred = new ClientSecretCredential(tenant, clientID, clientSecret);
//This is what you use to directly replace older AppAuthentication
var cred = new DefaultAzureCredential();
CryptographyClient cryptoClient = new CryptographyClient(new Uri(kvUri), cred);
KeyResolver keyResolver = new KeyResolver(cred);
ClientSideEncryptionOptions encryptionOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0)
{
KeyEncryptionKey = cryptoClient,
KeyResolver = keyResolver,
KeyWrapAlgorithm = "RSA-OAEP"
};
BlobClientOptions options = new SpecializedBlobClientOptions() { ClientSideEncryption = encryptionOptions };
var blobClient = new BlobServiceClient(storageConnStr,options).GetBlobContainerClient(containerName).GetBlobClient(encyptBlob);
//upload local blob to container
blobClient.Upload(localblobPath);
//If you want to modify the meta data you have to copy the exisiting meta, think there is a bug in the library that will wipe out the encryptiondata metadata if you write your own meta
var myMeta = new Dictionary<string, string>();
myMeta.Add("comment", "dis file is da shiznit");
foreach (var existingMeta in blobClient.GetProperties().Value.Metadata)
{
if (!myMeta.ContainsKey(existingMeta.Key))
{
myMeta.Add(existingMeta.Key, existingMeta.Value);
}
}
blobClient.SetMetadata(myMeta);
//Download from container to see if it is decided
blobClient.DownloadTo(localblobPath2);
}
}
}
Result:
My local .txt file content:
Upload to blob and its content, it has been encrypted :
Download to local again and its content, it has been decoded:
Currently i am trying to send message from C# to Google chat Room ,tried Authentication using following code
UserCredential credential;
var jsonPath = "";
jsonPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "client_secrets.json");
//using (var stream = new FileStream(jsonPath, FileMode.Open, FileAccess.Read))
using (var stream = new FileStream(jsonPath, FileMode.Open, FileAccess.Read))
{
string[] scopes = new[] { "https://www.googleapis.com/auth/chat"};
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
scopes,
"admin#XXXX.XX", CancellationToken.None, new FileDataStore("C:\\AlexaHangout\\Google.Hangout.Auth.Store")).Result;
}
// Create the service.
var service = new HangoutsChatService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "VSAHangout",
})
Message msg = new Message();
msg.Text = "Hi USER";
msg.Sender = new User() { DisplayName = "Test", Name = "admin#XXXXX.XX", ETag = "12345", Type = "BOT" };
msg.Space = new Space() { Name = "spaces/XXXXXXXX", DisplayName = "ViSev" }
SpacesResource.MessagesResource.CreateRequest req = new SpacesResource.MessagesResource(service).Create(msg, "spaces/XXXXXXX");
var result = req.Execute();
Authenication is working fine but when i trying to send message getting following error.
{"ClassName":"Google.GoogleApiException","Message":"Google.Apis.Requests.RequestError\r\nRequest had insufficient authentication scopes. [403]\r\nErrors [\r\n\tMessage[Request had insufficient authentication scopes.] Location[ - ] Reason[forbidden] Domain[global]\r\n]\r\n","Data":null,"InnerException":null,"HelpURL":null,"StackTraceString":" at Google.Apis.Requests.ClientServiceRequest`1.d__31.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at Google.Apis.Requests.ClientServiceRequest`1.Execute()\r\n at HangoutSample.WebForm1.CheckService() in E:\\mahesh Works\\HangoutSample\\HangoutSample\\WebForm1.aspx.cs:line 70","RemoteStackTraceString":null,"RemoteStackIndex":0,"ExceptionMethod":"8\nMoveNext\nGoogle.Apis, Version=1.43.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab\nGoogle.Apis.Requests.ClientServiceRequest`1+d__31\nVoid MoveNext()","HResult":-2146233088,"Source":"Google.Apis","WatsonBuckets":null}
Judging by this maybe your scope should be set to:
string[] scopes = new[] { "https://www.googleapis.com/auth/chat.bot"};
Don't forget to delete the previously generated token.json with the old scope.
I'm building a Web Api and I need to get data from a Google Analytics report.
I need to get data from a Google Analytics view.
But I think I'm facing an issue with the credentials.
Here is the code I'm using.
var filepath = "XXXXXXXXXXXXXXXXx";
var viewid = "XXXXXXXXXX";
GoogleCredential credentials;
using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read))
{
string[] scopes = { AnalyticsReportingService.Scope.AnalyticsReadonly };
var googleCredential = GoogleCredential.FromStream(stream);
credentials = googleCredential.CreateScoped(scopes);
}
var reportingService = new AnalyticsReportingService(
new BaseClientService.Initializer
{
HttpClientInitializer = credentials
});
var dateRange = new DateRange
{
StartDate = "2018-06-01",
EndDate = "2018-06-25"
};
var sessions = new Metric
{
Expression = "ga:pageviews",
Alias = "Sessions"
};
var date = new Dimension { Name = "ga:date" };
var reportRequest = new ReportRequest
{
DateRanges = new List<DateRange> { dateRange },
Dimensions = new List<Dimension> { date },
Metrics = new List<Metric> { sessions },
ViewId = viewid
};
var getReportsRequest = new GetReportsRequest
{
ReportRequests = new List<ReportRequest> { reportRequest }
};
var batchRequest = reportingService.Reports.BatchGet(getReportsRequest);
var response = batchRequest.Execute();
foreach (var x in response.Reports.First().Data.Rows)
{
Console.WriteLine(string.Join(", ", x.Dimensions) + " " + string.Join(", ", x.Metrics.First().Values));
}
I'm getting the following issue:
Google.GoogleApiException: 'Google.Apis.Requests.RequestError
User does not have any Google Analytics account. [403]
Errors [
Message[User does not have any Google Analytics account.] Location[ - ]
Reason[forbidden] Domain[global]
Thanks,
Andrés
Make sure the credentials´ user has access to the Google Analytics account you are trying to access.
You must grant it access in the analytics page, just as you would for any other user.
Hello I have created a windows application which uploads image from hdd to google cloud server.
My code was working perfectly but after changing bucket name it is not working.
My both buckets are in the same project and I have given OAuth 2.0 to my project.
even there is no error showing while processing. Please help me.
string bucketForImage = ConfigurationManager.AppSettings["BucketName"];
string projectName = ConfigurationManager.AppSettings["ProjectName"];
string Accountemail = ConfigurationManager.AppSettings["Email"];
var clientSecrets = new ClientSecrets();
clientSecrets.ClientId = ConfigurationManager.AppSettings["ClientId"];
clientSecrets.ClientSecret = ConfigurationManager.AppSettings["ClientSecret"];
string gcpPath = #"D:\mrunal\tst_mrunal.png";
var scopes = new[] { #"https://www.googleapis.com/auth/devstorage.full_control" };
var cts = new CancellationTokenSource();
var userCredential = await GoogleWebAuthorizationBroker.AuthorizeAsync(clientSecrets, scopes, Accountemail, cts.Token);
var service = new Google.Apis.Storage.v1.StorageService();
var bucketToUpload = bucketForImage;
var newObject = new Google.Apis.Storage.v1.Data.Object()
{
Bucket = bucketToUpload,
Name = "mrunal.png"
};
fileStream = new FileStream(gcpPath, FileMode.Open);
var uploadRequest = new Google.Apis.Storage.v1.ObjectsResource.InsertMediaUpload(service, newObject,
bucketToUpload, fileStream, "image/png");
uploadRequest.OauthToken = userCredential.Token.AccessToken;
await uploadRequest.UploadAsync();
//uploadRequest.UploadAsync();
if (fileStream != null)
{
fileStream.Dispose();
}
Did you try this same code for the older bucket and it worked? It seems to me that there is an issue with line of code, uploadRequest.OauthToken = userCredential.Token.AccessToken. You are calling the Token.AccessToken directly from the userCredentials. These methods should be called from the userCredentials.Result.
I am trying to use the following code to add files to my document library on Sharepoint Office365 using web services.
public void SaveFileToSharePoint(string fileName)
{
try
{
var copyService = new Copy { Url = "https://mydomain.com/_vti_bin/copy.asmx", Credentials = new NetworkCredential("username", "password", "domain") };
var destURL = "https://mydomain.com/Shared%20Documents/" + Path.GetFileName(fileName);
string[] destinationUrl = { destURL };
CopyResult[] cResultArray;
var fFiledInfo = new FieldInformation { DisplayName = "Description", Type = FieldType.Text, Value = Path.GetFileName(fileName) };
FieldInformation[] fFiledInfoArray = {fFiledInfo};
var copyresult = copyService.CopyIntoItems(destURL, destinationUrl, fFiledInfoArray, File.ReadAllBytes(fileName), out cResultArray);
var b = copyresult;
}
catch (Exception ex)
{
}
}
I receive the error "Object Moved". The URL loads the WSDL in the browser though. If there is a better way to upload and get files from SharePoint on Office365 online I would entertain that as well. Thanks.
as the ASMX webservices are deprecated you should check out the "new" rest services of sharepoint. ON MSDN you find information about it
Or you can use the Client object model which would be my favorite way. The following example shows basic usage, to connect to SharePoint online check out the following link
using(ClientContext context = new ClientContext("http://yourURL"))
{
Web web = context.Web;
FileCreationInformation newFile = new FileCreationInformation();
newFile.Content = System.IO.File.ReadAllBytes(#"C:\myfile.txt");
newFile.Url = "file uploaded via client OM.txt";
List docs = web.Lists.GetByTitle("Documents");
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(newFile);
context.ExecuteQuery();
}
Using roqz suggestions above, here is the ultimate solution I came up with to place files in the SharePoint 2013 Office 365 document library and to retrieve them by name:
public void SaveFileToSharePoint(string fileName)
{
using (var context = new ClientContext("https://mydomain.com/"))
{
var passWord = new SecureString();
foreach (var c in "MyPassword") passWord.AppendChar(c);
context.Credentials = new SharePointOnlineCredentials("me#mydomain.com", passWord);
var web = context.Web;
var newFile = new FileCreationInformation {Content = File.ReadAllBytes(fileName), Url = Path.GetFileName(fileName)};
var docs = web.Lists.GetByTitle("Documents");
docs.RootFolder.Folders.GetByUrl("Test").Files.Add(newFile);
context.ExecuteQuery();
}
}
public void GetFileFromSharePoint(string fileName, string savePath)
{
using (var context = new ClientContext("https://mydomain.com/"))
{
var passWord = new SecureString();
foreach (var c in "MyPassword") passWord.AppendChar(c);
context.Credentials = new SharePointOnlineCredentials("me#mydomain.com", passWord);
var web = context.Web;
var myFile = web.Lists.GetByTitle("Documents").RootFolder.Folders.GetByUrl("Test").Files.GetByUrl(fileName);
context.Load(myFile);
context.ExecuteQuery();
using (var ffl = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, myFile.ServerRelativeUrl))
{
using (var destFile = File.OpenWrite(savePath + fileName))
{
var buffer = new byte[8*1024];
int len;
while ((len = ffl.Stream.Read(buffer, 0, buffer.Length)) > 0)
{
destFile.Write(buffer, 0, len);
}
}
}
}
}