upload doc on dropbox how to get url - ruby-on-rails

How to get URL uploaded doc on drop box and how to store this URL our data base.
This is the code :
def passport_upload
app_key = ENV['APP_DROPBOX_APP_KEY_DEVELOPMENT']
app_secret = ENV['APP_DROPBOX_APP_SECRET_DEVELOPMENT']
flow = DropboxOAuth2FlowNoRedirect.new(app_key, app_secret)
authorize_url = flow.start()
client=DropboxClient.new(ENV['APP_DROPBOX_ACCESS_TOKEN_DEVELOPMENT'])
file = open(params[:doc])
file_name = params[:doc].original_filename
response = client.put_file(file_name, file)
end

If you want the URL to retrieve it using authorized access, you should appending the path returned in the metadata response to https://content.dropboxapi.com/1/files/auto/ (per https://www.dropbox.com/developers-v1/core/docs#files-GET).
If you want to publicly share it and get a public URL you will have to
make a call to share it (per https://www.dropbox.com/developers-v1/core/docs#shares)
client.shares(response.path)

Related

How to replace an existing video in Dailymotion API?

I'm building an app using Dailymotion API
https://developer.dailymotion.com/
with official python sdk
https://github.com/dailymotion/dailymotion-sdk-python
and writing video CRUD(Create, Read, Update, Delete) simply.
Create, Read, Delete were succeccfully completed, but encountering a weird response of the API about "Update".
Here is a simplified snippet of my code in my Django project,
def update(request, video_id):
user = request.user
video = get_object_or_404(Video, pk=video_id)
file_path = # define file_path from uploaded file object
input_title = # define input_title from post request
input_description = # define input_description from post request
d = get_dailymotion_d(user)
if d == 'revoked':
# do actions of logout and delete the user
try:
# get url for upload with the file_path on my server
url = d.upload(file_path)
# update
response = d.post('/video/' + video.dailymotion_video_id, {'url': url, 'title': input_title, 'description': input_description, 'published': 'true', 'channel': 'creation'})
# delete the video from my sever
video.file_field.delete()
return redirect('/videos')
except Exception as e:
print(e.args)
print('update failed..!')
# delete the video from my server
video.file_field.delete()
return redirect('/videos')
def get_dailymotion_d(user):
d = dailymotion.Dailymotion()
d.set_grant_type('token', api_key=settings.DAILYMOTION_API_KEY, api_secret=settings.DAILYMOTION_API_SECRET, scope=['email', 'userinfo', 'manage_videos'], info={'redirect_uri': settings.DAILYMOTION_REDIRECT_URI})
# get credentiaols from database
access_token = user.dailymotionuser.access_token
expires = user.dailymotionuser.expires
refresh_token = user.dailymotionuser.refresh_token
session_params = {'access_token': access_token, 'expires': expires, 'refresh_token': refresh_token}
# set the credentials
d._session_store.set(session_params)
# check if the user revoked or not
try:
force_refreshed_access_token = d.get_access_token(force_refresh=True)
except dailymotion.DailymotionAuthError as e:
print(e.args[0])
return 'revoked'
# get valid access token
valid_access_token = d.get_access_token()
# update database with the valid access token
DailymotionUser.objects.filter(user=user).update(access_token=valid_access_token, expires=expires, refresh_token=refresh_token)
# prepare dic of the valid access token
valid_access_token_dic = {'access_token': valid_access_token}
# set the valid access token
d._session_store.set(valid_access_token_dic)
return d
but the update fails except title field with the following message,
'access_forbidden: You are not allowed to change existing video source.'
from doc,
access_forbidden: Thrown when the user doesn't have the permission to access the data (e.g. missing a required scope to access certain fields).
but I'm sure that the permission has manage_videos scope which is an enough scope to update the existing video source because the doc says,
manage_videos: Allows to modify or delete the user's uploaded videos and to publish new ones.
and described above,
Only the title field of the video is updated with the input_title properly.
Thanks for reading, I researched their docs carefully, but still don't understand this response.
Only partner users can update the video source urls.
Best,

Trying to generate a presigned url link so an user can download an Amazon S3 object, but getting invalid request

I am currently using the Ruby aws-sdk, version 2 gem with server-side customer-provided encryption key(SSE-C). I am able to upload the object from a rails form to Amazon S3 with no issues.
def s3
Aws::S3::Object.new(
bucket_name: ENV['S3_BUCKET'],
key: 'hello',
)
end
def upload_object
customer_key = OpenSSL::Cipher::AES.new(256, :CBC).random_key
customer_key_md5 = Digest::MD5.new.digest(customer_key)
object_key = 'hello'
options = {}
options[:key] = object_key
options[:sse_customer_algorithm] = 'AES256'
options[:sse_customer_key] = customer_key
options[:sse_customer_key_md5] = customer_key_md5
options[:body] = 'hello world'
options[:bucket] = ENV['S3_BUCKET']
s3.put(options)
test_params = {
object_key: object_key,
customer_key: Base64.encode64(customer_key),
md5_key: Base64.encode64(customer_key_md5),
}
Test.create(test_params)
end
But I'm having some issues with retrieving the object and generating a signed url link for the user to download it.
def retrieve_object(customer_key, md5)
options = {}
options[:key] = 'hello
options[:sse_customer_algorithm] = 'AES256'
options[:sse_customer_key] = Base64.decode64(customer_key)
options[:sse_customer_key_md5] = Base64.decode64(md5)
options[:bucket] = ENV['S3_BUCKET']
s3.get(options)
url = s3.presigned_url(:get)
end
The link is generated, but when I clicked on it, it directs me to an amazon page saying.
<Error>
<Code>InvalidRequest</Code>
<Message>
The object was stored using a form of Server Side Encryption. The correct parameters must be provided to retrieve the object.
</Message>
<RequestId>93684EEBA062B1C2</RequestId>
<HostId>
OCnn5EG7ydfoKzsmEDMbqK5kOhLFpNXxVRdekfhOfnBc6s+jtPYFsKi8IZsEPcd9ConbYUHgwC8=
</HostId>
</Error>
The error message is not helping as I'm unsure what parameters I need to add. I think I might be missing some permissions parameters.
Get Method
http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#get-instance_method
Presigned_Url Method
http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#presigned_url-instance_method
When you generate a pre-signed GET object URL, you need to provide all of the same params that you would pass to Aws::S3::Object#get.
s3.get(sse_customer_algorithm: 'AES256', sse_customer_key: customer_key).body.read
This means you need to pass the same sse_customer_* options to #presigned_url:
url = obj.presigned_url(:get,
sse_customer_algorithm: 'AES256',
sse_customer_key: customer_key)
This will ensure that the SDK correctly signs the headers that Amazon S3 expects when you make the final GET request. The next problem is that you are now responsible for sending those values along with the GET request as headers. Amazon S3 will not accept the algorithm and key in the query string.
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri, {
"x-amz-server-side-encryption-customer-algorithm" => 'AES256',
"x-amz-server-side-encryption-customer-key" => Base64.encode64(cpk),
"x-amz-server-side-encryption-customer-key-MD5" => Base64.encode64(OpenSSL::Digest::MD5.digest(cpk))
})
Please note - while testing this, I found a bug in the presigned URL implementation of the current v2.0.33 version of the aws-sdk gem. This has been fixed now and should be part of v2.0.34 once it releases.
See the following gitst for a full example that patches the bug and demonstrates:
Uploads an object using a cpk
Gets the object using the SDK
Generates a presigned GET url
Downloads the object using just Net::HTTP and the presigned URL
You can view the sample script here:
https://gist.github.com/trevorrowe/49bfb9d59f83ad450a9e
Just replace the bucket_name and object_key variables at the top of the script.

