mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
http/oauth fixes, http/fetch POST support, place/threads signatures, place/userthreads: twitter submit
This commit is contained in:
parent
b48557c67a
commit
2ecaf00c24
8 changed files with 237 additions and 183 deletions
|
@ -30,6 +30,7 @@ volatile mapping rheaders = (["User-Agent": SERVER_VERSION]);
|
|||
volatile string http_message;
|
||||
volatile int http_status, port, fetching, ssl;
|
||||
volatile string buffer, thehost, url, fetched, host, resource, method;
|
||||
volatile mixed rbody;
|
||||
|
||||
int parse_status(string all);
|
||||
int parse_header(string all);
|
||||
|
@ -37,8 +38,9 @@ int buffer_content(string all);
|
|||
|
||||
string qHost() { return thehost; }
|
||||
|
||||
varargs void fetch(string murl, string meth, mapping hdrs) {
|
||||
varargs void fetch(string murl, string meth, mixed body, mapping hdrs) {
|
||||
method = meth || "GET";
|
||||
rbody = body;
|
||||
if (hdrs) rheaders += hdrs;
|
||||
if (url != murl) {
|
||||
// accept.c does this for us:
|
||||
|
@ -96,18 +98,28 @@ varargs int real_logon(int failure) {
|
|||
unless (url) return -3;
|
||||
unless (resource) sscanf(url, "%s://%s/%s", scheme, host, resource);
|
||||
|
||||
string body = "";
|
||||
if (stringp(rbody)) {
|
||||
body = rbody;
|
||||
} else if (mappingp(rbody) && sizeof(rbody)) {
|
||||
body = make_query_string(rbody);
|
||||
unless (rheaders["Content-Type"])
|
||||
rheaders["Content-Type"] = "application/x-www-form-urlencoded";
|
||||
}
|
||||
if (strlen(body)) rheaders["Content-Length"] = strlen(body);
|
||||
|
||||
buffer = "";
|
||||
foreach (string key, string value : rheaders) {
|
||||
buffer += key + ": " + value + "\r\n";
|
||||
}
|
||||
|
||||
// we won't need connection: close w/ http/1.0
|
||||
//emit("Connection: close\r\n\r\n");
|
||||
P2(("%O fetching /%s from %O\n", ME, resource, host))
|
||||
P4(("%O using %O\n", ME, buffer))
|
||||
emit(method + " /"+ resource +" HTTP/1.0\r\n"
|
||||
"Host: "+ host +"\r\n"
|
||||
+ buffer +
|
||||
"\r\n");
|
||||
+ buffer + "\r\n" + body);
|
||||
|
||||
buffer = "";
|
||||
next_input_to(#'parse_status);
|
||||
|
|
|
@ -192,7 +192,7 @@ default:
|
|||
return 0;
|
||||
}
|
||||
|
||||
parse_query(query, qs) {
|
||||
mapping parse_query(mapping query, string qs) {
|
||||
foreach (string pair : explode(qs, "&")) {
|
||||
string key, val;
|
||||
|
||||
|
@ -207,3 +207,14 @@ parse_query(query, qs) {
|
|||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
varargs string make_query_string(mapping params, int sort) {
|
||||
string q = "";
|
||||
array(mixed) keys = m_indices(params);
|
||||
if (sort) keys = sort_array(keys, #'>);
|
||||
|
||||
foreach(string key : keys) {
|
||||
q += (strlen(q) ? "&" : "") + urlencode(to_string(key)) + "=" + urlencode(to_string(params[key]));
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
|
|
@ -13,52 +13,49 @@
|
|||
string consumer_key;
|
||||
string consumer_secret;
|
||||
string request_token_url;
|
||||
string request_token;
|
||||
string request_secret;
|
||||
mapping request_params = ([ ]);
|
||||
mapping access_params = ([ ]);
|
||||
string access_token_url;
|
||||
string access_token;
|
||||
string access_secret;
|
||||
string authorize_url;
|
||||
string callback_url = "http://" + my_lower_case_host() + ":" + HTTP_PORT + "/oauth"; //TODO: https?
|
||||
mapping oauth = ([]);
|
||||
object user;
|
||||
|
||||
varargs void fetch(object ua, string url, string method, mapping oauth) {
|
||||
varargs void fetch(object ua, string url, string method, mapping get, mapping post, mapping oauth) {
|
||||
P3((">> oauth:fetch(%O, %O, %O)\n", url, method, oauth))
|
||||
unless (method) method = "GET";
|
||||
unless (get) get = ([]);
|
||||
unless (post) post = ([]);
|
||||
unless (oauth) oauth = ([]);
|
||||
|
||||
oauth["consumer_key"] = consumer_key;
|
||||
if (access_token || request_token) oauth["token"] = access_token || request_token;
|
||||
string token_secret = access_token ? access_secret : request_token ? request_secret : "";
|
||||
oauth["timestamp"] = time();
|
||||
oauth["nonce"] = sprintf("%x", random(oauth["timestamp"] ^ 98987));
|
||||
oauth["signature_method"] = "HMAC-SHA1";
|
||||
oauth["version"] = "1.0";
|
||||
oauth["oauth_consumer_key"] = consumer_key;
|
||||
string token;
|
||||
if (token = access_params["oauth_token"] || request_params["oauth_token"])
|
||||
oauth["oauth_token"] = token;
|
||||
string token_secret = access_params["oauth_token_secret"] || request_params["oauth_token_secret"] || "";
|
||||
oauth["oauth_timestamp"] = time();
|
||||
oauth["oauth_nonce"] = sprintf("%x", random(oauth["oauth_timestamp"] ^ 98987));
|
||||
oauth["oauth_signature_method"] = "HMAC-SHA1";
|
||||
oauth["oauth_version"] = "1.0";
|
||||
|
||||
array(string) params = ({});
|
||||
foreach (string key : sort_array(m_indices(oauth), #'>)) //'))
|
||||
params += ({"oauth_" + key + "=" + urlencode(to_string(oauth[key]))});
|
||||
string base_str = method + "&" + urlencode(url) + "&" + urlencode(implode(params, "&"));
|
||||
oauth["signature"] = hmac_base64(TLS_HASH_SHA1, urlencode(consumer_secret) + "&" + urlencode(token_secret), base_str);
|
||||
P3(("token: %O, token_secret: %O, access: %O, request: %O\n", token, token_secret, access_params, request_params))
|
||||
string base_str = method + "&" + urlencode(url) + "&" + urlencode(make_query_string(get + post + oauth, 1));
|
||||
oauth["oauth_signature"] = hmac_base64(TLS_HASH_SHA1, urlencode(consumer_secret) + "&" + urlencode(token_secret), base_str);
|
||||
|
||||
params = ({});
|
||||
string p = "";
|
||||
foreach (string key, string value : oauth)
|
||||
params += ({"oauth_" + key + "=\"" + urlencode(to_string(value)) + "\""});
|
||||
p += (strlen(p) ? "," : "") + key + "=\"" + urlencode(to_string(value)) + "\"";
|
||||
|
||||
ua->fetch(url, method, (["Authorization": "OAuth " + implode(params, ",")]));
|
||||
ua->fetch(url, method, post, (["Authorization": "OAuth " + p]));
|
||||
}
|
||||
|
||||
void parse_request_token(string body, mapping headers) {
|
||||
P3((">> oauth:parse_request_token(%O, %O)\n", body, headers))
|
||||
mapping params = ([]);
|
||||
parse_query(params, body);
|
||||
request_token = params["oauth_token"];
|
||||
request_secret = params["oauth_token_secret"];
|
||||
if (strlen(request_token) && strlen(request_secret)) {
|
||||
shared_memory("oauth_request_tokens")[request_token] = ME;
|
||||
request_params = ([]);
|
||||
parse_query(request_params, body);
|
||||
if (strlen(request_params["oauth_token"]) && strlen(request_params["oauth_token_secret"])) {
|
||||
shared_memory("oauth_request_tokens")[request_params["oauth_token"]] = ME;
|
||||
sendmsg(user, "_notice_oauth_authorize_url", "Open [_url] to perform authorization.",
|
||||
(["_url": authorize_url + "?oauth_token=" + request_token]));
|
||||
(["_url": authorize_url + "?oauth_token=" + request_params["oauth_token"]]));
|
||||
} else {
|
||||
sendmsg(user, "_error_oauth_token_request", "OAuth failed: could not get a request token.");
|
||||
}
|
||||
|
@ -66,11 +63,9 @@ void parse_request_token(string body, mapping headers) {
|
|||
|
||||
void parse_access_token(string body, mapping headers) {
|
||||
P3((">> oauth:parse_access_token(%O, %O)\n", body, headers))
|
||||
mapping params = ([]);
|
||||
parse_query(params, body);
|
||||
access_token = params["oauth_token"];
|
||||
access_secret = params["oauth_token_secret"];
|
||||
if (strlen(access_token) && strlen(access_secret)) {
|
||||
access_params = ([]);
|
||||
parse_query(access_params, body);
|
||||
if (strlen(access_params["oauth_token"]) && strlen(access_params["oauth_token_secret"])) {
|
||||
sendmsg(user, "_notice_oauth_success", "OAuth successful.");
|
||||
} else {
|
||||
sendmsg(user, "_error_oauth_token_access", "OAuth failed: could not get an access token.");
|
||||
|
@ -81,7 +76,7 @@ void verified(string verifier) {
|
|||
P3((">> oauth:verified(%O)\n", verifier))
|
||||
object ua = clone_object(NET_PATH "http/fetch");
|
||||
ua->content(#'parse_access_token, 1, 1); //');
|
||||
fetch(ua, access_token_url, "POST", (["verifier": verifier]));
|
||||
fetch(ua, access_token_url, "POST", 0, 0, (["oauth_verifier": verifier]));
|
||||
}
|
||||
|
||||
object load(object usr, string key, string secret, string request, string access, string authorize) {
|
||||
|
@ -95,7 +90,7 @@ object load(object usr, string key, string secret, string request, string access
|
|||
if (request_token_url && user) {
|
||||
object ua = clone_object(NET_PATH "http/fetch");
|
||||
ua->content(#'parse_request_token, 1, 1); //');
|
||||
fetch(ua, request_token_url, "POST", (["callback": callback_url]));
|
||||
fetch(ua, request_token_url, "POST", 0, 0, (["oauth_callback": callback_url]));
|
||||
}
|
||||
return ME;
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ case "/oauth":
|
|||
//PT((">>> oauth: %O\n", oauth))
|
||||
oauth->verified(query["oauth_verifier"]);
|
||||
m_delete(shared_memory("oauth_request_tokens"), query["oauth_token"]);
|
||||
write("OAuth succeeded");
|
||||
write("OAuth succeeded, you can now return to your client.");
|
||||
} else {
|
||||
write("OAuth failed: token not found");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue