Getting Invalid Token response when trying to create D2L user account - desire2learn

I am trying to modify a D2L database from within a 3rd party application using their Valence API. I've gotten some operations to work but am stuck trying to create a new user account. I have been told that the account I am working under is authorized to do this.
I’ve defined a JSON object to hold the values I want:
{
"OrgDefinedId": "XX000TEST",
"FirstName": "Tom",
"MiddleName": "",
"LastName": "Foolery",
"ExternalEmail": "tom#something.com",
"UserName": "Tom.Foolery",
"RoleId": "78",
"IsActive": "true",
"SendCreationEmail": "false"
}
I copied the above text to the HTTP post buffer and then called the following link:
/d2l/api/lp/1.0/users/?
The parameter string contains the IDs and signatures (x_a, x_b, etc) as specified in the Valence docs. I assume the authorization values are correct, since I'm getting correct results when using the same algorithms on other Valence queries.
Any suggestions on how to get past the "Invalid Token" message would be appreciated.
--stein

If you're getting a 403 "Invalid Token" message then you are not, for some reason, forming your x_a, x_b, x_c, or x_d authentication tokens correctly. Common problems we have seen in the past are:
Trying to re-use x_c and or x_d signatures generated for one API call with another
Getting the tokens swapped around: x_a is App ID, x_c is App Sig, x_b is User ID, and x_d is User Sig
Generating the signatures using the wrong HTTP method (the method is one of the components of the base string for the signatures)
Not using all upper case letters for the HTTP method in the base string (the component should be GET not get)
Not using all lower case letters for the API route in the base string, or including incorrect characters: for example, in your question, you seem to imply that you're passing in the ? as a part of the route; you shouldn't do this. In this case, your base string for creating the URL should be POST&/d2l/api/lp/1.0/users/&1234567 where 1234567 should be replaced with the timestamp you generate and also pass in x_t
Using the API route with API version component provided, but when calling, using another version component (i.e. generating with /d2l/api/lp/1.0/... but calling with /d2l/api/lp/1.1/...)
Using an incorrect/mismatching timestamp value in the base string (the timestamp you use for the basestring should be in seconds, and be the same stamp as the x_t value)
While calls previously worked, suddenly none of the calls work with a 403 invalid token result: the user tokens could have expired and you need to re-authenticate the user
While calls previously worked against a test instance, when you try moving to a different LMS (prod instance for example) the calls don't work: perhaps the App ID/Key pair hasn't shown up on this new LMS, or you're trying to use the user ID/Key pair from one LMS to generate signatures on a different LMS
Also, notice that your JSON object is strictly not correctly formed: the IsActive and SendCreationEmail properties should have values of true and false respectively, not "true" and "false", although it's possible that the LMS parser on the server side will be forgiving about that.
If none of these points assist you, please feel free to open an issue in our issue tracker, or contact our Valence support email address, and we can try to help you out through this issue.
NOTE Please note that invalid tokens will throw you back a 403 (but the message will be "Invalid Token" or "Expired Token" or similar). If your tokens are correctly generated, but your calling user context is not allowed to create a user, then you'll also get a 403, but this time the message will be "Not Permitted" or "Not Authorized" or similar. Make sure you double check what sort of 403 you're getting back.
In this particular case, the permissions around creating a user are a bit tricky; not only must you have a permission to create a user, you must also have permission to modify the properties that you will be passing into the API in the CreateUserData structure (OrgDefinedId, Email, and so on), and you must also be able to see all those fields in the User Information Privacy settings, and you must have permission to enroll the user role you have provided at the organization level... those last two bits have tripped up some of our clients in the past.

Related

Cumulocity smarREST response templates

I am trying to set up the Cumulocity smartREST response templates to supply info from the device object stored by an app. I am thinking it is not possible but I want to confirm because the documentation is brief and not clear.
I have successfully implemented MEASUREMENT POST templates previously but I am trying to do INVENTORY GET now. I have set some values in the device object and I can see them from tenant.cumulocity.com/inventory/managedObjects/id/. This could look like:
"custom_values": {
"val1": "abcde",
"val2": "fghij"
}
Now I go to the smartREST template web interface editor and create a template (eg t1) and set a message (eg m001) and set it to 'inventory' and 'get' and tick 'includes response'. I'm not sure if I need custom fields here. Then I create a response (eg r001) and I now have to fill in base pattern with a condition and some number of other patterns. I assume in one of those fields I have $.custom_values.val1 etc but all permutations I try result in 'no access to object' error from topic 's/e'.
My ideal result (from the above example) would be to publish to '/s/uc/t1' with 'm001' and receive 'r001,abcde' (ie custom_values.val1) and publish 'm002' and receive 'r001,fghij' (ie custom_values.val2).
Thanks for taking the time to read.
Your approach is correct but your MQTT user probably is just missing the rights to the object as it is created by the app (I guess the mqtt client is a device user).
The best approach here is to give this object you are creating from the app the fragment c8y_Global
{
"name": "testObject3",
"c8y_Global": {},
"custom_values": {
"val1": "abcde",
"val2": "fghij"
}
}
This fragment will make this object available to all registered users. This is common practice for app meta data.

How can I content-partner and can-read-video-streams roles from Dailymotion?

