Mercurial > openid
changeset 27:f129ddee75f3
Some XRDS fixes; ignore query strings in naming endpoints for association purposes
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sun, 23 Jan 2011 17:40:42 -0500 |
parents | ee97bc0e08fa |
children | fcd3a977d77b |
files | include/openid.h src/c/openid.c src/ur/lib.urp src/ur/openid.ur src/ur/openidFfi.urs src/ur/openidUser.ur |
diffstat | 6 files changed, 70 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/include/openid.h Sun Jan 23 14:57:49 2011 -0500 +++ b/include/openid.h Sun Jan 23 17:40:42 2011 -0500 @@ -20,6 +20,7 @@ uw_unit uw_OpenidFfi_addInput(uw_context, uw_OpenidFfi_inputs, uw_Basis_string key, uw_Basis_string value); uw_Basis_string uw_OpenidFfi_getOutput(uw_context, uw_OpenidFfi_outputs, uw_Basis_string key); +uw_unit uw_OpenidFfi_printOutputs(uw_context, uw_OpenidFfi_outputs); uw_OpenidFfi_outputs uw_OpenidFfi_direct(uw_context, uw_Basis_string url, uw_OpenidFfi_inputs); uw_OpenidFfi_outputs uw_OpenidFfi_indirect(uw_context, uw_Basis_string fields);
--- a/src/c/openid.c Sun Jan 23 14:57:49 2011 -0500 +++ b/src/c/openid.c Sun Jan 23 17:40:42 2011 -0500 @@ -77,6 +77,7 @@ uw_context ctx; uw_OpenidFfi_discovery *d; xrds_mode mode; + int cur_priority, max_priority; } endpoint; static void XMLCALL startElement(void *userData, const XML_Char *name, const XML_Char **atts) { @@ -105,9 +106,18 @@ } } } - else if (!strcmp(name, "Service")) + else if (!strcmp(name, "Service")) { + const XML_Char **attp; + + ep->cur_priority = 0; + for (attp = atts; *attp; attp += 2) + if (!strcmp(attp[0], "priority")) { + ep->cur_priority = atoi(attp[1]); + break; + } + ep->mode = SERVICE; - else if (!strcmp(name, "Type")) { + } else if (!strcmp(name, "Type")) { if (ep->mode == SERVICE) ep->mode = TYPE; } @@ -130,9 +140,12 @@ ep->mode = MATCHED; break; case URI: - ep->d->endpoint = uw_malloc(ep->ctx, len+1); - memcpy(ep->d->endpoint, s, len); - ep->d->endpoint[len] = 0; + if (ep->cur_priority < ep->max_priority) { + ep->d->endpoint = uw_malloc(ep->ctx, len+1); + memcpy(ep->d->endpoint, s, len); + ep->d->endpoint[len] = 0; + ep->max_priority = ep->cur_priority; + } break; default: break; @@ -174,8 +187,9 @@ CURL *c = curl(ctx); curl_discovery_data cd = {}; uw_OpenidFfi_discovery *dy = uw_malloc(ctx, sizeof(uw_OpenidFfi_discovery)); - endpoint ep = {ctx, dy, NONE}; + endpoint ep = {ctx, dy, NONE, 0, INT_MAX}; CURLcode code; + struct curl_slist *headers = NULL; dy->endpoint = dy->localId = NULL; @@ -200,9 +214,13 @@ curl_easy_setopt(c, CURLOPT_URL, id); curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_discovery_data); curl_easy_setopt(c, CURLOPT_WRITEDATA, &cd); + curl_slist_append(headers, "Accept: application/xrds+xml"); + uw_push_cleanup(ctx, (void (*)(void *))curl_slist_free_all, headers); + curl_easy_setopt(c, CURLOPT_HTTPHEADER, headers); code = curl_easy_perform(c); uw_pop_cleanup(ctx); + uw_pop_cleanup(ctx); if (code || !dy->endpoint) return NULL; @@ -250,6 +268,15 @@ return NULL; } +uw_unit uw_OpenidFfi_printOutputs(uw_context ctx, uw_OpenidFfi_outputs buf) { + char *s = buf->start; + + for (; *s; s = strchr(strchr(s, 0)+1, 0)+1) + fprintf(stderr, "%s => %s\n", s, strchr(s, 0)+1); + + return uw_unit_v; +} + static size_t write_buffer_data(void *buffer, size_t size, size_t nmemb, void *userp) { uw_buffer *buf = userp;
--- a/src/ur/lib.urp Sun Jan 23 14:57:49 2011 -0500 +++ b/src/ur/lib.urp Sun Jan 23 17:40:42 2011 -0500 @@ -5,6 +5,7 @@ effectful OpenidFfi.discover effectful OpenidFfi.createInputs effectful OpenidFfi.addInput +effectful OpenidFfi.printOutputs effectful OpenidFfi.direct effectful OpenidFfi.indirect effectful OpenidFfi.generate
--- a/src/ur/openid.ur Sun Jan 23 14:57:49 2011 -0500 +++ b/src/ur/openid.ur Sun Jan 23 17:40:42 2011 -0500 @@ -106,7 +106,13 @@ | _ => Some (AssError ("OP error during association: " ^ v))) | None => None +fun eatQstring s = + case String.split s #"?" of + Some (s', _) => s' + | _ => s + fun associateNoEncryption url atype = + url <- return (eatQstring url); is <- createInputs; OpenidFfi.addInput is "openid.mode" "associate"; OpenidFfi.addInput is "openid.assoc_type" (show atype); @@ -130,6 +136,7 @@ | _ => return (AssError "Missing expires_in") fun associateDh url atype stype = + url <- return (eatQstring url); dh <- OpenidFfi.generate; is <- createInputs; @@ -166,6 +173,7 @@ | _ => return (AssError "Missing expires_in") fun oldAssociation url = + url <- return (eatQstring url); secret <- oneOrNoRows1 (SELECT associations.Handle, associations.Typ, associations.Key FROM associations WHERE associations.Endpoint = {[url]}); @@ -381,22 +389,28 @@ case dy of None => return "Discovery failed" | Some dy => - case r.Association of - Stateless => - redirect (bless (dy ^ "?openid.ns=http://specs.openid.net/auth/2.0&openid.mode=checkid_setup" - ^ "&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select" - ^ "&openid.identity=http://specs.openid.net/auth/2.0/identifier_select&openid.assoc_handle=" - ^ "&openid.return_to=" ^ show (effectfulUrl returnTo) ^ realmString)) - | Stateful ar => - assoc <- association ar.AssociationType ar.AssociationSessionType dy; - case assoc of - AssError msg => return ("Association failure: " ^ msg) - | AssAlternate _ => return "Association failure: server didn't accept its own alternate association modes" - | Association assoc => - redirect (bless (dy ^ "?openid.ns=http://specs.openid.net/auth/2.0&openid.mode=checkid_setup" + let + val begin = case String.index dy #"?" of + None => "?" + | Some _ => "&" + in + case r.Association of + Stateless => + redirect (bless (dy ^ begin ^ "openid.ns=http://specs.openid.net/auth/2.0&openid.mode=checkid_setup" ^ "&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select" ^ "&openid.identity=http://specs.openid.net/auth/2.0/identifier_select&openid.assoc_handle=" - ^ assoc.Handle ^ "&openid.return_to=" ^ show (effectfulUrl returnTo) ^ realmString)) + ^ "&openid.return_to=" ^ show (effectfulUrl returnTo) ^ realmString)) + | Stateful ar => + assoc <- association ar.AssociationType ar.AssociationSessionType dy; + case assoc of + AssError msg => return ("Association failure: " ^ msg) + | AssAlternate _ => return "Association failure: server didn't accept its own alternate association modes" + | Association assoc => + redirect (bless (dy ^ begin ^ "openid.ns=http://specs.openid.net/auth/2.0&openid.mode=checkid_setup" + ^ "&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select" + ^ "&openid.identity=http://specs.openid.net/auth/2.0/identifier_select&openid.assoc_handle=" + ^ assoc.Handle ^ "&openid.return_to=" ^ show (effectfulUrl returnTo) ^ realmString)) + end end task periodic 60 = fn () =>
--- a/src/ur/openidFfi.urs Sun Jan 23 14:57:49 2011 -0500 +++ b/src/ur/openidFfi.urs Sun Jan 23 17:40:42 2011 -0500 @@ -11,6 +11,7 @@ type outputs val getOutput : outputs -> string -> option string +val printOutputs : outputs -> transaction {} val direct : string -> inputs -> transaction outputs val indirect : queryString -> transaction outputs
--- a/src/ur/openidUser.ur Sun Jan 23 14:57:49 2011 -0500 +++ b/src/ur/openidUser.ur Sun Jan 23 17:40:42 2011 -0500 @@ -259,13 +259,13 @@ fun signup after = let - fun fixed cls label url = + fun fixed cls url = let fun doFixedButton () = doSignup after {Identifier = url} in <xml><form class={provider}> - <submit class={cls} value={label} action={doFixedButton}/> + <submit class={cls} value="" action={doFixedButton}/> </form></xml> end in @@ -273,10 +273,10 @@ <p>This web site uses the <b><a href="http://openid.net/">OpenID</a></b> standard, which lets you log in using your account from one of several popular web sites, without revealing your password to us.</p> <p>You may click one of these buttons to choose to use your account from that site:</p> - {fixed aol "AOL" "https://openid.aol.com/"} - {fixed google "Google" "https://www.google.com/accounts/o8/id"} - {fixed myspace "Myspace" "https://www.myspace.com/openid"} - {fixed yahoo "Yahoo!" "https://me.yahoo.com/"} + {fixed aol "https://openid.aol.com/"} + {fixed google "https://www.google.com/accounts/o8/id"} + {fixed myspace "https://www.myspace.com/openid"} + {fixed yahoo "https://me.yahoo.com/"} <p>Visitors familiar with the details of OpenID may also enter their own identifiers:</p> <form>