Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dialyzer tweaks for the new usage of the AppCtx #32

Merged
merged 1 commit into from Jan 8, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -27,7 +27,7 @@ ct: clean deps test-build

build-plt:
$(DIALYZER) --build_plt --output_plt .$(PROJECT).plt \
--apps kernel stdlib sasl inets crypto public_key ssl
--apps erts kernel stdlib sasl inets crypto public_key ssl

dialyze: clean deps test-build
$(DIALYZER) --plt .$(PROJECT).plt ebin
39 changes: 22 additions & 17 deletions src/oauth2.erl
Expand Up @@ -39,6 +39,7 @@
-export_type([context/0]).
-export_type([lifetime/0]).
-export_type([scope/0]).
-export_type([appctx/0]).
-export_type([error/0]).

%%%_* Macros ===========================================================
Expand All @@ -59,6 +60,7 @@
-type response() :: oauth2_response:response().
-type lifetime() :: non_neg_integer().
-type scope() :: list(binary()) | binary().
-type appctx() :: term().
-type error() :: access_denied | invalid_client | invalid_grant |
invalid_request | invalid_scope | unauthorized_client |
unsupported_response_type | server_error |
Expand All @@ -68,8 +70,8 @@
%%%_ * API -------------------------------------------------------------
%% @doc Authorizes a resource owner's credentials. Useful for
%% Resource Owner Password Credentials Grant and Implicit Grant.
-spec authorize_password(binary(), binary(), scope(), term())
-> {ok, auth()} | {error, error()}.
-spec authorize_password(binary(), binary(), scope(), appctx())
-> {ok, {appctx(), auth()}} | {error, error()}.
authorize_password(UId, Pwd, Scope, AppCtx1) ->
case ?BACKEND:authenticate_username_password(UId, Pwd, AppCtx1) of
{error, _} -> {error, access_denied};
Expand All @@ -90,8 +92,8 @@ authorize_password(UId, Pwd, Scope, AppCtx1) ->
%% of a public client identifier and a shared client secret.
%% Should only be used for confidential clients; see the OAuth2 draft
%% for clarification.
-spec authorize_client_credentials(binary(), binary(), scope(), term())
-> {ok, auth()} | {error, error()}.
-spec authorize_client_credentials(binary(), binary(), scope(), appctx())
-> {ok, {appctx(), auth()}} | {error, error()}.
authorize_client_credentials(CId, CSecret, Scope, AppCtx1) ->
case ?BACKEND:authenticate_client(CId, CSecret, AppCtx1) of
{error, _} -> {error, invalid_client};
Expand All @@ -115,8 +117,8 @@ authorize_client_credentials(CId, CSecret, Scope, AppCtx1) ->
%%
%% Then verify the supplied RedirectionUri and Code and if valid issue
%% an Access Token and an optional Refresh Token
-spec authorize_code_grant(binary(), binary(), token(), binary(), term())
-> {ok, auth()} | {error, error()}.
-spec authorize_code_grant(binary(), binary(), token(), binary(), appctx())
-> {ok, {appctx(), auth()}} | {error, error()}.
authorize_code_grant(CId, CSecret, Code, RedirUri, AppCtx1) ->
case ?BACKEND:authenticate_client(CId, CSecret, AppCtx1) of
{error, _} -> {error, invalid_client};
Expand Down Expand Up @@ -149,7 +151,8 @@ authorize_code_grant(CId, CSecret, Code, RedirUri, AppCtx1) ->
, binary()
, binary()
, scope()
, term()) -> {ok, auth()} | {error, error()}.
, appctx())
-> {ok, {appctx(), auth()}} | {error, error()}.
authorize_code_request(CId, RedirUri, UId, Pwd, Scope, AppCtx1) ->
case ?BACKEND:get_client_identity(CId, AppCtx1) of
{error, _} -> {error, unauthorized_client};
Expand Down Expand Up @@ -178,7 +181,7 @@ authorize_code_request(CId, RedirUri, UId, Pwd, Scope, AppCtx1) ->
end
end.

-spec issue_code(auth(), term()) -> response().
-spec issue_code(auth(), appctx()) -> {ok, {appctx(), response()}}.
issue_code(#authorization{client = Client, resowner = ResOwner,
scope = Scope, ttl = TTL}, AppCtx1) ->
ExpiryAbsolute = seconds_since_epoch(TTL),
Expand All @@ -194,7 +197,7 @@ issue_code(#authorization{client = Client, resowner = ResOwner,
, <<>>
, AccessCode )}}.