How to get LinkedIn profile picture using OAuth?

Users can log in to my Rails app using their LinkedIn account thanks to OAuth. However, I am having trouble displaying the user's profile image. The following URL does not load a picture:
<%= image_tag("http://api.linkedin.com/v1/people/{user-id}/picture-url") %>
How can I get the user's LinkedIn profile image to display in my Rails app?
Thanks!
Try to get the original picture with:
http://api.linkedin.com/v1/people/{user-id}/picture-urls::(original)
Update:
From current docs (recommend to read it):
Using current user (after user logged in):
http://api.linkedin.com/v1/people/~:(picture-url)
Using member_id:
http://api.linkedin.com/v1/people/id=12345:(picture-url)
Public profile:
http://api.linkedin.com/v1/people/url=<public-profile-url>:(picture-url)
Those URLs return xml, so you could parse the xml response to get picture-url string and use it as a param for image_tag. Alternatively, you can retrieve info as a json passing an extra param like:
http://api.linkedin.com/v1/people/~:(picture-url)?format=json
In both cases (xml or json), you need to extract the picture-url from api response for passing it to image_tag.
This gem omniauth-linkedin-oauth2 could probably help you.
This is my solution working perfectly:
def callback(self):
self.validate_oauth2callback()
oauth_session = self.service.get_auth_session(
data={'code': request.args['code'],
'grant_type': 'authorization_code',
'redirect_uri': self.get_callback_url()},
decoder=jsondecoder
)
me = oauth_session.get('people/~:(id,first-name,last-name,public-profile-url,email-address,picture-url,picture-urls::(original))?format=json&oauth2_access_token='+str(oauth_session.access_token), data={'x-li-format': 'json'}, bearer_auth=False).json()
social_id = 'linkedin$' + me['id']
name = me['firstName']
surname = me['lastName']
email = me['emailAddress']
url = me['publicProfileUrl']
image_small = me.get('pictureUrl', None)
image_large = me.get('pictureUrls', {}).get('values', [])[0]
return social_id, name, surname, email, url, image_small, image_large, me

How can I access a raw private paste from pastebin?

I know how to generate a user key using the pastebin API, but how can I use this userkey to access a raw private paste?
I am using Lua for this.
Obtaining the raw paste bin output is not part of of the Pastebin API:
This option is actually not part of our API, but you might still want to use it. To get the RAW output of a paste you can use our RAW data output URL:
http://pastebin.com/raw.php?i=
Simply add the paste_key at the end of that URL and you will get the RAW output.
Since private pastes can only be seen by the user who created them, my guess is that they use the logincookie for authentication. In that case, you'll need to send it with the HTTP request.
In respect to implementing this in Lua, (since you haven't said which library you're using) I'm gonna go forth and recommend the HTTP module in LuaSocket or the wonderful Luvit (http://luvit.io).
Here is a ready example of the code for you:
local https = require('ssl.https')
https.TIMEOUT= 15
local private_raw_url="https://pastebin.com/raw/YOURPAGE" -- Change raw link
local user_name, user_password = "USER", "PASS" -- and user with password
local request_body = "submit_hidden=submit_hidden&user_name=".. user_name .. "&user_password=" .. user_password .. "&submit=Login"
local resp = {}
local res, code, headers, status = https.request ( {
method = 'POST',
url = "https://pastebin.com/login",
headers = {
Host = "pastebin.com",
["Content-Type"] = "application/x-www-form-urlencoded",
["Content-Length"] = string.len(request_body),
Connection = "keep-alive",
},
source = ltn12.source.string(request_body),
sink = ltn12.sink.table(resp),
protocol = "tlsv1",
verify = "none",
verifyext = {"lsec_continue", "lsec_ignore_purpose"},
options = { "all", "no_sslv2", "no_sslv3" }
} )
if not headers['set-cookie']:find('pastebin_user') then
print('bad login')
return
end
resp={}
local cookie = headers['set-cookie'] or ''
local cookie1, cookie2, cookie3 = cookie:match("(__cfduid=%w+; ).*(PHPSESSID=%w+; ).*(pastebin_user=%w+; )" )
if cookie1 and cookie2 and cookie3 then
cookie = cookie1 .. cookie2 .. cookie3
body, code, headers= https.request{
url = private_raw_url ,
headers = {
--Host = "pastebin.com",
['Cookie'] = cookie,
['Connection'] = 'keep-alive'
},
sink = ltn12.sink.table(resp)
}
if code~=200 then return end
print( table.concat(resp) )
else
print("error match cookies!" )
end
I know that this is a little late to answer the question but I hope this will help someone later on.
If you want to access raw private pastes, you will first need to list the pastes that the user has created. This is a part of the API. This requires the user to be logged in.
With this API you can list all the pastes created by a certain user.
You will need send a valid POST request to the URL below to access the
data:
http://pastebin.com/api/api_post.php
The response that you will get will be an XML response, as follows:
<paste>
<paste_key>0b42rwhf</paste_key>
<paste_date>1297953260</paste_date>
<paste_title>javascript test</paste_title>
<paste_size>15</paste_size>
<paste_expire_date>1297956860</paste_expire_date>
<paste_private>0</paste_private>
<paste_format_long>JavaScript</paste_format_long>
<paste_format_short>javascript</paste_format_short>
<paste_url>http://pastebin.com/0b42rwhf</paste_url>
<paste_hits>15</paste_hits>
</paste>
Once you have that, parse the XML to get the paste_key and the paste_private. You need to check the value of paste_private because you want private pastes only. The documentation says:
We have 3 valid values available which you can use with the
'api_paste_private' parameter:
0 = Public
1 = Unlisted
2 = Private (only allowed in combination with api_user_key, as you have to be logged into your account to access the paste)
So, if your paste has paste_private set to 2, get the paste_key for it.
Once you have the paste_key, use the API call to get the RAW paste. No username or password required once you have the paste key for the private paste.
Have fun!

