Get secure file download ticket via .NET API - c#

Using the Microsoft.TeamFoundation .NET client APIs, how can I get a download ticket for a secure file from TFS 2017u2?
Using the Microsoft.TeamFoundation.DistributedTasks.WebApi nuget package, I puffed up the below code in a console app. It successfully retrieves all the metadata and associated properties entered in TFS for the secure file. However, despite passing the "includeDownloadTicket" argument as "true" to the GetSecureFileAsync method, the Ticket property is always null.
I thought perhaps it was a permissions issue but I am in the TFS Admin role and also specifically assigned myself as an admin to the file entry in the web interface.
var credentials = new VssCredentials();
var projectName = "{myProjectName}";
var secureFileId = new Guid("{theSecureFileId}");
var tfsUri = new Uri("https://{tfsBox}/{collection}");
var connection = new VssConnection(tfsUri, credentials);
var taskAgentClient = connection.GetClient<TaskAgentHttpClient>();
var projectClient = connection.GetClient<ProjectHttpClient>();
var project = await projectClient.GetProject(projectName, true);
var secureFile = await taskAgentClient.GetSecureFileAsync(project.Id, secureFileId, true);
var secureFileTicket = secureFile.Ticket;
if (secureFileTicket == null)
{
Console.WriteLine(
"No download ticket was provided by the TFS for the requested Secure File.");
return;
}

Your thought is right. This is related to the permission. For security reason, normal users are limited to download the secure files. The permission you can set is "Reader", "User" and "Administrator" for normal users while it requires "ViewSecrets" permission to include the download ticket.
So you cannot download the secure files for now.

Related

How can an authenticated user access the drive that is publicly accessible?

With this code, I am able to get the files that have been shared to the service account email.
But, when I shared the folder (that was not owned by me, but is publicly accessible) from a different email it is not displayed in the list.
Is there any way an authenticated user can access the drive folder that is publicly accessible, but which I won't own?
var serviceAccountEmail = "";
var certificate = new X509Certificate2(_credentialsService.GetCredentialPath(), "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { DriveService.Scope.Drive }
}.FromCertificate(certificate));
var service = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = credential
});
Getting Drive Details
Google.Apis.Drive.v3.FilesResource.ListRequest FileListRequest = service.Files.List();
// for getting folders only.
//FileListRequest.Q = "mimeType='application/vnd.google-apps.folder'";
FileListRequest.Fields = "nextPageToken, files(id, name)";
FileListRequest.Corpora = "allDrives";
FileListRequest.Q = "sharedWithMe";
FileListRequest.IncludeItemsFromAllDrives = true;
FileListRequest.SupportsAllDrives = true;
// List files.
IList<Google.Apis.Drive.v3.Data.File> files = FileListRequest.Execute().Files;
List<GoogleDriveFile> FileList = new List<GoogleDriveFile>();
Sharing Process:
I shared the file to the service account email, from my personal google email.
And See it is still not available, the image that I owned only is shared. Which is my problem.
Sending the link of a publicly viewable file is not the same as sharing the file
Your screen looks like this:
This means that you have view-only access to the file
If you had edit access to the file, the screen would look as following:
Thus, since you are not an editor of the public file, you cannot add another viewer / editor to this file and consecuently it will not appear in the sharedWithMe of the user to whom you sent the email - no matter if this user is an actual suer or a service account
Solution:
If you need to explicitly share the file with the service account, your options are
to obtain edit access to the public file (if feasible)
create a copy of the respective file onto your own Drive (if copying is not disabled) and share your version explicitly with the service account

Service Account authentication to upload a file to Google Drive

