Issue with OAuth and Flickr - cannot request token - actionscript-3

I am currently trying to request a token from Flickr to then be able to do some calls to their OAuth methods. I know I must be doing something wrong, for I get a reply that the signature is wrong, but honestly I followed their instructions (http://www.flickr.com/services/api/auth.oauth.html, http://www.flickr.com/services/api/auth.oauth.html#request_token, http://www.flickr.com/services/api/flickr.auth.oauth.getAccessToken.html) but I still get an error:
oauth_problem=signature_invalid&debug_sbs=GET&http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token&oauth_callback%3D%26oauth_consumer_key%3Da0f20d2c9b0a142848cffdf9d9a5ad78%26oauth_nonce%3DFCBB713F-581E-4BC6-42FF-C50252D839EC%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1330450158%26oauth_version%3D1.0
I don't get how to create that signature nor how to put it in the request, could anybody point me in the right direction? Thanks!
I am currently working with AS3, below is my code:
// request params
var now:Date = new Date();
var requestParams:Object = {};
requestParams.oauth_callback = ""; // there is no callback, it's a desktop application
requestParams.oauth_consumer_key = API_KEY;
requestParams.oauth_nonce = UIDUtil.getUID(now);
requestParams.oauth_timestamp = String(now.time).substring(0, 10);
requestParams.oauth_signature_method = "HMAC-SHA1";
requestParams.oauth_version = "1.0";
// create an array to sort param names alphabetically
// mandatory to create signature
var sortedRequestParamNames:Array = [];
var name:String;
for(name in requestParams)
{
sortedRequestParamNames.push(name);
}
sortedRequestParamNames.sort();
// create signature
// see http://www.flickr.com/services/api/auth.spec.html#signing
var oauthSignature:String = API_SECRET;
var i:uint;
var numParams:uint = sortedRequestParamNames.length;
var paramName:String;
for(i = 0; i < numParams; i++)
{
paramName = sortedRequestParamNames[i];
oauthSignature += paramName + convertToPercentEntities(requestParams[paramName]);
}
oauthSignature = MD5.hash(oauthSignature);
// build request
var tokenRequestString:String = REQUEST_TOKEN_URL;
for(i = 0; i < numParams; i++)
{
paramName = sortedRequestParamNames[i];
tokenRequestString += (i == 0) ? "?" : "&";
tokenRequestString += paramName + "=" + requestParams[paramName];
}
tokenRequestString += "&oauth_signature=" + oauthSignature;
var tokenRequest:URLRequest = new URLRequest(tokenRequestString);
tokenRequest.method = URLRequestMethod.GET;
// load request
initLoader();
_loader.addEventListener(Event.COMPLETE, requestTokenLoadedHandler);
_loader.load(tokenRequest);

Basically, you need to use the HMAC-SHA1 algorithm instead of an MD5. I'll walk you through it.
1. Create the signature base string
You seem to be doing that (but you are assigning it directly to the signature variable). Compiling the base string is done by concatenating three different parts.
Convert the HTTP Method to uppercase and set the base string equal to this value. Example: GET
Append the '&' character to the base string.
Percent encode the URL (without parameters) and append it to the base string. Example: http%3A%2F%2Fexample.com%2Frequest
Append the '&' character to the base string.
Percent encode the sorted parameter string and append it to the base string.
It should end up looking like this:
GET&http%3A%2F%2Fexample.com%2Frequest&a2%3Dr%2520b%26a3%3D2%2520q
%26a3%3Da%26b5%3D%253D%25253D%26c%2540%3D%26c2%3D%26oauth_consumer_
key%3D9djdj82h48djs9d2%26oauth_nonce%3D7d8f3e4a%26oauth_signature_m
ethod%3DHMAC-SHA1%26oauth_timestamp%3D137131201%26oauth_token%3Dkkk
9d7dh3k39sj
Now you're done with the signature base string. Lets move on to
2. Figuring out your signing key.
Your signing key is on this format: CONSUMER_SECRET + "&" + TOKEN_SECRET. But since you do not have a token yet, the signing key is the consumer secret and an ampersand. Like this: CONSUMER_SECRET + "&".
For all requests, except the first one your will have a token though, either a request token or an access token.
3. Combine the key and the base string using the HMAC-SHA1 algorithm.
I have used http://code.google.com/p/as3crypto/ when signing with AS3. You can even test its HMAC-SHA1 algorithm on this demo page: http://crypto.hurlant.com/demo/.
Use the base string as input, and the signing key as key to the HMAC-SHA1 algorithm.
The output of the HMAC-SHA1 algorithme will be a binary string which needs to be base64 encoded to produce the final signature. It should look something like this:
NYIQGEwIomgCuVOIA28pMDMID78=
This should be send with the request as the oauth_signature parameter.

I had problem with it too, ended up using FlickrNet API.
http://flickrnet.codeplex.com/

Related

Is there a simple way to have a local webpage display a variable passed in the URL?

I am experimenting with a Firefox extension that will load an arbitrary URL (only via HTTP or HTTPS) when certain conditions are met.
With certain conditions, I just want to display a message instead of requesting a URL from the internet.
I was thinking about simply hosting a local webpage that would display the message. The catch is that the message needs to include a variable.
Is there a simple way to craft a local web page so that it can display a variable passed to it in the URL? I would prefer to just use HTML and CSS, but adding a little inline javascript would be okay if absolutely needed.
As a simple example, when the extension calls something like:
folder/messageoutput.html?t=Text%20to%20display
I would like to see:
Message: Text to display
shown in the browser's viewport.
You can use the "search" property of the Location object to extract the variables from the end of your URL:
var a = window.location.search;
In your example, a will equal "?t=Text%20to%20display".
Next, you will want to strip the leading question mark from the beginning of the string. The if statement is just in case the browser doesn't include it in the search property:
var s = a.substr(0, 1);
if(s == "?"){s = substr(1);}
Just in case you get a URL with more than one variable, you may want to split the query string at ampersands to produce an array of name-value pair strings:
var R = s.split("&");
Next, split the name-value pair strings at the equal sign to separate the name from the value. Store the name as the key to an array, and the value as the array value corresponding to the key:
var L = R.length;
var NVP = new Array();
var temp = new Array();
for(var i = 0; i < L; i++){
temp = R[i].split("=");
NVP[temp[0]] = temp[1];
}
Almost done. Get the value with the name "t":
var t = NVP['t'];
Last, insert the variable text into the document. A simple example (that will need to be tweaked to match your document structure) is:
var containingDiv = document.getElementById("divToShowMessage");
var tn = document.createTextNode(t);
containingDiv.appendChild(tn);
getArg('t');
function getArg(param) {
var vars = {};
window.location.href.replace( location.hash, '' ).replace(
/[?&]+([^=&]+)=?([^&]*)?/gi, // regexp
function( m, key, value ) { // callback
vars[key] = value !== undefined ? value : '';
}
);
if ( param ) {
return vars[param] ? vars[param] : null;
}
return vars;
}

Can Microsoft Translator answer "does a word exist" queries?

I want to know if the API can do something like this:
I send a word in an predetermined language
API answer if the word exist in that language.
To add some context to the question, the idea is to develop a Scrabble like game, and I'm investigating a method to detect valid words, for all (or most common) languages that is.
I've already asked for a solution in one of their forums, but they are kind of dead.
I tested the MS translator service.
var result = MST.TranslateText("xyz", "en", "de"); // custom routine that calls MS service
var result2 = MST.TranslateText("dog", "en", "de");
var result2 = MST.TranslateText("sdfasfgd", "en", "de");
Result = XYZ // source xyz
Result2 = Hund // source dog
Result3 = sdfasfgd // sdfasfgd
Looks like when not found or a translation is not possible the string
is returned untouched.
The only strange behavior i've noted is conversion to uppercase for Some 3 letter scenarios that
arent obvious TLAs in either langauge.
public string TranslateText(string sourceText, string fromLang, string toLang) {
var httpRequestProperty = GetAuthorizationRequestHeader();
var msTransClient = new TranslatorService.LanguageServiceClient();
// Creates a block within which an OperationContext object is in scope.
using (var scope = new OperationContextScope(msTransClient.InnerChannel))
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
//Keep appId parameter blank as we are sending access token in authorization header.
var translationResult = msTransClient.Translate("", sourceText, fromLang, toLang, "text/plain", "");
return translationResult;
}
}

How to encode a JSON object before using it by borswe URL testing

http://localhost/catalog/{"request": "catalog","user_id": "test#gmail.com","purchased": "2"}
here goes my request URL. I need to test my service with a sample URL typed in browser. But it seems that many of the JSON items do not accepted by the server side. if i enter plane text string server works fine. I tried to encode the URL using http://www.albionresearch.com/misc/urlencode.php, but still the errors are there.
May be this is a problem which belongs to tapestry. Else i would like to get some help.
following request works.
http://localhost/catalog/helloworld
tapestry performs its own encoding of parameters within urls, which there is no replica for on the client side.
see org.apache.tapestry5.internal.services.URLEncoderImpl.encode(String)
the reason 'helloworld' works as expected is that there are no 'special characters' so the escaped value would equal 'helloworld' anyway.
So you will either need to encode your json via java using tapestry's URLEncoder or write a client side replica.
that is, if i understand your question properly.
EDIT i was bored so I wrote the client side replica:
/**
* see org.apache.tapestry5.internal.services.URLEncoderImpl.encode(String)
* correct as at tapestry 5.3.5
*/
function tapestryUrlEncodeParameter(input)
{
var safe = "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "01234567890-_.:";
if (input === null)
return "$N";
input = input.toString();
if (input === "")
return "$B";
var output = "";
for (var i = 0; i < input.length; i++)
{
var ch = input.charAt(i);
if (ch === '$')
{
output += "$$";
continue;
}
if (safe.indexOf(ch) != -1)
{
output += ch;
continue;
}
var chHex = ch.charCodeAt(0).toString(16);
while (chHex.length < 4)
chHex = "0" + chHex;
output += "$" + chHex;
}
return output;
}
What do you have server side? Either way you will have to decode your encoded json string on the server side if you want to do it this way.
A better solution might be to use a testing tool of some kind. This could be as simple as a jquery $.get request in a webpage or perhaps you might want to think about a more versatile HTTP client as suggested in this post