-spec issue_token(auth(), term()) -> response().
-spec issue_token(auth(), appctx()) -> {ok, {appctx(), response()}}.
issue_token(#authorization{client = Client, resowner = ResOwner,
scope = Scope, ttl = TTL}, AppCtx1) ->
ExpiryAbsolute = seconds_since_epoch(TTL),
Expand All @@ -208,7 +211,8 @@ issue_token(#authorization{client = Client, resowner = ResOwner,
%% @doc Issue an Access Token and a Refresh Token.
%% The OAuth2 specification forbids or discourages issuing a refresh token
%% when no resource owner is authenticated (See 4.2.2 and 4.4.3)
-spec issue_token_and_refresh(auth(), term()) -> response().
-spec issue_token_and_refresh(auth(), appctx())
-> {ok, {appctx(), response()}}.
issue_token_and_refresh(#authorization{client = Client, resowner = ResOwner,
scope = Scope, ttl = TTL}, AppCtx1)
when ResOwner /= undefined ->
Expand All @@ -227,7 +231,8 @@ issue_token_and_refresh(#authorization{client = Client, resowner = ResOwner,

%% @doc Verifies an access code AccessCode, returning its associated
%% context if successful. Otherwise, an OAuth2 error code is returned.
-spec verify_access_code(token(), term()) -> {ok, context()} | {error, error()}.
-spec verify_access_code(token(), appctx())
-> {ok, {appctx(), context()}} | {error, error()}.
verify_access_code(AccessCode, AppCtx1) ->
case ?BACKEND:resolve_access_code(AccessCode, AppCtx1) of
{ok, {AppCtx2, GrantCtx}} ->
Expand All @@ -243,8 +248,8 @@ verify_access_code(AccessCode, AppCtx1) ->
%% @doc Verifies an access code AccessCode and it's corresponding Identity,
%% returning its associated context if successful. Otherwise, an OAuth2
%% error code is returned.
-spec verify_access_code(token(), term(), term())
-> {ok, context()} | {error, error()}.
-spec verify_access_code(token(), term(), appctx())
-> {ok, {appctx(), context()}} | {error, error()}.
verify_access_code(AccessCode, Client, AppCtx1) ->
case verify_access_code(AccessCode, AppCtx1) of
{ok, {AppCtx2, GrantCtx}} ->
Expand All @@ -257,8 +262,8 @@ verify_access_code(AccessCode, Client, AppCtx1) ->

%% @doc Verifies an refresh token RefreshToken, returning a new Access Token
%% if successful. Otherwise, an OAuth2 error code is returned.
-spec refresh_access_token(binary(), binary(), token(), scope(), term())
-> {ok, {term(), response()}} | {error, error()}.
-spec refresh_access_token(binary(), binary(), token(), scope(), appctx())
-> {ok, {appctx(), response()}} | {error, error()}.
refresh_access_token(CId, CSecret, RefreshToken, Scope, AppCtx1) ->
case ?BACKEND:authenticate_client(CId, CSecret, AppCtx1) of
{ok, {AppCtx2, Client}} ->
Expand Down Expand Up @@ -298,8 +303,8 @@ refresh_access_token(CId, CSecret, RefreshToken, Scope, AppCtx1) ->

%% @doc Verifies an access token AccessToken, returning its associated
%% context if successful. Otherwise, an OAuth2 error code is returned.
-spec verify_access_token(token(), term())
-> {ok, context()} | {error, error()}.
-spec verify_access_token(token(), appctx())
-> {ok, {appctx(), context()}} | {error, error()}.
verify_access_token(AccessToken, AppCtx1) ->
case ?BACKEND:resolve_access_token(AccessToken, AppCtx1) of
{ok, {AppCtx2, GrantCtx}} ->
Expand Down
43 changes: 21 additions & 22 deletions src/oauth2_backend.erl
Expand Up @@ -22,93 +22,92 @@

%%%_ * Types -----------------------------------------------------------
-type grantctx() :: oauth2:context().
-type appctx() :: term().
-type token() :: binary().
-type scope() :: list(binary()) | binary().
-type appctx() :: oauth2:appctx().
-type token() :: oauth2:token().
-type scope() :: oauth2:scope().

%%%_* Behaviour ========================================================
%% @doc Authenticates a combination of username and password.
%% Returns the resource owner identity if the credentials are valid.
-callback authenticate_username_password(binary(), binary(), appctx()) ->
{ok, term()} | {error, notfound | badpass}.
{ok, {appctx(), term()}} | {error, notfound | badpass}.

%% @doc Authenticates a client's credentials for a given scope.
-callback authenticate_client(binary(), binary(), appctx()) ->
{ok, term()} | {error, notfound | badsecret}.
{ok, {appctx(), term()}} | {error, notfound | badsecret}.

%% @doc Stores a new access code token(), associating it with Context.
%% The context is a proplist carrying information about the identity
%% with which the code is associated, when it expires, etc.
-callback associate_access_code(token(), grantctx(), appctx()) ->
ok | {error, notfound}.
{ok, appctx()} | {error, notfound}.

%% @doc Stores a new access token token(), associating it with Context.
%% The context is a proplist carrying information about the identity
%% with which the token is associated, when it expires, etc.
-callback associate_access_token(token(), grantctx(), appctx()) ->
ok | {error, notfound}.
{ok, appctx()} | {error, notfound}.

%% @doc Stores a new refresh token token(), associating it with
%% grantctx(). The context is a proplist carrying information about the
%% identity with which the token is associated, when it expires, etc.
-callback associate_refresh_token(token(), grantctx(), appctx()) ->
ok | {error, notfound}.
{ok, appctx()} | {error, notfound}.

%% @doc Looks up an access token token(), returning the corresponding
%% context if a match is found.
-callback resolve_access_token(token(), appctx()) ->
{ok, grantctx()} | {error, notfound}.
{ok, {appctx(), grantctx()}} | {error, notfound}.

%% @doc Looks up an access code token(), returning the corresponding
%% context if a match is found.
-callback resolve_access_code(token(), appctx()) ->
{ok, grantctx()} | {error, notfound}.
{ok, {appctx(), grantctx()}} | {error, notfound}.

%% @doc Looks up an refresh token token(), returning the corresponding
%% context if a match is found.
-callback resolve_refresh_token(token(), appctx()) ->
{ok, grantctx()} | {error, notfound}.
{ok, {appctx(), grantctx()}} | {error, notfound}.

%% @doc Revokes an access token token(), so that it cannot be used again.
-callback revoke_access_token(token(), appctx()) ->
ok | {error, notfound}.
{ok, appctx()} | {error, notfound}.

%% @doc Revokes an access code token(), so that it cannot be used again.
-callback revoke_access_code(token(), appctx()) ->
ok | {error, notfound}.
{ok, appctx()} | {error, notfound}.

%% @doc Revokes an refresh token token(), so that it cannot be used again.
-callback revoke_refresh_token(token(), appctx()) ->
ok | {error, notfound}.
{ok, appctx()} | {error, notfound}.

%% @doc Returns the redirection URI associated with the client ClientId.
-callback get_redirection_uri(binary(), appctx()) ->
{error, notfound} | {ok, binary()}.
{error, notfound} | {ok, {appctx(), binary()}}.

%% @doc Returns a client identity for a given id.
-callback get_client_identity(binary(), appctx()) ->
{ok, term()} | {error, notfound | badsecret}.
{ok, {appctx(), term()}} | {error, notfound | badsecret}.

%% @doc Verifies that RedirectionUri is a valid redirection URI for the
%% client identified by Identity.
-callback verify_redirection_uri(term(), binary(), appctx()) ->
ok | {error, notfound | baduri}.
{ok, appctx()} | {error, notfound | baduri}.

%% @doc Verifies that scope() is a valid scope for the client identified
%% by Identity.
-callback verify_client_scope(term(), scope(), appctx()) ->
{ok, scope()} | {error, notfound | badscope}.
{ok, {appctx(), scope()}} | {error, notfound | badscope}.

%% @doc Verifies that scope() is a valid scope for the resource
%% owner identified by Identity.
-callback verify_resowner_scope(term(), scope(), appctx()) ->
{ok, scope()} | {error, notfound | badscope}.
{ok, {appctx(), scope()}} | {error, notfound | badscope}.

%% @doc Verifies that scope() is a valid scope of the set of scopes defined
%% by Validscope()s.
%% @end
%% by Validscope()s.
-callback verify_scope(scope(), scope(), appctx()) ->
{ok, scope()} | {error, notfound | badscope}.
{ok, {appctx(), scope()}} | {error, notfound | badscope}.

%%%_* Tests ============================================================
-ifdef(TEST).
Expand Down