youtube api token upload video - c#

I am retriving a token through an website, then I save the token, and refresh token in a database. Then I am writing .net program that uploads video's located on our server to youtube. My problem is to get the program I am making, use the stored token. I am using one of google's examples to upload the video. But the program should use the already saved token, instead os asking for new credentials.
The current code is this.
UserCredential credential;
//credential.UserCredential(,"",)
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows an application to upload files to the
// authenticated user's YouTube channel, but doesn't allow other types of access.
new[] { YouTubeService.Scope.YoutubeUpload },
"user",
CancellationToken.None
);
}
Console.WriteLine("HER");
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
});
So instead I would like to use an already saved token.
Any help, or a pointer in the right direction would be great. Thanks.

You would use GoogleAuthorizationCodeFlow instead of GoogleWebAuthorizationBroker in order to use the refresh token. See the answer here.

Related

Opening OAuth2 Authorization URL in a browser control

I am trying to learn about the Google's Drive API while I am writing a little program. I am using GoogleWebAuthorizationBroker class for asking the user to give the app permissions, but the drawback is that it is automatically opening a new browser tab in Chrome (as an example):
const string ApplicationName = "TestApp";
string[] scopes = { DriveService.Scope.Drive };
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/drive-dotnet-quickstart");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
I would like to know if there is a way to get the AuthorizationURL so I can show a browser dialog with it, and therefore get the respective token.
How can that be done? Thanks in advance.
Currently the way the client library is written it will automatically open it in the default browser.
There is an issue request already for this feature. GoogleWebAuthorizationBroker in embedded browser? #547
Answer: There is currently no way to get the Authorization url so that you can sow the dialog on your own. The client library is an open source project so you can add it.

Gmail API: forcing the authorization to reprompt the user

The credentials authorizing access to gmailAPI seem to be cached somehow. When I change the client ID and secret, and email address, nothing changes. Also, when I change the scope, nothing changes. I am trying to force the credentials to refresh. Is there a way to force the credentials to reprompt the user?
Is there a file I can find and delete?
I am using c# and the gmail api package from nuget. The code for credentialing is:
_emailAddress = Settings.EmailAddress;
string clientSecret = Settings.ClientSecret;
string clientId = Settings.ClientId;
ClientSecrets clientSecrets = new ClientSecrets {ClientId = clientId, ClientSecret = clientSecret};
UserCredential credential;
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
clientSecrets,
Scopes,
"user",
CancellationToken.None).Result;
_service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Draft Sender", //applicationName,
});
Also, once I credential, my scope is set: cannot change scope until I delete and renew the secret and clientID. Also, it takes two run-throughs in order to generate the credentials, the first resulting in an error, but the second resulting in a prompt to authorize.
I'm pretty sure that this is happening because the credentials are cached somewhere, somehow, even though I haven't specified any storage...but I don't know for sure. Either way, the issue seems to depend on code inside the gmail api package, but I am having trouble finding a solution for what I am dealing with.
Ultimately, I need to deploy a functionality to an ASP website that will access the gmail account as a repository for emails, so I need to have this authorization thing figured out so that the server will have access to the email account upon deployment (or easily after). It is not really necessary (but desired) that it happen without the intermediate error.
Is there a solution (easy or hard) to control this caching process and handle the permissions?
If you don't specify where you are storing the response token, it's stored on:
C:\Users\'Your user'\AppData\Roaming\Google.Apis.Auth
If you want to specify the directory look at this:
(note: you just need to create the directory App_Data in your project)
string path = HostingEnvironment.MapPath("~/App_Data");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "Client_ID",
ClientSecret = "Secret_Client"
},
Scopes,
"me",
CancellationToken.None,
new FileDataStore(path)
).Result;

Google Coordinate API authentication offline

Trying to authenticate the Google coordinate api. Tried the Service acount authentication usisng service account and posted stack flow with this question. Found this anwer and quite describes my question.
What the problem now is the library used is deprecated. Not able to execute the solution said.
var auth = new OAuth2Authenticator<WebServerClient> (provider, GetAuthorization);
// Create the service.
var service = new CoordinateService(new BaseClientService.Initializer()
{
Authenticator = auth
});
can anybody suggest a way to achieve the above code. I have installed the new version for Google APIs OAuth2 Client Library. But didn't found any similar code.
I am able to do the read the api using the below code snippet
using Google.Apis.Auth.OAuth2;
using Google.Apis.Coordinate.v1;
using Google.Apis.Coordinate.v1.Data;
using Google.Apis.Services;
using (var stream = new FileStream(System.Web.HttpContext.Current.Server.MapPath(#"../client_secret.json"), FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
new[] { CoordinateService.Scope.Coordinate },
"user", CancellationToken.None);
}
// Create the service.
var service = new CoordinateService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "test",
});
//builds with time last day 12 am
var locationReq = service.Location.List(teamId, workerMail, (ulong)DateTime.Today.AddDays(-1).ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalSeconds);
var locationResult = locationReq.Execute();
but this method reuires a redirection for the first time. I can't do that in my scenario. so need an offline solution.
Need to authenticate using a browser instance first and can reuse same "refresh token" for all other requests. We can provide a custom folder location to store the "auth token" and the library will use stored token from that folder. Modified source code pasted below:
using (var stream = new FileStream(#"client_secret.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
new[] { CoordinateService.Scope.Coordinate },
"user", CancellationToken.None,new FileDataStore(folder));
}
MG
It looks like you are using a very old version of the library (pre GA).
I recommend you to download the latest Coordinate API, which is available in NuGet - https://www.nuget.org/packages/Google.Apis.Coordinate.v1/.
Then, follow the get started and the OAuth 2.0 pages. You should find all the right documentation there, if something is missing - let us know. Open an issue in our issue tracker.