I need to upload a file to Google Drive from my Web Application. I need to use Service Account authentication. I have read Google Drive guide here: DotNetQuickStart and this tutorial for authentication Authentication Google Drive MVC but i don't know what i need to do.
In order to Google Drive guide i have set the parameter to Google Developers Page.
I have download and implemented secret.json file to my project and i have add this code to my project:
public static Google.Apis.Drive.v2.Data.File uploadFile(string _uploadFile, string _parent)
{
string[] scopes = new string[] { DriveService.Scope.Drive }; // Full access
var keyFilePath = #"c:\file.p12"; // Downloaded from https://console.developers.google.com
var serviceAccountEmail = "xx#developer.gserviceaccount.com"; // found https://console.developers.google.com
//loading the Key file
var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = scopes
}.FromCertificate(certificate));
But i can't understand what to set in keyFilePath and serviceAccountEmail. How can i set this code?Thanks to all
You will need the P12 key file instead of secret.json
Go to https://console.developers.google.com/iam-admin/serviceaccounts --> select your project --> click on the 3 vertical dots located at the right side of the listed Service account --> Create key --> you will see the below dialog

Analytics Reporting API V4 Client Library for .NET

I'm trying to get some data from our google analytics instance and I'd like to use the Analytics Reporting API V4 Client Library for .NET (https://developers.google.com/api-client-library/dotnet/apis/analyticsreporting/v4) so that I can bake some of this data into an administration site we have built. I'm having trouble finding any examples of using this code and the documentation seems to be incredibly sparse. I would like to use a service account to authorize as we only need to view data associated with the analytics account which we control.
If anyone could provide some sample code or point me in the right direction to get some basic report data using the .net api, it would be greatly appreciated
Calling the Google Analytics Reporting API from C# is not particularly difficult, however all of the necessary steps do not seem to be outlined very clearly in the Google Analytics API documentation. I will try to list them all out here. While YMMV, I believe these steps to be correct as of 7/20/2016.
You can start by creating a new C# project. We'll make a console application to test called GoogleAnalyticsApiConsole. Once the project is created, we'll add a reference to the Google Analytics Reporting API V4 Client Library for .NET using the NuGet Package Manager Console (found under the Tools menu in Visual Studio 2015). Fire up the Console and issue the following command at the PM> prompt:
PM> Install-Package Google.Apis.AnalyticsReporting.v4
Installing that package will download the client libraries needed to call the Google Analytics Reporting web services along with a number of other dependencies.
In order to call the web services, you'll need to set up OAuth 2.0 access for your application. The documentation for this setup can be found here, but I will summarize below:
Login to the Google Cloud Platform Console: https://console.cloud.google.com/. Be sure to login with an account that has access to the Google Analytics accounts you are trying to query with the reporting API.
Click the Google Cloud Platform menu and select API Manager.
On the left hand side, click Credentials and then create a new project called Google Analytics API Console. Give it some time to create the new project.
After the project is created, click Credentials again if it is not already selected, and then click the OAuth Consent Screen link in the right panel. Set the Product name shown to users to Google Analytics API Console and then click Save.
Click Credentials again, and then click Create Credentials, and choose OAuth Client ID. Select Other for Application type and then enter Google Analytics API Console as the Name and click Create.
After the credential is created, you will be presented with a client ID and a client secret. You can close the dialog window.
Now, under Credentials you should see an entry under OAuth 2.0 client ids. Click the download icon to the far right of that entry to download the client_secret.json file (this file will have a much longer name). Add that file to your project at the root level once it has been downloaded and rename it to client_secret.json.
Now that the OAuth 2.0 credential has been created, we need to enable it to call the Reporting API. Select Overview and make sure Google APIs is selected in the right panel. Type in Reporting in the search box and select Analytics Reporting API V4 from the list. On the next screen, click Enable. Once this API has been enabled, you should be able to see it under the Enabled APIs list in the right panel.
Now that we've created our project and created our OAuth 2.0 credential, it is time to call the Reporting API V4. The code listed below will use the Google API and the client_secret.json file to create a Google.Apis.Auth.OAuth2.UserCredential to query the Reporting API for all sessions between the given date range for a View. The code is adapted from the Java example here.
Before executing the code, be sure to set the Build Action on the client_secret.json file to Content and the Copy to Output Directory setting to Copy if newer. There are also two variables that need to be properly set. First, in the GetCredential() method, set the loginEmailAddress value to the email address used to create the OAuth 2.0 credential. Then, in the Main method, be sure to set the ViewId in the reportRequest variable to the view that you want to query using the Reporting API. To find the ViewId, log in to Google Analytics and select the Admin tab. From there, select the view you want to query in the View dropdown on the far right and select View Settings. The View ID will be displayed under Basic Settings.
The first time the code is executed, it will bring up a web page asking if you want to allow the Google Analytics API Console to have access to the API data. Select Allow to proceed. From then on that permission will be stored in the GoogleAnalyticsApiConsole FileDataStore. If that file is deleted, then permission will need to be granted again. That file can be found in the %APPDATA%\GoogleAnalyicsApiConsole directory.
Please note that I believe this scenario will meet the needs of the OP. If this application were to be distributed to clients, then a different OAuth 2.0 scheme would most likely be necessary.
Here is the code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.AnalyticsReporting.v4;
using Google.Apis.AnalyticsReporting.v4.Data;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Util.Store;
namespace GoogleAnalyticsApiConsole
{
class Program
{
static void Main(string[] args)
{
try
{
var credential = GetCredential().Result;
using(var svc = new AnalyticsReportingService(
new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = "Google Analytics API Console"
}))
{
var dateRange = new DateRange
{
StartDate = "2016-05-01",
EndDate = "2016-05-31"
};
var sessions = new Metric
{
Expression = "ga:sessions",
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 = "<<your view id>>"
};
var getReportsRequest = new GetReportsRequest {
ReportRequests = new List<ReportRequest> { reportRequest } };
var batchRequest = svc.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));
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
static async Task<UserCredential> GetCredential()
{
using (var stream = new FileStream("client_secret.json",
FileMode.Open, FileAccess.Read))
{
const string loginEmailAddress = "<<your account email address>>";
return await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { AnalyticsReportingService.Scope.Analytics },
loginEmailAddress, CancellationToken.None,
new FileDataStore("GoogleAnalyticsApiConsole"));
}
}
}
}
Here are the steps updated for Sep 2019.
First, understand that there are two choices under OAuth: User credentials and Service Account credentials. User credentials are meant to be used when you do not know which Google Analytics account you will be connected to, hence the user grants your application permission. Service Account credentials are meant to be used, e.g. if you build your own dashboard for your company to display Google Analytics data.
Most of the time, if you need programmatic access to Analytics data, it is the second case.
The steps below should get you started for a simple C# example. Note that the Google web console part may vary slightly, but should be easy to find nevertheless.
Go to the Google API Console. Create a Project if prompted.
Go to Service accounts.
Create a new Service Account. You should have an account with a random-generated email address (mine is ending with xxx#xxx.iam.gserviceaccount.com)
Find the Create Key button. Choose JSON and download the file. This is your private key and your only copy. Do not lose it.
Go to your Google Analytics admin panel. Grant access to the Service Account using its email address, the same way you would grant access to other users.
The Google configuration is done. Now jump into Visual Studio.
Create a new C# Console Project.
Get the Nuget package Google.Apis.AnalyticsReporting.v4. It should also automatically download the core packages as well.
Grab the JSON file downloaded earlier, put it in the project, set its Property to Content and Copy Always.
using Google.Apis.AnalyticsReporting.v4.Data;
using System;
namespace ConsoleApplication {
class Program {
static void Main(string[] args) {
var credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromFile("serviceAccount.json")
.CreateScoped(new[] { Google.Apis.AnalyticsReporting.v4.AnalyticsReportingService.Scope.AnalyticsReadonly });
using (var analytics = new Google.Apis.AnalyticsReporting.v4.AnalyticsReportingService(new Google.Apis.Services.BaseClientService.Initializer {
HttpClientInitializer = credential
})) {
var request = analytics.Reports.BatchGet(new GetReportsRequest {
ReportRequests = new[] {
new ReportRequest{
DateRanges = new[] { new DateRange{ StartDate = "2019-01-01", EndDate = "2019-01-31" }},
Dimensions = new[] { new Dimension{ Name = "ga:date" }},
Metrics = new[] { new Metric{ Expression = "ga:sessions", Alias = "Sessions"}},
ViewId = "99999999"
}
}
});
var response = request.Execute();
foreach (var row in response.Reports[0].Data.Rows) {
Console.Write(string.Join(",", row.Dimensions) + ": ");
foreach (var metric in row.Metrics) Console.WriteLine(string.Join(",", metric.Values));
}
}
Console.WriteLine("Done");
Console.ReadKey(true);
}
}
}
I had the same experience: Google's documentation is pretty in-depth but is pretty terrible at giving clear examples of how to connect with .NET.
One key thing I finally realized is that you can either connect using an OAuth2 credential or a service account credential. If you own your Analytics account, use a service account. If you're needing to connect to other users' Analytics accounts, use OAuth2.
There seem to be quite a few examples online of how to get Analytics API data using an OAuth2 credential, but I own my Analytics account and just wanted to pull data from it. I figured out how to connect to the Analytics Reporting API v4 using a ServiceAccountCredential, and I wrote an answer on a similar Stack Overflow question with all the details.
Here Is the code you actually looking for-
protected void Page_Load(object sender, EventArgs e)
{
IRestRequest request = new RestRequest("", Method.POST, DataFormat.Json);
string url = "https://analyticsreporting.googleapis.com/v4/reports:batchGet";
RestClient restClient = new RestClient();
RestRequest Tokenrequest = new RestRequest();
Tokenrequest.AddQueryParameter("client_id", "<CLIENTID>");
Tokenrequest.AddQueryParameter("client_secret", "<CLIENTSECRET>");
Tokenrequest.AddQueryParameter("grant_type", "refresh_token");
Tokenrequest.AddQueryParameter("refresh_token", "<REFRESH_TOKEN>");
restClient.BaseUrl = new System.Uri("https://oauth2.googleapis.com/token");
restClient.Post(Tokenrequest);
var responseToken = restClient.Execute(Tokenrequest);
//Response.Write(responseToken);
dynamic Tokendata = JObject.Parse(responseToken.Content);
var newToken = Tokendata.access_token.Value;
request.AddHeader("authorization", string.Concat("Bearer "+newToken));
string jsonString = "{" +
"\"reportRequests\": [{" +
"\"dateRanges\" : [{\"" +
"startDate\" :'2021-07-01' ," +
"\"endDate\" : '2021-07-07'" +
"}]," +
"\"metrics\":["+
"{\"expression\":'ga:totalEvents'},"+
"{\"expression\": 'ga:pageviews'}"+
"]," +
"\"dimensions\": ["+
"{\"name\": 'ga:eventCategory'}" +
",{" +
"\"name\": 'ga:eventAction'"+
"},"+
//"{\"name\": 'ga:deviceCategory'}"+
"]," +
"\"dimensionFilterClauses\": [{"+
"\"filters\": [{"+
"\"dimensionName\": 'ga:eventCategory',"+
"\"operator\": 'EXACT',"+
"\"expressions\": ["+
"\"Login_Form"+
"\"]}]}],"+
"\"viewId\":'<VIEWID>'" +
"}]" +
"}";
IRestClient client = new RestClient(url);
request.AddHeader("Content-Type", "application/json; CHARSET=UTF-8");
request.Resource = "";
request.AddParameter("application/json", jsonString, ParameterType.RequestBody);
var response = client.Execute(request);
dynamic jdata = JObject.Parse(response.Content);
var Row_data = jdata.reports[0].data.rows;
Response.Write(Row_data);
}
Read The Document To Get access_token through refresh_token.
https://developers.google.com/identity/protocols/oauth2/web-server#offline

Why office 365 login Cache shows null value?

Hi,
I am working on office 365 login for access the calendar, i have added the services to my project,it work fine without any problem, i have cleared my database and again run the project i could not get the calendar event ,It is not accessible because Cache shows null value,Again i have added the services but still it show null value for Cache,Can you please any one help me to resolve this problem,I am giving my code below.
UserTokenCache Cache;
// constructor
public ADALTokenCache(string user)
{
// associate the cache to the current user of the web app
User = user;
this.AfterAccess = AfterAccessNotification;
this.BeforeAccess = BeforeAccessNotification;
this.BeforeWrite = BeforeWriteNotification;
// look up the entry in the DB
Cache = db.UserTokenCacheList.FirstOrDefault(c => c.webUserUniqueId == User);
// place the entry in memory
this.Deserialize((Cache == null) ? null : Cache.cacheBits);
}
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = new ClientCredential(SettingsHelper.ClientId, SettingsHelper.ClientSecret);
String UserObjectId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(SettingsHelper.Authority, new ADALTokenCache(UserObjectId));
authContext.AcquireTokenByAuthorizationCode(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, SettingsHelper.AADGraphResourceId);
return Task.FromResult(0);
},
Thanks,
Karthik
i have cleared my database and again run the project i could not get the calendar event
In this case, you need to log out and log in again so that the new cache will be stored in the database.
If this does not work, you can also run my AspNetMvc-with-O365 project on GitHub to troubleshoot this issue.
Step#1 Download the sample project AspNetMvc-with-O365.zip.
Step#2 Register an app under Office 365 tenant AD (skip if you have an app registered), declare the Office 365 Exchange Online > Read user mail permission and set the REPLY URL as "http://localhost:2659/".
Step#3 In the web.config file, copy the ClientId, TenantId and Client Secret from Azure AD portal.
Step#4 Run the project in Visual Studio and log in with Azure AD account
The expected result should be as following:
You can also click the "Clear the cache database" button if you have acquire token issues.

