Create playlist Deezer API - ruby-on-rails

Im trying to create playlist for user using Deezer API but get error all the time "An active access token must be used to query information about the current use"
response = connection.post do |req|
req.url "user/#{user_id}/playlists"
req.headers['Authorization'] = "Bearer #{acces_token}"
req.headers['Content-Type'] = 'application/json'
req.body = {
title: name,
public: public
}.to_json
end

There is a typo in "access" in "Bearer #{acces_token}"
and
Authorization Code may need to be Authorization

As mentioned here http://developers.deezer.com/api/user/playlists, this action needs a permission "manage_library" from the user to create a new playlist. Just ask for this permission like here http://developers.deezer.com/api/oauth and all will be fine normally.

Related

Discord OAuth2 throws Missing Permissions error when I already granted it the right permissions

Literally every single post I see when I search this is about a bot. If you are here for a bot error leave, this is not about a bot.
I am trying to create a bot that allows users to join a server from OAuth2, and I already have the access token (which works) and I am able to successfully get their user id and everything. However, when I try to join a server it immediately throws the error '{"message": "Missing Permissions", "code": 50013}'.
OAuth link: https://discord.com/oauth2/authorize?client_id=1044368734988546068&redirect_uri=*****&response_type=code&scope=identify%20guilds.join
^ The link above works fine, it's just when I try to use it to join a server, it throws the issue.
my code:
def add_to_guild(access_token, guildID, userID):
url = f"{API_ENDPOINT}/guilds/{guildID}/members/{userID}"
data = {
"access_token": access_token,
}
headers = {
"Authorization": f"Bot {TOKEN}",
'Content-Type': 'application/json'
}
r = requests.put(url=url, headers=headers, json=data)
return r.text
PLEASE help me with this. Thank you

What auth flow to use with spa and service account msal

There's so many different flows in the Microsoft docs that I have no clue what one is needed for me. I am using React and Python. (I understand node, so if someone explains using node/express its fine)
What user should see:
A page with a button to login, nav is there but wont work till logged in. The login creates a popup to sign in with Microsoft account. Once signed in, the user will be able to use nav to see dynamics information.
What I am trying to do:
This app needs to sign in a user and obtain the users email through 'https://graph.microsoft.com/v1.0/me'.(no client secrets needed) Then I need to send that email in this request;
(The tenant == {company}.crm.dynamics.com.)
allInfo = requests.get(
f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq \'{email}\'', headers=headers).json()
This backend request needs to have a client secret to obtain the information. So I believe my backend also needs to be logged on to a service account. I believe I need to get a token for my backend to make requests on behalf of the service account.
What I have:
I have a React frontend that is signing a user in and calling 'https://graph.microsoft.com/v1.0/me' correctly and getting that email. Once I get the email, I am sending it to my backend.
Now I have no clue how to proceed and have tried many things.
What I have tried for backend:
Attempt 1: I get a token but error: {'error': {'code': '0x80072560', 'message': 'The user is not a member of the organization.'}}. Problem is, this id is the Azure AD ID. It should def work
#app.route('/dynToken', methods=['POST'])
def get_dyn_token():
req = request.get_json()
partnerEmail = req['partnerEmail']
token = req['accessToken']
body = {
"client_id": microsoft_client_id,
"client_secret": client_secret,
"grant_type": "client_credentials",
"scope": SCOPE_DYN,
}
TENANTID = '{hash here}'
res = requests.post(
f'https://login.microsoftonline.com/{TENANTID}/oauth2/v2.0/token', data=body).json()
dyn_token = res['access_token']
headers = {
"Prefer": "odata.include-annotations=\"*\"",
"content-type": "application/json; odata.metadata=full",
"Authorization": f"Bearer {dyn_token}"
}
try:
allInfo = requests.get(
f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq \'{email}\'', headers=headers).json()
print(allInfo)
Attempt 2:
Same code but instead of f'https://login.microsoftonline.com/{TENANTID}/oauth2/v2.0/token' its
f'https://login.microsoftonline.com/common/oauth2/v2.0/token'. Error: An exception occurred: [Errno Expecting value] : 0. Because it returns an empty string.
Now I don't know if I am even on the right path or where to go. I know the routes work themselves if the token is correct. I used only SSR with no react and these routes work. But I need the React to be there too. I just don't know what flow to use here to get what I need. The docs make it easy for /me route to work. But the {company}crm.dynamics.com docs don't really provide what I am trying to do.
Additional info after comment:
What 'f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq '{email}'', headers=headers" is trying to get are API keys. Full code :
try:
allInfo = requests.get(
f'https://{TENANT}api/data/v9.0/company_partneruserses?$filter=company_email eq \'{email}\'', headers=headers).json()
partner_value = allInfo['value'][0]['_company_partner_value']
response = requests.get(
f'https://{TENANT}api/data/v9.0/company_partnerses({partner_value})', headers=headers).json()
return {'key': response['company_apikey'], 'secret': response['company_apisecret']}
Then once it has the keys:
def api_authentication(apikey, apisecret):
headers = get_headers() #<-- same headers as above with using dyn_token
response = requests.get(
f'https://{TENANT}api/data/v9.0/company_partnerses?$filter=company_apikey eq \'{apikey}\' and company_apisecret eq \'{apisecret}\'&$select=company_apikey,company_apisecret,_company_account_value,_company_primarycontact_value,blahblah_unassignedhours,company_reporturl', headers=headers).json()
return response
Afterwards I am able to get all the information I am looking for to send back to my frontend for the client to see. (By making multiple request to crm with these keys)
The client_credentials grant that you are using should work, provided the CRM trusts the token issued to the client (your python backend). Please use MSAL library instead of hand crafting the token request. It will save you time and eliminate errors.

