# HG changeset patch # User Adam Chlipala # Date 1295822442 18000 # Node ID f129ddee75f30b9b29893a3b936dc395a48d1736 # Parent ee97bc0e08facc40f372c0d744ef7c994bfe2dd9 Some XRDS fixes; ignore query strings in naming endpoints for association purposes diff -r ee97bc0e08fa -r f129ddee75f3 include/openid.h --- 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); diff -r ee97bc0e08fa -r f129ddee75f3 src/c/openid.c --- 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; diff -r ee97bc0e08fa -r f129ddee75f3 src/ur/lib.urp --- 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 diff -r ee97bc0e08fa -r f129ddee75f3 src/ur/openid.ur --- 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 () => diff -r ee97bc0e08fa -r f129ddee75f3 src/ur/openidFfi.urs --- 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 diff -r ee97bc0e08fa -r f129ddee75f3 src/ur/openidUser.ur --- 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
- +
end in @@ -273,10 +273,10 @@

This web site uses the OpenID standard, which lets you log in using your account from one of several popular web sites, without revealing your password to us.

You may click one of these buttons to choose to use your account from that site:

- {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/"}

Visitors familiar with the details of OpenID may also enter their own identifiers: