Append a Stringsegment to a MS Graph Request with GraphServiceClient - c#

Is it possible to append a segment to a MS Graph GraphServiceClient Request and fetch that resource?
The scenario:
I want to get the root site of a group (more specifically its weburl property)
https://graph.microsoft.com/v1.0/groups/{group-id}/sites/root
but it is not possible to append the /root segment with the QueryBuilder and enumerating sites is not allowed and throws an exception
var task = graphClient.Groups[group.Id].Sites.Request().GetAsync() // exception
I can get the string for the request
var url = graphClient.Groups[group.Id].Sites.Request().AppendSegmentToRequestUrl("root")
But then I would need a method to which I can supply a full Graph Url, for example:
graphClient.MakeRequest(url).GetAsync()
I know I could use the HttpClient Class but that would introduce a different pattern to fetch Graph Resources and I would like to avoid that.
Edit - Solution
Seems as if you have to play with the RequestBuilders that are available under the Microsoft.Graph namespace until you find one that matches the type of your request, all the others return null.
var requestBuilder = client.Groups["guid-of-group"].Sites;
var url = requestBuilder.AppendSegmentToRequestUrl("root");
GroupRequestBuilder builder = new GroupRequestBuilder(url, client);
var result = await builder.Request().GetAsync();

Perharps you could try something like this and pass in the graphServiceClient and created url to a new instance of a request builder.
// create the url from the builders
var requestBuilder = graphClient.Groups["groupId"].Sites;
var url = request.AppendSegmentToRequestUrl("root");
// we have to create a new builder as the url property cannot be set/modified publicly
GroupSitesCollectionRequestBuilder groupSitesCollectionRequestBuilder = new GroupSitesCollectionRequestBuilder(url, graphClient);
// Make the call
var result = await groupSitesCollectionRequestBuilder.Request().GetAsync();

Related

AWS API Gateway - Call GET Method with C# SDK

I have an API Gateway that uses IAM authorization. I have a C# application that I'm hoping to call the API with. I started with a GetMethodRequest but I don't see anyway to set the PathPart parameter.
var userId = _remoteCredentials.UserId;
var key = _remoteCredentials.Key;
var client = new AmazonAPIGatewayClient(userId, key, Amazon.RegionEndpoint.USEast2);
GetMethodRequest getMethodRequest = new GetMethodRequest();
getMethodRequest.HttpMethod = HttpMethod.Get.ToString();
getMethodRequest.ResourceId = "4abcde";
getMethodRequest.RestApiId = "aasfasdfs";
var task = Task.Run(async () => await client.GetMethodAsync(getMethodRequest).ConfigureAwait(false));
I was expecting something like the Test-AGInvokeMethod in the Powershell SDK which allows me to set the query string and the path.
$response = Test-AGInvokeMethod
-RestApiId aasfasdfs
-ResourceId 4abcde
-HttpMethod GET
-PathWithQueryString '/etl/upload_url'
Any help is greatly appreciated.
EDIT Below is something of a solution that I ended up using the AWS4RequestSigner is a library that I found on Github
var signer = new AWS4RequestSigner(userId, key);
var destinationUrl = string.Format("https://ad9vxabc123.execute-api.us-east-2.amazonaws.com/dev/etl/summary/latest?tms_id={0}&model_id={1}", _tmsId, _modelId);
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(destinationUrl),
};
var signed = Task.Run(async () => await signer.Sign(request, "execute-api", "us-east-2").ConfigureAwait(false));
var signedResult = signed.Result;
The AmazonAPIGatewayClient is for managing your API Gateway e.g. adding new stages or deleting API keys.
You're looking to invoke a method on your API Gateway, like Test-AGInvokeMethod does.
To invoke your API gateway, you need to call the deployed API endpoint using a HTTP client.
.NET's in-built HttpClient is a good start.

ASP.Net Core 3.1 Identity - Generating Password Reset Token Issue

I am developing a site where the users will be able to click a "Forgot My Password" button to reset their passwords.
Currently, once the email has been validated, the following code should generate a token to be emailed to the user:
if(validUser != null)
{
var generationTime = DateTime.Now;
var pwToken = await _userManager.GeneratePasswordResetTokenAsync(validUser);
await _userManager.UpdateAsync(validUser);
var url = $"https://{Request.Host}/verify/{HttpUtility.UrlEncode(pwToken)}";
//EmailHelper.SendMagicLinkEmail(validUser, url, Request);
return new RedirectResult("/");
}
All information online regarding this seems to suggest that this is the way to do things. I have set up the Default token providers in the Startup.csfile too:
identityOptions: o => {
o.User.RequireUniqueEmail = true;
o.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultProvider;
o.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultProvider;
},
Yet when a token is generated it produces a large token such as this:
CfDJ8CnvAYtZf+1IjXpKUM7+umDYEaImg2SPFglPX3Y8RmYpEfg5zpK8xL54lvlbJUd54CaIzzYlff/GU+xKKS8mmG5UdC1zdk24nOsJNpIlmC3P5V72BchS4P9DGFTR77XiKbMAAYymnMomS2zCdTKh+E4bn9RI6FVinMecG1HR7nSHmOI2McbXHBFTanI/0uwxH5WI/Dj4AFTBP39ni7mfKkeWz2nJ5pTemELJJ6pYP50+
The problem here is obviously the forward slashes, which cause issues with routing so are encoded out here:
var url = $"https://{Request.Host}/verify/{HttpUtility.UrlEncode(pwToken)}";
The problem is that even with that, .Net Core seems to un-encode it and produce the following error when the generated link is accessed:
This error isn't necessarily the issue, and I do understand it's importance. Yet I can't seem to find any explanation as to why this token is behaving this way. All online examples seem to produce a fairly standard GUID style token, not something such as this.
Does anyone know why this might be happening?
Cheers
You may want to try the Url.Action() method:
Example:
var token = userManager.GeneratePasswordResetTokenAsync(user).Result;
var resetLink = Url.Action("ResetPassword","Account", new { token = token }, protocol: HttpContext.Request.Scheme);
var message = "Click here to reset your password";
//Then send your message to the user
Note in the example above the email must be HTML for the link to work
The token looks fairly normal to me.
I think the URL encoding method you'd want to use is Uri.EscapeDataString. What I've personally done is using a UriBuilder and escaped the query string values (in this case for email confirmation):
var uriBuilder = new UriBuilder
{
Scheme = "https",
Host = "my.website.com",
Path = "/confirmEmail",
Query = $"email={Uri.EscapeDataString(email)}&token={Uri.EscapeDataString(token)}"
};
var fullUrl = uriBuilder.Uri.AbsoluteUri;
For you that'd be:
var uriBuilder = new UriBuilder
{
Scheme = "https",
Host = Request.Host,
Path = $"/verify/{Uri.EscapeDataString(pwToken)}"
};
var fullUrl = uriBuilder.Uri.AbsoluteUri;

