Upload to D2L LOR Failing with Permission Error - desire2learn

In trying to upload a scorm package via the REST API the upload is not working.
PUT /d2l/api/lr/(D2LVERSION: version)/objects/
http://docs.valence.desire2learn.com/res/lor.html
We are always refused based on 403 permission.
Are there any settings I should look at? Also looking for a trace of this working.

As long as the account you are authenticated with can perform the function in the web UI it is expected that the API will also function.
If you are getting keys back from the login process but this call is failing you could try a basic call from the sample such as "whoami". If that works your keys are correct.
If the keys are correct and some GET calls are working, you may need to pass a different method to the signing call in the sdk. (The method is part of the signature).
Here is an example of a working trace. 403 errors often have a body that will provide additional information. Note the security parameters are: x_a,x_b,x_c,x_d,x_t parameters on the call.
PUT http://smihai-7:44459/d2l/api/LR/1.0/objects/?repositoryId=1&x_t=1339183935&x_a=L2Hd9WvDTcyiyu5n2AEgpg&x_c=tfJFhSUaczOeOGqDFPXPq8NSBPj2sOhz4U3RacqWRMY&x_b=TestToken&x_d=BEl7kdCcrjenkpBt9ri5dkt4bdEgCo6xfZDWIpkKctA HTTP/1.1
Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml
User-Agent: RestSharp 101.3.0.0
Host: smihai-7:44459
Content-Type: multipart/form-data; boundary=-----------------------------28947758029299
Content-Length: 1203
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
-------------------------------28947758029299
Content-Disposition: form-data; name="Resource"; filename="Hello World Module.zip"
Content-Type: application/zip
PK???u?h?]G?g???????????Hello World Topic.htmlM??
?#??A??wwo?xH+???h????b
[o+ ????oD??RYW9u??????}J,?q
d2?[!%E|Crj?Wo{34??Xg??s???L?3??+??/?????*??W?W3?Fyb w?>?cR?Zrf?*???b??PK???u?h?N2?T??n?????imsmanifest.xml?V??0?#?Q??m#TI?.b ?XF??5?????k,?$~???6I??Vt??s?=g?x???%7)??J?i4 P?f\???????????DR?W`]?(?WL???g??d???s?,.&i?q????r??jT?kI??E?C?fsmd6-?q??G? .?f?i??4???!??v\???o?7$\jH%
??K??~P??m?`E?¥a)?C????v???6????#???U~?????x???[fe?.?3????~W???;B_?,???V#B?HE???:??q?e???s??_E? 1wK??<R????T??.9YE??SkP`?????*UT??3???j??#'??#2?;?e_c?#g.????}?p?>?c??????\?
????~,u????\s?M*L?U???E??
??????Kzp\E?X#?%\p???\??R
X-????%??C??????7?|??/&?=???h????l?\?\???????P???s??))??Td??K?????{?Y?+????v?gTN??h$?
?E'E?aB?UD????PK-????u?h?]G?g?????????????????????????Hello World Topic.htmlPK-????u?h?N2?T??n???????????????????imsmanifest.xmlPK??????????E????
-------------------------------28947758029299--
And the response is like this:
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Length: 69
Content-Type: application/json; charset=UTF-8
Expires: -1
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
X-XSS-Protection: 0
Date: Fri, 08 Jun 2012 19:32:22 GMT
{"IdentId":4,"Version":1,"ExecutionMessage":null,"ExecutionStatus":0}

Related

When does Rails respond with 'transfer-encoding' vs. 'content-length'?

I'm building an API on Rails version 4.1.7/Nginx that responds to request from an iOS app. We're seeing some weird caching on the client and we think it has something to do with a small difference in the response that Rails is sending back. My questions...
1) I want to understand why, for the exact same request (with only the Authorization header value changed), Rails sends back transfer-encoding: chunked sometimes and Content-Length: <number> sometimes? I thought that maybe it had something to do with the response size, but in the example responses whose headers I've pasted below, the data returned in the body is EXACTLY the same.
2) Is there a way to force it to use Content-Length? We think that that will fix our caching issues in our iOS app.
Response #1
HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
Date: Wed, 18 Mar 2015 00:59:31 GMT
ETag: "86f277ea63295460d4f3bed9a073eaa2"
Server: nginx/1.6.2
Status: 200 OK
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Request-Id: dd36f139-1986-4da6-9645-4438d41e74b0
X-Runtime: 0.123865
X-XSS-Protection: 1; mode=block
transfer-encoding: chunked
Connection: keep-alive
Request #2
HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
Date: Wed, 18 Mar 2015 00:59:36 GMT
ETag: "86f277ea63295460d4f3bed9a073eaa2"
Server: nginx/1.6.2
Status: 200 OK
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Request-Id: 0cfd7705-157b-41b5-aa36-739bc6f8302e
X-Runtime: 0.092672
X-XSS-Protection: 1; mode=block
Content-Length: 2234
Connection: keep-alive
Both responses are valid according to HTTP 1.1, so you need to fix your client code that it can handle both. It is a bad idea to try to fix the server so that that it behave in a way that it does not trigger a bug in the client.
The next version of nginx may behave differently, you users may even have proxies that change the transfer, maybe only when they do roaming and use a different provider.
If you want to do some finger-printing on the header, the ETag-header may help you, as the ETag should stay constant when the content of the response is not changed, regardless of the transfer.
The server typically sends in chunks when it calls a dynamic page, because it then does not need to create a buffer for the whole page and wait till all of the page is generated.
The server often send the response in one go if it has the buffer already, for example because it is in cache or the content is on a file and is not to big. Sending in one go is more efficient, on the other hand, an extra copy of the data to buffer the output needs more memory and is less efficient. So the server may even decide this according to the available memory.

