How to use SODA.net and App Token in asp.net-core MVC - asp.net-mvc

As per Socradata.com suggest, I have created both and an Application Token and an Application Key.
When I query using a Soda.net Click using the App Token and username and password like this:
var client = new SodaClient(sodaHost, sodaAppToken, user, pwd);
var soql = new SoqlQuery().Select("draw_date", "winning_numbers", "mega_ball", "multiplier").Where("draw_date > '2018-01-01'").Order(SoqlOrderDirection.DESC, "draw_date");
var dataset = client.GetResource<MyClass>(soda4x4);
var results = dataset.Query<MyClass>(soql);
Or when query using the App Token and App Key like this:
var client = new SodaClient(sodaHost, sodaAppToken, keyId, keySecret);
var soql = new SoqlQuery().Select("draw_date", "winning_numbers", "mega_ball", "multiplier").Where("draw_date > '2018-01-01'").Order(SoqlOrderDirection.DESC, "draw_date");
var dataset = client.GetResource<MyClass>(soda4x4);
var results = dataset.Query<MyClass>(soql);
I get the following error:
System.ArgumentOutOfRangeException
HResult=0x80131502
Message=The provided resourceId is not a valid Socrata (4x4) resource identifier.
Parameter name: resourceId
Source=SODA
StackTrace:
at SODA.SodaClient.Query[TRow](SoqlQuery soqlQuery, String resourceId)
at SODA.Resource1.Query[T](SoqlQuery soqlQuery)
at NumPicker.Controllers.HomeController.MegaMillions() in C:\Users\ka8kgj\Desktop\NumPicker\NumPicker\Controllers\HomeController.cs:line 45
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
However, when I query anonymously with this client. No error. All is well.
var client = new SodaClient(sodaHost);
var soql = new SoqlQuery().Select("draw_date", "winning_numbers", "mega_ball", "multiplier").Where("draw_date > '2018-01-01'").Order(SoqlOrderDirection.DESC, "draw_date");
var dataset = client.GetResource<MyClass>(soda4x4);
var results = dataset.Query<MyClass>(soql);
Obviously I can not see an issue with the code. Can someone point out what I am missing?

Ok, Here is the answer. It is most embarrassing but I will take the humiliation so that others may not have too..
When you create the app-token on the SOCRATA web site. You get a Key / Secrete pair.
When passing the app-token, It is the KEY that should be passed. NOT THE SECRETE !

Related

Google OAuth Returning Additional Scopes Without Requesting

I was testing around with Google's oauth and was trying out different scopes.
However, I then reduced my scope request to just this : "https://www.googleapis.com/auth/userinfo.email"
The following is more in dotnetcore
Dictionary<string, string> queries = new Dictionary<string, string>();
queries.Add("scope", "https://www.googleapis.com/auth/userinfo.email");
queries.Add("access_type", "offline");
queries.Add("include_granted_scopes" ,"true");
queries.Add("response_type", "code");
queries.Add("state", "state");
queries.Add("redirect_uri", "http://localhost:5000/api/authenticate/googauth");
queries.Add("client_id", _clientId);
queries.Add("prompt", "consent");
UriBuilder builder = new UriBuilder();
builder.Host = "accounts.google.com";
builder.Scheme = "https";
builder.Path = "o/oauth2/v2/auth";
//builder.Query = ""
foreach (var query in queries)
{
if (string.IsNullOrEmpty(builder.Query))
{
builder.Query += $"{query.Key}={query.Value}";
}
else
{
builder.Query += $"&{query.Key}={query.Value}";
}
}
var redirectUri = builder.Uri.ToString();
return Redirect(redirectUri);
From the returned code, I then retrieved the access token etc.
Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("code", code);
values.Add("client_id", _clientId);
values.Add("client_secret",_clientSecret);
values.Add("redirect_uri", "http://localhost:5000/api/authenticate/googauth");
values.Add("grant_type", "authorization_code");
var client = new HttpClient();
var result = await client.PostAsync("https://oauth2.googleapis.com/token", new FormUrlEncodedContent(values));
var content = await result.Content.ReadAsStringAsync();
var convertedContent = JsonSerializer.Deserialize<GoogleAccesstoken>(content);
However, I seem to get more than what I asked for. I get this in the returned scopes :
openid https://www.googleapis.com/auth/user.gender.read https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/user.birthday.read
I've tried using incognito, and different browsers and they all return the same thing (thinking that it may have been a cache issue).
Is anyone able to help me on this?
Thanks.
Enables applications to use incremental authorization to request access to additional scopes in context. If you set this parameter's value to true and the authorization request is granted, then the new access token will also cover any scopes to which the user previously granted the application access. See the incremental authorization section for examples.
extract from google documentation: https://developers.google.com/identity/protocols/oauth2/web-server
Basically means that the user has previously granted you the other scopes. Could have been through a login screen or something where you have used the same clientId