I try to retrieve an HLS stream URL of my videos on Dailymotion, calling /video/ API with stream_hls_url value in the fields parameter. But I get a 403 error with the following message:
Unsufficient roles for the 'fields' parameter of 'GET /video/<id>' with 'stream_hls_url' value, roles required: content-partner, can-read-video-streams
How could I obtain these roles, given that I'm a Dailymotion partner?
You should either contact your Dailymotion content manager if you have one, or get in touch with us by writing your request to https://faq.dailymotion.com/hc/en/requests/new
Anyone coming to this question with a similar response from an API request; please check the fields you're requesting within your request against those listed in the Dailymotion API Data API Reference.
Often this "403" response, seemingly due to "Unsufficient Roles" (yes that's a typo), is actually down to requesting a field that no longer exists within the defined reference (linked above). This happens more than it should, with little or no notice to the end user - as demonstrated here.
I hope this helps :)

What is the purpose of each parameter in a MailChimp unsubscribe URL?

In the following URL, that unsubscribes a user from a list:
http://xxxxx.us2.list-manage.com/unsubscribe?
u=87f537bccxx35e53a1890e0d9&
id=40dcxx6cd6&
e=c4aaxx1dd6&
c=9a6xx11963
What does each parameter do?
Today I had to learn what each nondescript parameter means so that I could generate URLs for each email I send through Mandrill. It wasn't that easy to discover their meaning, but here are the one's I've come up with and how I found out what they are.
http://xxxxx.us2.list-manage.com/unsubscribe?
u=87f537bccxx35e53a1890e0d9&
id=40dcxx6cd6&
e=c4aaxx1dd6&
c=9a6xx11963
URL format:
Protocol can be http or https.
Your username comes next
In the example, us2 is the MailChimp datacenter where your account resides. That's different for each account. (https://apidocs.mailchimp.com/api/2.0/) It's good practice to specify a DC even though the documentation says that it isn't required. Specifying it will cut down on unnecessary latency.
list-manage[n].com can work with or without the number at the end of the domain, or it can have a 1 or a 2. Changing that doesn't appear to matter, but I think it has something to do with their load balancing.
/unsubscribe can also be /subscribe or /profile (The latter appears to be dependent on the "e" parameter. (See below) When you don't specify it, it states, "List member profiles cannot be updated from test campaigns or archive pages" and if you specify an invalid value, you get an error page.
u Is a unique identifier for your account. Every list on your account uses it. (See http://kb.mailchimp.com/lists/signup-forms/find-the-unsubscribe-link-for-your-list for how you can view the various URLs for your account.)
id is your list ID
e is the euid as documented on https://apidocs.mailchimp.com/api/2.0/lists/subscribe.php
c I haven't seen this one yet, but my guess is that it's the campaign ID.
Also, when you wish to prefill subscribe and unsubscribe forms, you can use the following GET params.
EMAIL Allows you to enter the subscriber's email
MERGE1 Allows you to enter the subscriber's first name
MERGE2 Allows you to enter the subscriber's last name

verifying a single attendee with email

Is there a method to return a specific attendee's information by sending:
1) the attendee's email address
2) my user_key
3) my app_key
I could do this by searching the returned xml from this "event_list_attendees" method, however, I would prefer to only receive the one result (not hundreds for each call).
Note: I work on the platform team at Eventbrite
Currently there is no way to search for a specific attendee with event_list_attendees.
However, you can cut down on the amount of data returned by paging through the results until you have found the attendee or using the modified_after parameter if you know when the user was last updated: http://developer.eventbrite.com/doc/events/event_list_attendees/
I realize this limitation is non-ideal. We're actively working on building a new API which is more RESTful and does not have issues like this.

Is this a proper implementation of PUT idempotency and what should the response be?

The way I have understood idempotency thus far is basically: If I send 10 identical PUTs to a server the resulting additional resources created will be identical to if I had sent a single PUT statement.
What I take this to mean is that the following implementation would adhere to this:
[AcceptVerbs(HttpVerbs.Put)]
ContentResult User(){
//parse XML that was sent to get User info
//User has an e-mail address which is unique to the system
//create a new user in the system only if one for this e-mail address does not exist
return Content(something, "text/xml");
}
There now if I sent 10 PUTs with XML for User data and they all contain the same e-mail address, only one user will be created.
However, what if they send 10 requests (for whatever reason) and they are all different, but the e-mail is the same. If the first request doesn't make it through then the data of the 2nd request will be used to create the user, and the following 8 requests will be ignored. Is there a flaw here? Or should I literally only ignore requests that are explicitly identical in every way and instead send back an error saying the user already exists if they use the same e-mail address?
Also, what kind of response should be sent from a such PUT statement? Info about the user? Maybe an ID to manipulate them with other API calls? Or perhaps it should just say "success" or "fail: [error details]"?
Your question doesn't reveal the URL where the PUT request is sent to. This is actually very important as it is not the email address within the XML data that dictates whether a new resource is created or an old one updated but the URL that you are sending the request to.
So, if you send PUT to /users/jonh.doe#foo.com/ it either creates the user john.doe#foo.com or updates it if it was already in the system.
Similaraly, if you send PUT to /users/123/ (using id instead of email) it will create or update user 123. However, in this case if the email has to be unique and somebody sends PUT /users/456/ and within that XML is the same email as what the user 123 already has, you have to respond with 409 Conflict.
If the user already exists with the same email address, then the 2nd and subsequent PUT operations should update the data for that resource. The success or failure should be communicated in the status code. If the update succeeds, respond with "200 OK", or "204 No Content"; you can return some information, but don't expect caches to store it as if it were the new representation you would obtain from a GET. If you do not intend for that resource to ever accept a PUT operation other than the first one, then respond instead with "405 Method Not Allowed", with an explanation in the response body. Use "409 Conflict" (again, with an explanation in the response body) if the submitted representation might replace the resource, but can't because it's particular fields cannot be reconciled with the existing state.

Resources