Rails - gem instagram - issues on access token and sandbox

I need to put on a website the complete instagram feed of my customer. I have tried several ways to access to instagram and get the whole feed, but I get some errors.
Using the gem "instagram" (the easiest and simplest method) i got the following error when I try to get the access token.
Instagram::BadRequest: POST https://api.instagram.com/oauth/access_token/: 400: OAuthException: Matching code was not found or was already used.
I tried to follow the indication on the instagram documentation https://www.instagram.com/developer/authentication/ using my browser and I can get the access token, but I am not able to do the http calls manually in ruby.
I need to download all the data and keep it inside my database (as I always done) so I need everything in the controller.
my code is very simple:
accessToken = Instagram.get_access_token(Instagram.client_id, :redirect_uri => CALLBACK_URL)
client = Instagram.client(access_token: accessToken)
response = client.user_recent_media
#other code to cycle inside posts and put everything in db
i'm sure to have included the same redirect_url in my instragram registration app and in my code.
As shown in the sample application in the gem's repo, you will need to call authorize_url first:
Instagram.authorize_url(:redirect_uri => CALLBACK_URL)
and then you will get request on the CALLBACK_URL, where you should have an action with the code that you provided:
response = Instagram.get_access_token(params[:code], :redirect_uri => CALLBACK_URL)
client = Instagram.client(:access_token => response.access_token)
# do stuff with the client
SOLVED!
I have misunderstood the usage of the api.
I got my access token following this https://elfsight.com/blog/2016/05/how-to-get-instagram-access-token/
and i can access my posts using in my model:
access_token = Instagram.access_token
client = Instagram.client(access_token: access_token)
response = client.user_recent_media
and in my config file:
Instagram.configure do |config|
config.client_id = "CLIENT_ID"
config.client_secret = "CLIENT_SECRET"
config.access_token = "ACCESS_TOKEN"
end
thanks a lot for your support
you should get the token when processing the callback in the omniauth.auth hash: request.env['omniauth.auth']['credentials']['token']

how to get user information from Withings api on grails