Separating a part of the current URL

I want Separating a part of the current URL
Example:localhost:50981/Admin/AddCustomer.aspx
The part I want: AddCustomer
or
Example:localhost:50981/Request/Customer.aspx
The part I want: Customer
You can use AbsolutePath in your onLoad function of page.
//AddCustomer or Customer
string yourPath = HttpContext.Current.Request.Url.AbsolutePath.Split('/').Last().Split('.')[0];
You can make use of string.Split():
var url = "localhost:50981/Admin/AddCustomer.aspx";
var result = url.Split('/').Last().Split('.')[0];
To get the current Url path in Asp.Net:
var url = HttpContext.Current.Request.Url.AbsolutePath;
Note:
If you are interested in how to get the different parts of an url have a look at this answer:
var scheme = Request.Url.Scheme; // will get http, https, etc.
var host = Request.Url.Host; // will get www.mywebsite.com
var port = Request.Url.Port; // will get the port
var path = Request.Url.AbsolutePath; // should get the /pages/page1.aspx part, can't remember if it only get pages/page1.aspx

OAuthException #100 when creating custom object with facebook sharp SDK

Basically, I have a custom object inheriting from place. I am creating a c# tool for creating the objects using the Facebook Sharp c# SDK located here I am using an app access token when making these calls.
I've tried various approaches and variation within:
Here is a sample call that yeilds:
(OAuthException - #100) (#100) The parameter object is required
_api.AccessToken = GetExtendedToken().Token;
var postdata = new Dictionary<string, object>
{
//{"fb:app_id", "appId"},
//{"type", "myapp:myobject"},
{"url", resort.Url},
{"title", resort.Name },
{"image", resort.Image},
{"video", resort.Video},
{"description", resort.Description},
{"place:location:latitude", lat},
{"place:location:longitude", long}
};
var response = _api.Post("/app/objects/myapp:myobject", postdata);
if I uncomment the type parameter I get:
(OAuthException - #2500) Cannot specify type in both the path and query parameter
If I add the type back in, and remove the type from the path, I get
a response of true but this should be something like id:
23049820398092384
If I remove the place objects, or if I remove place and type, or if
I remove place but use the type and change the get path, I still get
errors.
refactored a bit. In this scenario I needed to assign the postdata information to an object as such below. also needed to stop using facebooksharp, their api does weird stuff to the request.
var obj = new
{
app_id = appId,
type = app_name:object_type",
url = Url,
title = Name,
image = Image,
video = Video,
description = Description
};
var vars = new NameValueCollection {{"object", JsonConvert.SerializeObject(obj)}, {"format", "json"}, {"access_token", AppToken}};
var url = "https://graph.facebook.com/app/objects/"+ _appName + object_type;
return HttpTools.Post(url, vars);

Get revision feed for a document in Google Docs using .NET

I am trying to get revision feed for an existing document in Google Docs (actually I just need revision count). I use the code below and get a GDataRequestException. The inner exception is 404 while the response string is (document id is truncated):
<errors xmlns='http://schemas.google.com/g/2005'>
<error>
<domain>GData</domain>
<code>ResourceNotFoundException</code>
<internalReason>Invalid document id: file:0BxwzFL2fD0</internalReason>
</error>
</errors>
And here is the code:
var documentsService = new DocumentsService("myappname");
documentsService.SetAuthenticationToken(token);
var uri = string.Format("https://docs.google.com/feeds/default/private/full/{0}/revisions", Uri.EscapeDataString(resourceId));
var query = new DocumentsListQuery(uri);
var feed = documentsService.Query(query);
It looks like the resourceId you are using is invalid.
Instead of constructing the uri manually, you should use the RevisionDocument property of the DocumentEntry instance you want to retrieve the revisions for:
var uri = entry.RevisionDocument;
var documentsRequest = new DocumentsRequest();
// ... do any authentication here..
var revisions = documentsRequest.Get<Google.Documents.Document>(entry.RevisionDocument).Entries;

Categories