AcquireTokenAsync works normally without valid cilent secret

I can get the AccessToken to use with MS Graph using the code below
var credentials = new ClientCredential(accessRequest.ClientId, accessRequest.ClientSecret);
var authContext = new AuthenticationContext($"{accessRequest.Authoriy}/{accessRequest.Domain}/");
var result = await authContext.AcquireTokenAsync(accessRequest.Resource, credentials);
var graphAccess = new Library.Service.Implements.GraphCalendarService(result.AccessToken);
var mailsBox = await graphAccess.GetMailboxSettings(accessRequest.User);
The weird thing here is the value of [accessRequest.ClientSecret] used in first line = "qwerty".
Is this a bug or I need find another way to work with MS Graph(condition: need valid ClientId & ClientSecret)?
Thanks in advance.

How can i Pull Profile image from sharepoint

I'am new in API's & trying to pull user profile from sharepoint i use following code but don't know about servername? domainname? and username?
const string serverUrl = "http://sharepoint.com/";
const string targetUser = "ttgdev-my.sharepoint.com\\testuser1#ttgdev.guru";
// Connect to the client context.
ClientContext clientContext = new ClientContext(serverUrl);
// Get the PeopleManager object and then get the target user's properties.
PeopleManager peopleManager = new PeopleManager(clientContext);
PersonProperties personProperties = peopleManager.GetPropertiesFor(targetUser);
// Load the request and run it on the server.
// This example requests only the AccountName and UserProfileProperties
// properties of the personProperties object.
clientContext.Load(personProperties, p => p.AccountName, p => p.UserProfileProperties);
clientContext.ExecuteQuery();
foreach (var property in personProperties.UserProfileProperties)
{
Console.WriteLine(string.Format("{0}: {1}",
property.Key.ToString(), property.Value.ToString()));
}
Console.ReadKey(false);
Please guide me it will give me the error in
{"The property or field 'UserProfileProperties' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested."}
in the following line
clientContext.ExecuteQuery();
Most likely it is related with the format of targetUser variable. PeopleManager.GetPropertiesFor method expects accountName parameter to be specified in the proper format, in case of SharePoint Online it should be specified in claims format, for example:
i:0#.f|membership|jdow#contoso.onmicrosoft.com
For more details about Claims format follow this article.
So, in your case targetUser value should be replaced from ttgdev-my.sharepoint.com\\testuser1#ttgdev.guru to i:0#.f|membership|testuser1#ttgdev.guru
The following example demonstrates how to retrieve user profile picture via CSOM API:
using (var ctx = TokenHelper.GetClientContextWithAccessToken(webUri.ToString(), accessToken))
{
// Get the PeopleManager object and then get the target user's properties.
var peopleManager = new PeopleManager(ctx);
PersonProperties personProperties = peopleManager.GetPropertiesFor(targetUser);
//Retrieve picture property
var result = peopleManager.GetUserProfilePropertyFor(accountName, "PictureURL");
ctx.ExecuteQuery();
Console.WriteLine("Picture Url: {0}",result.Value);
}

How to change the default values of start and count parameters when picking the companies followed by a user in linkedin?