ff9 in Wireshark Capture

I am attempting to save a wireshark capture for later analysis and replay and I noticed that the reconstituted stream has a series off ff9/n scattered through it which is breaking up the message. What is causing this sequence to be embedded in the stream? I do not see this artifact in other requests so is this just a reflection of what is actually on the wire or just a idiosyncrasy with wireshark?
Ex.
POST /gatewayvnext/xdr.svc HTTP/1.1
Content-Type: multipart/related; type="application/xop+xml"; boundary="uuid:b08aed3e-8972-4f75-a5f1-74ee6f0f9a4e"; start="<root.message#cxf.apache.org>"; start-info="application/soap+xml"; action="urn:ihe:iti:2007:ProvideAndRegisterDocumentSet-b"
Accept: */*
User-Agent: Apache CXF 2.2.9
Cache-Control: no-cache
Pragma: no-cache
Host: directuat
Connection: keep-alive
Transfer-Encoding: chunked
ff9
--uuid:b08aed3e-8972-4f75-a5f1-74ee6f0f9a4e
Content-Type: application/xop+xml; charset=UTF-8; type="application/soap+xml"; action="urn:ihe:iti:2007:ProvideAndRegisterDocumentSet-b";
Content-Transfer-Encoding: binary
Content-ID: <root.message#cxf.apache.org>
It's a reflection of what's actually on the wire.
Note that the HTTP headers include "Transfer-Encoding: chunked". Those items are part of chunked transfer encoding.

Wireshark POST data

This is the captured data from wireshark
POST /r HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.0.4; GT-I9100 Build/IMM76L)(en-us)
Cache-Control: no-transform
Host: xx.xx.xx.xx
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 77
WLL202GUI#00000058$CuII4425339CnsI4425339CzsXT3BQnVOa1ZR0OL0+0hLWwgCksHiqQ0V5HTTP/1.1 200 OK
Server: piled
Keep-Alive: timeout=30, max=300
Connection: keep-alive
Content-Type: application/octet-stream
Content-Length: 103
WLL202GUI#00000084$ChsN989338254856CcsD98Cvsb90ccdc057d52d0e53d906f963aabcfa7CqsI4425339CmsHPedr#mCgIC1
What I know is that this is the POST data:
WLL202GUI#00000058$CuII4425339CnsI4425339CzsXT3BQnVOa1ZR0OL0+0hLWwgCksHiqQ0V5
and this the response:
WLL202GUI#00000084$ChsN989338254856CcsD98Cvsb90ccdc057d52d0e53d906f963aabcfa7CqsI4425339CmsHPedr#mCgIC1
(correct me if i'm wrong)
what is the full URI path for this? is it :
http://xx.xx.xx.xx/r
followed by the above data?
i mean how can i send the same post data and recieve the same response? or change some of the data ?
this packets was sent by an app from an android OS (using BlueStacks to be exact)
The post data immediately follows the headers you pasted and should be visible in the tree.
It is not secured by SSL. If it were, you wouldn't be able to read the headers like you have.

Box oauth2: Invalid grant_type parameter or parameter missing

I don't know what I do wrong, but everytime I tried to obtain the token (after user authentication of course), the result is always Invalid grant_type parameter or parameter missing
Possibly related to Box API always returns invalid grant_type parameter on obtaining access token
Here is my fiddler result:
POST https://api.box.com/oauth2/token HTTP/1.1
Host: api.box.com
Content-Length: 157
Expect: 100-continue
Connection: Keep-Alive
grant_type=authorization_code&code=nnqtYcoik7cjtHQYyn3Af8uk4LG3rYYh&client_id=[myclientId]&client_secret=[mysecret]
Result:
HTTP/1.1 400 Bad Request
Server: nginx
Date: Thu, 07 Mar 2013 11:18:36 GMT
Content-Type: application/json
Connection: keep-alive
Set-Cookie: box_visitor_id=5138778bf12a01.27393131; expires=Fri, 07-Mar-2014 11:18:35 GMT; path=/; domain=.box.com
Set-Cookie: country_code=US; expires=Mon, 06-May-2013 11:18:36 GMT; path=/
Cache-Control: no-store
Content-Length: 99
{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}
Even following the curl example gives the same error. Any help would be appreciated.
Edit: tried with additional redirect_uri params but still the same error
POST https://api.box.com/oauth2/token HTTP/1.1
Content-Type: application/json; charset=UTF-8
Host: api.box.com
Content-Length: 187
Expect: 100-continue
Connection: Keep-Alive
grant_type=authorization_code&code=R3JxS7UPm8Gjc0y7YLj9qxifdzBYzLOZ&client_id=*****&client_secret=*****&redirect_uri=http://localhost
Result:
HTTP/1.1 400 Bad Request
Server: nginx
Date: Sat, 09 Mar 2013 00:46:38 GMT
Content-Type: application/json
Connection: keep-alive
Set-Cookie: box_visitor_id=513a866ec5cfe0.48604831; expires=Sun, 09-Mar-2014 00:46:38 GMT; path=/; domain=.box.com
Set-Cookie: country_code=US; expires=Wed, 08-May-2013 00:46:38 GMT; path=/
Cache-Control: no-store
Content-Length: 99
{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}
Looks like Box requires a correct Content-Type: application/x-www-form-urlencoded request header in addition to properly URL encoding the parameters. The same seems to apply to refresh and revoke requests.
Also, per RFC 6749, the redirect_uri is only
REQUIRED, if the "redirect_uri" parameter was included in the authorization request
as described in Section 4.1.1, and their values MUST be identical.
I was facing a similar issue.
The problem is not with Content-Type.
The issue is with the lifecycle of code you receive.
One key aspect not mentioned in most places is that the code you get on redirect lasts only 30 seconds.
To get the access token and refresh token, you have to make the post request in 30 seconds or less.
If you fail to do that, you get the stated error. I found the info here.
Below code worked for me. Keep in mind, the 30-second rule.
import requests
url = 'https://api.box.com/oauth2/token'
data = [
('grant_type', 'authorization_code'),
('client_id', 'YOUR_CLIENT_ID'),
('client_secret', 'YOUR_CLIENT_SECRET'),
('code', 'XXXXXX'),
]
response = requests.post(url, data=data)
print(response.content)
Hope that helps.
You are missing the redirect URI parameter. Try:
POST https://api.box.com/oauth2/token HTTP/1.1
Host: api.box.com
Content-Length: 157
Expect: 100-continue
Connection: Keep-Alive
grant_type=authorization_code&code=nnqtYcoik7cjtHQYyn3Af8uk4LG3rYYh&client_id=[myclientId]&client_secret=[mysecret]&redirect_uri=[your-redirect-uri]
I have also face same issue implementing oauth2. I have add Content-Type: application/x-www-form-urlencoded. When I add content-type my issue solved.
Check and add valid content-type.
Not sure who might need this in the future but be sure you're sending a POST request to get the access token and not trying to retrieve it by using GET or if you're testing- pasting in the address bar won't work, you need to send a POST request with the data in the BODY and not as query parameter.
Also the code usually lasts for a few seconds, so you need to use it as soon as its sent back.

Service Exception

I am trying to upload a video to youtube from an iPhone "installed application" with GData for ObjectiveC.
Currently I receive an error on my upload ticket: ServiceException - error code 500.
From the documentation I cannot figure out what this error means and what I am doing wrong:
500 (Internal error) - A 500 response code indicates that YouTube
experienced an error handling a request. You could retry the request
at a later time.
I received only this error for more then a week (so this is not a temporary outage) and I've tryied with different product registrations for the Youtube API.
Can anyone spot what I am doing wrong in my request ?
Below you can find the log from GData's GTMHttpDebugLogs:
uploadTicket:finishedWithEntry:error:
2012-10-18 17:13:26 +0000
Request: POST https://uploads.gdata.youtube.com/resumable/feeds/api/users/default/uploads
Request headers:
Accept: application/atom+xml, text/xml
Authorization: AuthSub token=<authorization subtoken refreshed every time>
Cache-Control: no-cache
Content-Length: 793
Content-Type: application/atom+xml; charset=utf-8
GData-Version: 2.0
Slug: video-filename.mp4
User-Agent: <bundle>/2.0.0 GData-ObjectiveC/1.12 iPhone/5.1 (gzip)
X-GData-Key: key=<my developer key
X-Upload-Content-Length: 4005670
X-Upload-Content-Type: video/mp4
Request body: (793 bytes)
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gml="http://www.opengis.net/gml" xmlns:app="http://www.w3.org/2007/app" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:media="http://search.yahoo.com/mrss/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:yt="http://gdata.youtube.com/schemas/2007"><yt:accessControl action="list"/><media:group><media:description>Video description here</media:description><media:keywords/><media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">Music</media:category><media:title>Video title here</media:title></media:group></entry>
Response: status 500
Response headers:
Cache-Control: no-cache, no-store, must-revalidate
Content-Length: 171
Content-Type: application/vnd.google.gdata.error+xml
Date: Thu, 18 Oct 2012 17:13:19 GMT
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Pragma: no-cache
Server: HTTP Upload Server Built on Oct 3 2012 16:52:30 (1349308350)
X-GData-User-Country: US
X-GUploader-UploadID: <### I made this upload id anonymous ###>
Response body: (171 bytes)
<errors xmlns='http://schemas.google.com/g/2005'><error><domain>GData</domain><code>ServiceException</code><internalReason>Internal Error</internalReason></error></errors>
-----------------------------------------------------------
This is being caused by <yt:accessControl action="list"/> in your request, which isn't a valid value. It should be something like <yt:accessControl action='list' permission='denied'/>
That being said, the API should handle that gracefully and not return an internal server error. I'll file a bug with the relevant folks internally to fix that.

Resources