Microsoft Graph Client not specified resource in requiredResourceAccessList

I get the following error when I try to retrieve AccessToken.
/MicrosoftGraph/Authorise?error=access_denied&error_description=AADSTS65005%3a+The+client+application+has+requested+access+to+resource+%27https%3a%2f%2fgraph.microsoft.com%2f%27.+This+request+has+failed+because+the+client+has+not+specified+this+resource+in+its+requiredResourceAccess+list.%0d%0aTrace+ID%3a+7cd46ad3-d294-41ad-98ec-6ef06db7a0db%0d%0aCorrelation+ID%3a+4e2a6d3b-b3dd-4a98-b36d-550d8f8c3382%0d%0aTimestamp%3a+2016-01-27+10%3a40%3a12Z
Which is... graph.microsoft.com This request has failed because the client has not specified this resource in its requiredResourceAccess list
It is a multitenant application in Azure Active Directory. I am able to login successfully with one of my email Ids but not with another one.
Where am I going wrong? What am I missing?
Code Snippet:
public ActionResult Login() {
....
Uri authUri = authContext.GetAuthorizationRequestURL(
MicrosoftGraphSettings.O365UnifiedAPIResource,
MicrosoftGraphSettings.ClientId,
loginRedirectUri,
UserIdentifier.AnyUser,
null);
string authUriAsString = authUri.ToString();
return Redirect(authUriAsString);
}
public async Task<ActionResult> Authorise()
{
Uri loginRedirectUri = new Uri(Url.Action("Authorise", "MicrosoftGraph", null, Request.Url.Scheme));
var authContext = new AuthenticationContext(MicrosoftGraphSettings.AzureADAuthority);
var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
Request.Params["code"],
loginRedirectUri,
new ClientCredential(MicrosoftGraphSettings.ClientId, MicrosoftGraphSettings.ClientSecret),
MicrosoftGraphSettings.O365UnifiedAPIResource);
}
I have tried the following
public static string O365UnifiedAPIResource = #"https://graph.microsoft.com/";
//public static string O365UnifiedAPIResource = #"https://graph.windows.net/";
Using the second one, the authentication succeeds but whenever I use my existing code to access list of files in OneDrive for business account or create a text file, it throws an Unauthorized exception while making an API call.
That error message indicates that your application doesn't have delegated permissions for the "Microsoft Graph" (https://graph.microsoft.com/) resource.
Please use the Azure Management Portal (https://manage.windowsazure.com) to configure delegated permissions for that resource. Find the app -> Configure -> "permissions to other applications" -> "Add application" -> select "Microsoft Graph".
Since you're able to get a token for "https://graph.windows.net/" your application already has permissions configured for the "Windows Azure Active Directory" resource, but that is a different resource than "Microsoft Graph".

Categories

Resources