I'm trying to get user information from Withings Api, i've already success login into Withings with Oauth using Scribe library(Java). But there is a problem when i sent request to get user information follow Withings Api document it always return result with error code.
I've tried some way but it didn't work. Can someone help me to solve this problem.
Withings Api http://www.withings.com/en/api#documentation
First i call withings action in WithingsController.groovy to get authentication.
After authenticate success server return access token, in withingsCallback action i get user information.
Result return when get user information is result code of Withings Api
{"status":2554}
This is my code
WithingsService.groovy
def getAuthDetails(callbackUrl) {
if (!authService) {
authService = new ServiceBuilder()
.provider(WithingsApi.class)
.apiKey( grailsApplication.config.oauth.withings.key as String )
.apiSecret( grailsApplication.config.oauth.withings.secret as String )
.callback( callbackUrl as String )
.build();
}
Token requestToken = authService.getRequestToken();
[ authUrl : authService.getAuthorizationUrl(requestToken), requestToken : requestToken ]
}
def getWithingsUserInformation(Token accessToken,String userId){
String url = 'http://wbsapi.withings.net/user?action=getbyuserid&userid='+userId;
OAuthRequest request = new OAuthRequest( Verb.POST, url )
authService.signRequest(accessToken, request)
Response response = request.send()
return response
}
def getAccessToken( params, requestToken ){
requestToken = requestToken as Token
Verifier verifier = new Verifier( params.oauth_verifier )
authService.getAccessToken(requestToken, verifier);
}
WithingsController.groovy
def withings() {
def authInfo = withingsService.getAuthDetails(createLink(action: 'withingsCallback', controller: 'withings', absolute: 'true'))
if (authInfo.requestToken)
{
session["withings_requestToken"] = authInfo.requestToken
}
}
def withingsCallback(){
def accessToken = withingsService.getAccessToken(params, session["withings_requestToken"])
session["withings_accessToken"] = accessToken
if(accessToken) {
def profile
String userId = params.userid
profile = withingsService.getWithingsUserInformation(accessToken,userId)
}
}
Unless I'm missing something, it looks like you are not redirecting your user to get the "access token". After you get a request token:
you then generate a authentication url
redirect the user to this authentication url
they will authenticate
if authentication is successful, provider will call your callback with access token
So your withings action should include:
def withings() {
def authInfo = withingsService.getAuthDetails(createLink(action: ....
if (authInfo.requestToken)
{
session["withings_requestToken"] = authInfo.requestToken
}
//are you missing this?
redirect(authInfo.authUrl)
}
If you're using some type of http debugging/logging, check for the following request after your withings action.
https://oauth.withings.com/account/authorize?
oauth_callback=http%3A%2F%2Fexample.com%2Fget_access_token
&oauth_consumer_key=c331c571585e7c518c78656f41582e96fc1c2b926cf77648223dd76424b52b
&oauth_nonce=369f9ceb2f285ac637c9a7e9e98019bd
&oauth_signature=OR9J9iEl%2F2yGOXP2wk5c2%2BWtYvU%3D
&oauth_signature_method=HMAC-SHA1
&oauth_timestamp=1311778988
&oauth_token=5bb105d2292ff43ec9c0f633fee9033045ed4643e9871b80ce586dc1bf945
&oauth_version=1.0
Though this is unrelated to the question initially asked, I thought I would post here since this was a common stopping ground for me reaching a Withings 2554 error.
If updating to the newest version of Withings Api for access token authentication, the current version of the Withings Api will now also cause this 2554 status code if you do not attach action: requesttoken to the access token request body.
Additionally, when pulling apart the response, make sure to drill into the body of the payload, since the latest version of the Withings access token api delivers its payload contents differently. This may be a no brainer for those implementing from scratch, but if you are using an oauth library, most of this behavior is abstracted by the library, and it likely won't be anticipating the payload structure to contain the body field.
more info here: https://developer.withings.com/api-reference#operation/oauth2-getaccesstoken

Require Google to return email address as part of OAuth

I am using OAuth to access Gmail with dotNetOAuth. How can I force Google to return user's email address as part of callback after authorization?
By default, Google OAuth callback only returns the token secret and access tokens.
First you need to add the following scope (https://www.googleapis.com/auth/userinfo.email) to your oauth request.
After you're back to your app from Google and you have your access token, you can make a request using the access token to https://www.googleapis.com/userinfo/email?alt=json.
This will return the email address. More info at http://sites.google.com/site/oauthgoog/Home/emaildisplayscope
For getting the Email Id, you need to add the scope "https://wwww.googleapis.com/auth/userinfo.email"
Then you will get id_token in the response.
Response={
"access_token" : "ya29.eAG__HY8KahJZN9VmangoliaV-Jn7hLtestkeys",
"token_type" : "Bearer",
"expires_in" : 3600,
"id_token" : "id_token_from_server",
"refresh_token" : "1/GIHTAdMo6zLVKCqNbA"
}
Then use this id_token as below POST request:
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=id_token_from_server
And you will get response like below:
Response={
"issuer": "accounts.google.com",
"issued_to": "80780.apps.googleusercontent.com",
"audience": "8078909.apps.googleusercontent.com",
"user_id": "1118976557884",
"expires_in": 3598,
"issued_at": 1456353,
"email": "emailId#gmail.com",
"email_verified": true
}
Make sure you add "www" in the APIs as shown above...
OAuth doesn't provide a facility for extra parameters during an OAuth handshake, so I don't think you can force Google to supply it. There is likely a Google API however that you can use your OAuth access token to call to fetch the email address after the handshake, however.
request OAuth scope to include the "Email Display Scope" https://www.googleapis.com/auth/userinfo.email
scope="http://www.google.com/m8/feeds/ https://www.googleapis.com/auth/userinfo.email"
Then use REST API like Hammock to get address
RestClient client = new RestClient
{
Authority = "https://www.googleapis.com",
};
RestRequest request = new RestRequest
{
Path = "userinfo/email?alt=json",
Credentials = OAuthCredentials.ForProtectedResource(
this.requestSettings.ConsumerKey,
this.requestSettings.ConsumerSecret,
this.requestSettings.Token,
this.requestSettings.TokenSecret)
};
var response = client.Request(request);
Here's a c# function for when you have pre-authorized the request as detailed above:
private void FetchUsersEmail(token)
{
var emailRequest = #"https://www.googleapis.com/userinfo/email?alt=json&access_token=" + token;
// Create a request for the URL.
var request = WebRequest.Create(emailRequest);
// Get the response.
var response = (HttpWebResponse) request.GetResponse();
// Get the stream containing content returned by the server.
var dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
var reader = new StreamReader(dataStream);
// Read the content.
var jsonString = reader.ReadToEnd();
// Cleanup the streams and the response.
reader.Close();
dataStream.Close();
response.Close();
dynamic json = JValue.Parse(jsonString);
var currentGoogleEmail = json.data.email;
}
(JValue is part of JSON.Net)
In php, apiOauth2Service.php class provides methods to access logged in user info. For this you can use userinfo->get() method. Make sure you also use scope https://www.googleapis.com/auth/userinfo.email.
This will work with same access token. Also you should try looking in other APIs for similar kind of information in return. This is much easier to look through oAuth_playground >> http://code.google.com/apis/explorer/
If you request the userinfo.email scope, Google returns an id_token along with the access_token.
The id_token can be unencrypted to provide the user's email address, at www.googleapis.com?/oauth2/v1/tokeninfo?id_token=IDTOKENHERE
More information here: https://developers.google.com/accounts/docs/OAuth2Login

Resources