Transfer ownership of Google Drive documents

We develop application in C# which need to transfer ownership of all Google Drive documents related to the curtain domain to a single certain user without permission of original owner. We are using trial version of Google Apps business account.
In principal, we need to do this: http://screencast.com/t/effVWLxL0Mr4 but in C# code.
Accourding to the documentation, it is implemented in OAuth2 as superadmin functionality. https://support.google.com/a/answer/1247799?hl=en (1).
But document was deprecated and more over we did not find any API call to do that.
Using account of project creator, it is appeared, that he can not access to all files and can not see files is not shared with him.
In Google Admin Console in manage API client access we added access rights to him to access files without permission to files without permission. Link: screencast.com/t/zU9cc6Psyb. We added routes access routes there according to that document link: trovepromo-tf.trove-stg.com/0m1-sds/support.google.com/a/answer/162106?hl=en and tried again.
It did not work out...
Also, We found out that we need to use service account to have access to all data of all users of the domain, therefore we generated API keys for service account link: screencast.com/t/rNKuz6zchwV in the created project and got authenticated in the application using the following code:
var certificate = new X509Certificate2(#"C:\Temp\key.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer("Service account email")
{
User= "admin#domain.com",
Scopes = new[] { DriveService.Scope.Drive }
}.FromCertificate(certificate));
but when we try to get list of folders, we get error :"access_denied", Description:"Requested client not authorized.", Uri:""
Please help us to transfer ownership of one user to another by service account!
Update from 13-08-2014:
Dear, It seems I have problem with user impersonalization.
1) When I use api to connect on behalf of user. During the authentication it redirects to browser and ask permisstion. After that all is completely fine, I can manimulate with folders except one one thing: I can not transfer ownership to him
2) When I use service account without impersonalization, authentication looks like the following:
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(ServiceAccountId)
{
Scopes = new[] { DriveService.Scope.Drive,
DriveService.Scope.DriveAppdata,
DriveService.Scope.DriveFile,
DriveService.Scope.DriveScripts,
DirectoryService.Scope.AdminDirectoryUser,
DirectoryService.Scope.AdminDirectoryGroup,
DirectoryService.Scope.AdminDirectoryOrgunit,
DirectoryService.Scope.AdminDirectoryUserReadonly
},
}.FromCertificate(certificate));
Then I can access to all files shared to service account but (again) I can not transfer the rights.
3) Then I try impersonalize Service account by adding sypeadministrator email account to the user User = myaddress#mydomain.com
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(ServiceAccountId)
{
Scopes = new[] { DriveService.Scope.Drive,
DriveService.Scope.DriveAppdata,
DriveService.Scope.DriveFile,
DriveService.Scope.DriveScripts,
DirectoryService.Scope.AdminDirectoryUser,
DirectoryService.Scope.AdminDirectoryGroup,
DirectoryService.Scope.AdminDirectoryOrgunit,
DirectoryService.Scope.AdminDirectoryUserReadonly
},
User = AdminEmail,
}.FromCertificate(certificate));
Then I have Error:"access_denied", Description:"Requested client not authorized.", Uri:""
How can I impersonalize service account correctly?
Updated 13-08-2014
We found out that basic api for authentication is here: https://developers.google.com/accounts/docs/OAuth2ServiceAccount#creatingjwt
Normally, all what I showed before is an .net implementation of the protocol.
How can we please do impersonalization of of user in .net code. We did not find any working .net implementation of it.
I finally found an answer.
I could impersonalize an account by using the following construction:
Thanks to all, who tried to help me!
var initializer = new ServiceAccountCredential.Initializer(ServiceAccountId)
{
Scopes = scope,
User = AdminEmail1
};
var credential = new ServiceAccountCredential(initializer.FromCertificate(certificate));
var driveService = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName
});

Google Drive API invalid_grant after removing access

I have been writing a desktop application that uses the Google Drive API v2. I have the following code:
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync
(
new ClientSecrets { ClientId = ClientID, ClientSecret = ClientSecret },
new[] { DriveService.Scope.Drive }, "user", CancellationToken.None
)
.Result;
this.Service = new DriveService( new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "My Test App",
} );
var request = this.Service.Files.List();
request.Q = "title = 'foo' and trashed = false";
var result = request.Execute();
The first time I ran this code it opened a browser and asked me to grant permissions to the App, which I did. Everything worked successfully until I realized I was using the wrong Google account. At that point I logged into the wrong Google account and revoked access to my App. Now, whenever I run the same code it throws an exception:
Error:"invalid_grant", Description:"", Uri:""
When I examine the service and request objects, it looks like the oauth_token isn't getting created any more.
I know what I did to mess things up, but I can't figure out how to correct it so I can use a different Google account for testing. What do I need to do?
The stored credentials are persisted using StorageDataStore. You can either call the DeleteAsync() method or manually find and delete the file.

Categories