Google data API for .Net allows Sharing outside organization in Google apps account

I am using Google Data API for .Net(version 1.9) in my application.
I have created a Google apps account and i have set the "Users cannot share documents outside this organization" setting under Google Docs.
When i try to share a file outside of the domain(organization) from Google docs web, i get a error saying the file cannot be shared outside of my domain.
But when i try the same thing from the API, it succeeds. I get a 200 success from the API. When i try to access the file from the share link it says 'You need permission to access this resource'. My question is shouldn't the API return with a error? how can i handle this case?
Here is the code that I am using:
DocumentsRequest request = null;
/* request initialization */
string csBatchReqBody = "<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:gAcl="http://schemas.google.com/acl/2007" xmlns:batch="http://schemas.google.com/gdata/batch"><category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/acl/2007#accessRule"/><entry><id>https://docs.google.com/feeds/default/private/full/document:1DsELtiNwq-ogOrp8cAONdMpGR4gBF79PjijTae-vVNg/acl/user:myusername#mydomain.com</id><batch:operation type="query"/></entry><entry><batch:id>1</batch:id><batch:operation type="insert"/><gAcl:role value="reader"/><gAcl:scope type="user" value="myusername#gmail.com"/></entry>"
string Url = "https://docs.google.com/feeds/default/private/full/document:1DsELtiNwq-ogOrp8cAONdMpGR4gBF79PjijTae-vVNg/acl/batch";
byte[] byteArray = Encoding.ASCII.GetBytes(csBatchReqBody);
MemoryStream inputStream = new MemoryStream(byteArray);
AtomEntry reply = request.Service.Insert(new Uri(Url), inputStream, "application/atom+xml", "");
MemoryStream stream = new MemoryStream();
reply.SaveToXml(stream);
The API actually returns a 400 if you try to share a file outside the domain and the admins have set the "Users cannot share documents outside this organization" flag.
Your code sends a batch request (even if for a single element), you'd have to check the batch response to notice the error.
Instead, use the following code to share a document to a single user, it assumes that entry is the DocumentEntry you want to share:
AclEntry acl = new AclEntry();
acl.Scope = new AclScope("username#gmail.com", "user");
acl.Role = new AclRole("reader");
acl = service.Insert(new Uri(entry.AccessControlList), acl);

Resources