Losing leading 0s when string converts to array

I have a textInput control that sends .txt value to an array collection. The array collection is a collection of US zip codes so I use a regular expression to ensure I only get digits from the textInput.
private function addSingle(stringLoader:ArrayCollection):ArrayCollection {
arrayString += (txtSingle.text) + '';
var re:RegExp = /\D/;
var newArray:Array = arrayString.split(re);
The US zip codes start at 00501. Following the debugger, after the zip is submitted, the variable 'arrayString' is 00501. But once 'newArray' is assigned a vaule, it removes the first two 0s and leaves me with 501. Is this my regular expression doing something I'm not expecting? Could it be the array changing the value? I wrote a regexp test in javascript.
<script type="text/javascript">
var str="00501";
var patt1=/\D/;
document.write(str.match(patt1));
</script>
and i get null, which leads me to believe the regexp Im using is fine. In the help docs on the split method, I dont see any reference to leading 0s being a problem.
**I have removed the regular expression from my code completely and the same problem is still happening. Which means it is not the regular expression where the problem is coming from.
Running this simplified case:
var arrayString:String = '00501';
var re:RegExp = /\D/;
var newArray:Array = arrayString.split(re);
trace(newArray);
Yields '00501' as expected. There's nothing in the code you've posted that would strip leading zeros. You may want to dig around a bit more.
This smells suspiciously like Number coercion: Number('00501') yields 501. Read through the docs for implicit conversions and check if any pop up in your code.
What about this ?
/^\d+$/
You can also specify exactly 5 numbers like this :
/^\d{5}$/
I recommend just getting the zip codes instead of splitting on non-digits (especially if 'arrayString' might have multiple zip codes):
var newArray:Array = [];
var pattern:RegExp = /(\d+)/g;
var zipObject:Object;
while ((zipObject = pattern.exec(arrayString)) != null)
{
newArray.push(zipObject[1]);
}
for (var i:int = 0; i < newArray.length; i++)
{
trace("zip code " + i + " is: " + newArray[i]);
}

Extracting "filename" from full path in actionscript 3

Does AS3 have a built in class / function to extract "filename" from a complete path. e.g. I wish to extract "filename.doc" from full path "C:\Documents and Settings\All Users\Desktop\filename.doc"
For Air, you can try using File Class to extract file name
var file:File=new File("path_string");
//path_string example "C:\\Windows\\myfile.txt"
var filename:String = file.name;
First you want to find the last occurrence of / or \ in the path, do that using this:
var fSlash: int = fullPath.lastIndexOf("/");
var bSlash: int = fullPath.lastIndexOf("\\"); // reason for the double slash is just to escape the slash so it doesn't escape the quote!!!
var slashIndex: int = fSlash > bSlash ? fSlash : bSlash;
That will give you the index in the string that is right BEFORE that last slash. So then to return the portion of the string after that, you add one to the index (moving it past the last slash) and return the remainder of the string
var docName: String = fullPath.substr(slashIndex + 1);
To do this as a simple to use function, do this:
function getFileName(fullPath: String) : String
{
var fSlash: int = fullPath.lastIndexOf("/");
var bSlash: int = fullPath.lastIndexOf("\\"); // reason for the double slash is just to escape the slash so it doesn't escape the quote!!!
var slashIndex: int = fSlash > bSlash ? fSlash : bSlash;
return fullPath.substr(slashIndex + 1);
}
var fName: String = getFileName(myFullPath);
Couldn't you just do something basic like:
string filename = filename.substring(filename.lastIndexOf("\\") + 1)
I know it's not a single function call, but it should work just the same.
Edited based on #Bryan Grezeszak's comment.
Apparently you can use the File class, or more specifically, the File.separator static member if you're working with AIR. It should return "/" or "\", which you can plug in to #cmptrgeekken's suggestion.
Try this:
var file_ :File = new File("C:/Usea_/Dtop/sinim (1).jpg"); // or url variable ... whatever//
file_ = file_.parent;
trace(file_.url);
You can use something like this to do the job :
var tmpArray:Array<String>;
var fileName:String;
tmpArray = fullFilePath.split("\");
fileName = tmpArray.pop();
You have to take care if you are using Unix file system ("/") or Windows file system ("\").