Skip to content

Commit

Permalink
Claimed IDs and OP-Local IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
brendonh committed Sep 18, 2009
1 parent aa215f9 commit bcc8fa6
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 33 deletions.
64 changes: 37 additions & 27 deletions src/openid.erl
Original file line number Diff line number Diff line change
Expand Up @@ -19,44 +19,53 @@
discover(Identifier) ->
case yadis:retrieve(Identifier) of
{none, Body} -> html_discovery(Body);
XRDS -> extract_identifier(XRDS)
XRDS -> extract_authreq(XRDS)
end.


extract_identifier(XRDS) ->
case extract_op_id(XRDS) of
none -> extract_claimed_id(XRDS);
OpID -> OpID
extract_authreq(XRDS) ->
case authreq_by_opid(XRDS) of
none -> authreq_by_claimed_id(XRDS);
Req -> Req
end.

extract_op_id(XRDS) ->
case find_service_type(XRDS#xrds.services, "http://specs.openid.net/auth/2.0/server") of
authreq_by_opid(XRDS) ->
case find_service(XRDS#xrds.services, "http://specs.openid.net/auth/2.0/server") of
none -> none;
URL -> #authReq{opURL=URL, version={2,0}}
end.

extract_claimed_id(XRDS) ->
extract_claimed_id(XRDS, [{"http://specs.openid.net/auth/2.0/signon", {2,0}},
{"http://openid.net/signon/1.1", {1,1}},
{"http://openid.net/signon/1.0", {1,0}}]).

extract_claimed_id(_, []) ->
none;
extract_claimed_id(XRDS, [{Type,Version}|Rest]) ->
case find_service_type(XRDS#xrds.services, Type) of
none -> extract_claimed_id(XRDS, Rest);
URL -> #authReq{opURL=URL, version=Version}
Service -> build_authReq(XRDS, Service, {2,0})
end.


find_service_type([], _) -> none;
find_service_type([{Types, []}|Rest], Type) -> find_service_type(Rest, Type);
find_service_type([{Types, [URL|_]}|Rest], Type) ->
find_service([], _) -> none;
find_service([#xrdService{uris=[]}|Rest], Type) -> find_service(Rest, Type);
find_service([#xrdService{types=Types}=Service|Rest], Type) ->
case lists:any(fun(X) -> X == Type end, Types) of
true -> URL;
false -> find_service_type(Rest, Type)
true -> Service;
false -> find_service(Rest, Type)
end.


authreq_by_claimed_id(XRDS) ->
authreq_by_claimed_id(XRDS, [{"http://specs.openid.net/auth/2.0/signon", {2,0}},
{"http://openid.net/signon/1.1", {1,1}},
{"http://openid.net/signon/1.0", {1,0}}]).

authreq_by_claimed_id(_, []) ->
none;
authreq_by_claimed_id(XRDS, [{Type,Version}|Rest]) ->
case find_service(XRDS#xrds.services, Type) of
none -> authreq_by_claimed_id(XRDS, Rest);
Service -> build_authReq(XRDS, Service, Version)
end.


build_authReq(XRDS, Service, Version) ->
[URL|_] = Service#xrdService.uris,
#authReq{opURL=URL, version={2,0},
claimedID=XRDS#xrds.claimedID,
localID=Service#xrdService.localID}.


html_discovery(Body) ->
html_discovery(Body, [{"openid2.provider", "openid2.local_id", {2,0}},
{"openid.server", "openid.delegate", {1,1}}]).
Expand Down Expand Up @@ -88,11 +97,12 @@ html_local_id(Body, RelName) ->

test() ->

?DBG({"Someone:", discover("blog.paulbonser.com")}),
?DBG({"Google:", discover("https://www.google.com/accounts/o8/id")}),
?DBG({"AOL:", discover("http://openid.aol.com/brend")}),
?DBG({"Flickr:", discover("http://flickr.com/exbrend")}),
?DBG({"Myspace:", discover("www.myspace.com")}),
?DBG({"LiveJournal:", discover("http://exbrend.livejournal.com")}),
?DBG({"XRI Brend:", discover("=brendonh")}),
?DBG({"XRI Brend:", discover("=brendonh")}),

application:stop(inets). % Avoid error spam from held-open connections
10 changes: 8 additions & 2 deletions src/openid.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
%%% Created : 18 Sep 2009 by Brendon Hogger <[email protected]>
%%%-------------------------------------------------------------------

-record(xrdService, {
types,
uris,
localID
}).

-record(xrds, {
origID,
claimedID,
Expand All @@ -17,6 +23,6 @@
-record(authReq, {
opURL,
version,
claimedID,
localID
claimedID=none,
localID=none
}).
21 changes: 17 additions & 4 deletions src/yadis.erl
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,20 @@ get_descriptor_url(Body) ->
munge_xrds(String) ->
{Doc, _} = xmerl_scan:string(String),
CanonicalID = get_canonical_id(Doc),
Services = [{Ts, Us} || {_P, Ts, Us} <- lists:sort(
fun({P1,_,_},{P2,_,_}) -> P1 < P2 end,
Services = [S || {_P, S} <- lists:sort(
fun({P1,_},{P2,_}) -> P1 < P2 end,
[munge_service(S) || S <- xmerl_xpath:string("XRD/Service", Doc)])],
#xrds{canonicalID=CanonicalID, services=Services}.

munge_service(Service) ->
Priority = get_priority(Service#xmlElement.attributes),
Types = [get_text(T) || T <- xmerl_xpath:string("Type", Service)],
LocalID = get_local_id(Service),
URIs = [U || {_P, U} <- lists:sort(
fun({P1,_},{P2,_}) -> P1 < P2 end,
[{get_priority(U#xmlElement.attributes), get_text(U)}
|| U <- xmerl_xpath:string("URI", Service)])],
{Priority, Types, URIs}.
{Priority, #xrdService{types=Types, uris=URIs, localID=LocalID}}.

get_text(#xmlElement{content=[]}) -> "";
get_text(#xmlElement{content=[Value|_]}) -> Value#xmlText.value.
Expand All @@ -163,7 +164,19 @@ get_canonical_id(Doc) ->
[] -> none;
[#xmlElement{content=[Value|_]}|_] -> Value#xmlText.value
end.



get_local_id(Service) ->
get_local_id(Service, ["LocalID", "Delegate"]).

get_local_id(_, []) ->
none;
get_local_id(Service, [Tag|Rest]) ->
case xmerl_xpath:string(Tag, Service) of
[] -> get_local_id(Service, Rest);
[#xmlElement{content=[Value|_]}|_] -> Value#xmlText.value
end.


%% ------------------------------------------------------------
%% Tests
Expand Down

0 comments on commit bcc8fa6

Please sign in to comment.