PDA

View Full Version : UplHold an OAuth 2.0 compliant service



franco
27-Dec-2015, 07:46 AM
Hello Mike
I trying to implement UpHold the "world's fastest growing platform for moving, converting?, transacting ?and holding any form of money or commodity.?Instantly, securely and for free". Uphold is an OAuth 2.0 compliant service -info here: https://uphold.com/en/what-we-do/developers https://uphold.com/en/developer/api/documentation

I think this could be very useful implementation for all ecommerce Dataflex applications. They offer full api for developers, here some app developed used their api https://uphold.com/en/apps

So I started to study it to see how we can implement with OAuth Library for Dataflex. The application created with uphold api must be secured with a valid SSL certificate issued by a known Certificate Authority. Likewise, the provided Redirect URL when registering the application must be a valid static subresource

For now I got the base informations to get access... so I implemented follow values




Object oUPHttp is a cHttpTransferUIG

Set psRemoteHost to "api-sandbox.uphold.com"
Set piRemotePort to rpHttpSSL
Set peTransferFlags to ifSecure
End_Object

Object oOAuth is a cOAuth2
Set wpsOAuth2Url to "https://uphold.com/authorize/" <<<< it could be wrong?
Set wpsClientID to "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // ClientID could be generated from uphold using a sandbox account
Set wpsRedirectUrl to "https://dataflex.it/OAuth2/Callback.html" // this empty page i created to receive back from upload
// Normal properties
Set psClientSecret to "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // app secret could be generated from uphold using a sandbox account
// https://sandbox.uphold.com/login

Set psTokenHost to "api-sandbox.uphold.org"
Set psTokenPath to "oauth2/token" //or "v0/me/tokens" for personal access with login e pasw with basic authentication // correct sintax only branch or all path?
Set wpsAuthCdName to "authorization_code" // it is correct?
......


and add these two parameters required



Procedure OnBeforeLogin
Send ClearParams

Send AddParam "scope" "cards:Read" // command scope
End_Procedure


first when I try to login I Got 404 error Sorry, that page doesn't exist! looking to further investigate.
If you have some suggestion thanks.


regards
Franco Spinella
websoftwarerevolution.com (http://websoftwarerevolution.com)
francospinella.com (http://francospinella.com)
bitcoinsalvation.com (http://bitcoinsalvation.com)

franco
27-Dec-2015, 09:42 AM
after changed Set wpsOAuth2Url to "https://uphold.com/authorize/" to "https://api-sandbox.uphold.com/authorize/"

I now get the message within the popup windows (instead of login there is this message) : {"code":"not_found","message":"Not Found"} what mean that the authorization passed at least?

so the address iscorrect. But there is no login, maybe that I can insert and debugger only capture the event OnBeforeLogin . . and after Send ClientAction "login" appear the message above on the browser page
so never go to the events "OnLogin" or OnLoginFail
I think that I should send Code that they sent to me after validation but still don't know how

after authorization need STEP 2 - REQUESTING A TOKEN

If the user accepts your request, Uphold will redirect the user back to your site with a temporary code and the previously provided state, as is.
This temporary code is valid for a duration of 5 minutes and can only be used once.
their example to get the code

curl https://api.uphold.com/oauth2/token \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-u <clientId>:<clientSecret> \
-d 'code=<code>&grant_type=authorization_code'


any idea how can do it?, or what I wronging ... always if the authorization is now accepted, thing that I'm not sure.
. Further investigations need

franco
29-Dec-2015, 06:01 AM
I got some result after I setting these value


Set wpsOAuth2Url to "https://uphold.com/authorize/<myclientid>"

Set wpsClientID to "<myclientid>"
Set wpsRedirectUrl to "https://dataflex.it/oAuth2/Callback.html"



Procedure OnBeforeLogin
Send ClearParams
Send AddParam "scope" "user:read"
End_Procedure

I can open the popup login page and do all step to login correctly, the system ask a second factor and then require to confirm the authorization to the user in this case user:read. And the request is correctly added to the account, but the webapp do not capture any event back. Maybe I missing something

On the Popup browser page I can read the correct redirect address with the Code I need to can do all other operation something like
https://www.dataflex.it/dinastyoffreedom/callback.html?code=45be3820f084c62550f13c4e0edafb7 12de51db4&state=0F9B0ECF-F5DF-48F5-9653-E4761989F8EF

but I cannot capture any of the events back to can use, for example it could be good if I could trap the message LoginDone that allow me to get wpsAuthCode :

Procedure LoginDone
String sCode sToken sID sReDir sSecret sPath sBody sResp sHost
Integer iOK i iLastNode
Boolean bOK bError
tJsonNode json
tGrantToken tResp

WebGet wpsAuthCode to sCode



......

any Idea how to get this?

franco
29-Dec-2015, 11:42 AM
I did further step now the authentication is correct. but after login, and second factor authentication I have the code to continue
but the browser popup login is not closed and I cant capture the event LoginDone.
After investigation with Firebug I saw that this line win.document.URL.indexOf(obj.wpsRedirectUrl) is always -1



if (win.document.URL.indexOf(obj.wpsRedirectUrl) != -1) {

so never it can close the popup windows. But I can see the full url correct with the redirect page
obj.wpsRedirectUrl content is correct and it si what I specified in wpsRedirectUrl = https://www.dataflex.it/dinastyoffreedom

win.document.URL.indexOf should be include the full url ie: https://www.dataflex.it/dinastyoffreedom/callback.html?code=xxxxxxxxxxxxxxxxxxx&state=yyyyyyyyyyyyyyyyyyyyy

but probably something is wrong since.
if (win.document.URL.indexOf(obj.wpsRedirectUrl) != -1) never it is passed

So i further will investigate but this see m to be a problem to solve within the oAuth2.js


if Mike have some suggestion for this it will be appreciate.

franco
30-Dec-2015, 05:46 AM
After further investigation I realized that the problem to solve is within the oAuth2.js I debugged the javascript and what happen is strange and I need help of someone that know better javascript.
the line

if (win.document.URL.indexOf(obj.wpsRedirectUrl) != -1) {
give always -1
also after that the poup windows page is redirect to the right address after login and then Win.document.Url have theriright full 'callback' address. I can checking the value with debugger and it is always showed to the popup browser address bar, like you can see on follow picture that is the login popup windows after login and after confirmed sms code
1) open popup login
9634
After confirm login appear this popup
9635
after confirmed the sms code I got the right redirect address
9633
then I can see with debugger:

win.document.URL =
"https://www.dataflex.it/dinastyoffreedom/callback.html?code=efc5d7b0defc46cec319864787f9e11 abce092c1&state=D4930E61-E53F-4AE4-AEAF-3F961ABB91AF"
and obj.wpsRedirectUrl =
"https://www.dataflex.it/dinastyoffreedom/callback.html"

so the result should be 0 and the the condition passed but instead the condition is always -1

What I can saw, that is different compared with other already implemented services is that after popup login windows (see picture above), I got this new internal smal popup windows where I need to enter double factor protection that is a code number that I receive via Sms. I think this can create some access problem to win.document.URL

So I suppose that this could be a problem, that can be soved changing win.document.URL with something else...
the debugger check the line if (win.document.URL.indexOf(obj.wpsRedirectUrl) != -1) but fails always
Looking with the mouse cursor... over the single word.. win report a correct address but .document and .url dont show any tooltip. but how you can see on the below picture using debugger I can found the right values on the left debugger panel!
9632
so since the values exist but cannot be read directly for some reason since
if (win.document.URL.indexOf(obj.wpsRedirectUrl) != -1) always fails ( I suppose that there is some javascript way to can do it. But still I dind't found it

I tested all other examples and they of course work when I debug the line
if (win.document.URL.indexOf(obj.wpsRedirectUrl) != -1) after login it report the right values and the popup is close and the process come back to the dataflex events. but if I try to access directly win.document property also debugger say "denied to access property "document"

Meantime I still continue to try... If MIKE or someone else that know better java script have some idea how to solve this strange problem... It will be appreciate a lot
I suppose that after this step I can complete all others integration steps to can send receive money, transfer and convert to any currency (24 fiat currencies plus Bitcoin and 4 precious metals all with free rate conversion. It is a very powerfull integration for any Dataflex ecommerce solution).. and I will share with all of you the results with all sources.

franco
30-Dec-2015, 10:23 AM
ok. the problem is a cross site security problem. I don't understand well why other Mike's samples work using Localhost redirect
Looking on internet seem that there is some solution like add in the header Access-Control-Allow-Origin *
looking now how.... if server or client... looks that it is not so easy work with multiple domines
If someone have some knowledge about this concern that can be useful to solve this problem with oath2.js.... it should be nice!:o

Mike Peat
31-Dec-2015, 01:06 PM
Hi Franco - sorry to not be responding very quickly: I have been out of the office since before Christmas and will be away until the 5th of January.

However, I may be able to help a little in the meantime.

Firstly, I use localhost in my samples because that is easy for development and testing - it should not (and cannot) be used for deployment, because that only works if the web app and the browser using it are on the same machine (i.e. "localhost").

What URL are you launching your web app on? From what I am seeing in your messages, it would need to be, at the very least, on https://www.dataflex.it (not localhost) somewhere. The OAuth2 component launches the oauth2.js stuff in whatever domain and path it (the web app) is running in, so if that is not on the same host as the callback URL, the browser will not let the JavaScript look at the data in the callback pop-up, which you need it to be able to do.

Assuming you are running your web app on the www.dataflex.it (http://www.dataflex.it) machine, make sure that you launch it (either from the studio, or manually from the browser) using: "https://www.dataflex.it/...rest-of-path-to-web-app.../index.html".

There may be other issues, but that looks likely to be the first one.

Have a Happy New Year!

Mike

franco
1-Jan-2016, 08:27 AM
Hello Mike good year, not worry thank you for the answer

I realized that problem was the javascript security that don't allow the access to 2 differents https domine or protocol.. Infact debugging everything was fine
Only .document was not accessible so never comeback to application and never close the popup login window

but Today 2016 so I wake up this morning with another solution in mind that by pass the limit of javascript authorization working with 2 different https domine
infact Fortunately there was another way to get the personal access code, it is what they call PAT to get a personal code authorization.
So I solved the first important

Without need oAuth2 only using Http class. But now that I got the Authorization Code I can get access to all other functions using oAuth2 class

This is how I solved.



Object oUPHttp is a cHttpTransferUIG

Function createauthorization String soptToken String username String password String smycomment Returns Boolean
String sReDir sID sSecret sPath sHost sData sVar sBody
Integer iLen iOK
Address aBinary

Move "v0/me/tokens" to sPath

Send Reset
Set psRemoteHost to "api.uphold.com"
Set piRemotePort to rpHttpSSL // Is this always the case?
Set peTransferFlags to ifSecure // Presumably this *is* always the case

// aBinary could be any binary data of length iLen.
Move ( trim( String(username))+":" + (trim(String(password )))) to sData
Move (AddressOf(sData)) to aBinary
Move (Length(sData)) to iLen


// base64Encode to string
Get Base64EncodeToStr of oCharTranslate aBinary iLen to sVar
Get AddHeader "Content-Type" "application/json" to iOK

Get AddHeader "Authorization" ("Basic" * (String(sVar)) ) to iok
Get AddHeader "Access-Control-Allow-Origin" "*" to iOK // it don't really need
If (soptToken >"") Get AddHeader "X-Bitreserve-OTP" (String( soptToken)) to iok // double authentication factor if enabled on the uphold backoffice it need
// to get before send command need to login uphold and receive sms by code
//soptToken Must be = to the sms token received by uphold
Move ('{ "description": '+'"'+sMyComment+'" }' to sBody

Get HttpVerbAddrRequest sPath (AddressOf(sBody)) (Length(sBody)) False "POST" to iOK
Function_Return iOK
End_Function
end_object


After the succesfull "POST" , using psgetdata I can check the return data in json format somenthing like

//{"accessToken":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","description":"My command line script","id" :"yyyyyyyyyyyyyyyyyyyyyyyyyyyy"}
accessToken is what I need to can do all other stuff

There is a DF Json class to parse this string like we can do with Xml? or I need to parse by myself, it is not a problem of course do it. But always better use standard df classes/methods.

Anyway now I can create a df Class with all functions to read/write create transactions, money transfer and more.... using oAuth2, when finish I will publish here the source! Hope to not found other problems

Hope this was more complex part (:>) I lost 2 full days to can write these few lines of code (:<)