I am making a web-application in ASP.NET. I have used oauth to get profile fields of a user. I need the names of the companies followed by the user, but the problem is that the default value is set to 20. so, if the user is following more than 20 companies i am not able to get it. Please tell me how can i modify the start and count values. Iv used this url to make the call http://api.linkedin.com/v1/people/~:(following:(people,companies,industries,news-sources),educations).. Please help asap..
var requestHeader = GetUserProfileAuthorizationHeader();
var queryString = CreateQueryString();
var request = WebRequest.Create(RequestProfileUrl + queryString);
request.Headers.Add("Authorization", requestHeader.ToString());
request.Method = HttpMethod.Get;
try
{
var response = request.GetResponse();
using (var responseStream = response.GetResponseStream())
{
var reader = new StreamReader(responseStream);
var responseText = reader.ReadToEnd();
reader.Close();
return responseText;
}
}
Here public static string RequestProfileUrl = "http://api.linkedin.com/v1/people/~:(following:(companies:(id,name,size,industry),industries))"; And the method CreateQueryString() does this queryString = "?format=xml"; whenever i try to add something like queryString = "?format=xml&start=0&count=40"; it gives error dispite the number of companies followed being more than 60.. maybe i need to pass the query parameters in between the RequestProfileUrl i.e near the company somehow..
Did you tried adding ?start=x&count=y to the url?
Probably if you're getting an error when you add query parameters to the URL, you're not adding those parameters in the way that your OAuth library expects them to be added. You need to figure out how to add the parameters so they're added to the signature generation process or your signature will be invalid and you'll get a 401 error back from the server.

Why is my DotNetOpenAuth consumer not respecting the version 1.0a?

I am building an OAuth service provider using DotNetOpenAuth, and to test it I have modified the sample wcf consumer to simply call a plain http endpoint. The token request works fine, but when I request access to a protected resource, I get the following protocol execption:
The following required parameters were missing from the DotNetOpenAuth.OAuth.Messages.AuthorizedTokenRequest message: oauth_verifier
When I look at the log output on my service provider I see this:
Error while performing basic validation of AuthorizedTokenRequest with these message parts:
oauth_token: pgzjBIs0pKCeDIcaIinyrV5Jhi0=
oauth_consumer_key: sampleconsumer
oauth_nonce: TM0Rc8kg
oauth_signature_method: HMAC-SHA1
oauth_signature: zmpxK5c69n1VzTEEcrnnd4e+qYI=
oauth_version: 1.0
oauth_timestamp: 1305067751
Notice the oauth_version: 1.0, even though I have specified ProtocolVersion.V10a when I create the consumer.
If I specify ProtocolVersion.V10 on both sides I get this exception:
Expected message DotNetOpenAuth.OAuth.Messages.AccessProtectedResourceRequest but received DotNetOpenAuth.OAuth.Messages.AuthorizedTokenRequest instead.
Here is the consumer code to get the token (this is straight from the sample code):
WebConsumer consumer = this.CreateConsumer();
UriBuilder callback = new UriBuilder(Request.Url);
callback.Query = null;
string[] scopes = (from item in this.scopeList.Items.OfType<ListItem>()
where item.Selected
select item.Value).ToArray();
string scope = string.Join("|", scopes);
var requestParams = new Dictionary<string, string> { { "scope", scope } };
var response = consumer.PrepareRequestUserAuthorization(callback.Uri, requestParams, null);
consumer.Channel.Send(response);
Here is my consumer code that is failing:
var accessToken = Session["WcfAccessToken"] as string;
var consumer = CreateConsumer();
var serviceEndpoint = new MessageReceivingEndpoint("https://mymachine/test/getUserName", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest);
var httpRequest = consumer.PrepareAuthorizedRequest(serviceEndpoint, accessToken);
var httpResponse = httpRequest.GetResponse();
In my service provider I call serviceProvider.ReadProtectedResourceAuthorization(); and it fails with the exception I mentioned above.
Any ideas what I am doing wrong?
This was a silly mistake on my part, I was returning the wrong TokenType, from my IServiceProviderTokenManager. The correct logic is shown in the service provider sample, and looks something like this:
if (tokenObject.State == TokenAuthorizationState.AccessToken)
return TokenType.AccessToken;
return TokenType.RequestToken;

Resources