Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge pull request #32 from synlay/feature/appctx_dialyzer_tweaks

Dialyzer tweaks for the new usage of the AppCtx
  • Loading branch information...
commit 7052b70224e06bd4a2fd1665de7bdf69c8e4f422 2 parents e8f7c5b + 8987f1e
Bip Thelin bipthelin authored

Showing 3 changed files with 44 additions and 40 deletions. Show diff stats Hide diff stats

  1. +1 1  Makefile
  2. +22 17 src/oauth2.erl
  3. +21 22 src/oauth2_backend.erl
2  Makefile
@@ -27,7 +27,7 @@ ct: clean deps test-build
27 27
28 28 build-plt:
29 29 $(DIALYZER) --build_plt --output_plt .$(PROJECT).plt \
30   - --apps kernel stdlib sasl inets crypto public_key ssl
  30 + --apps erts kernel stdlib sasl inets crypto public_key ssl
31 31
32 32 dialyze: clean deps test-build
33 33 $(DIALYZER) --plt .$(PROJECT).plt ebin
39 src/oauth2.erl
@@ -39,6 +39,7 @@
39 39 -export_type([context/0]).
40 40 -export_type([lifetime/0]).
41 41 -export_type([scope/0]).
  42 +-export_type([appctx/0]).
42 43 -export_type([error/0]).
43 44
44 45 %%%_* Macros ===========================================================
@@ -59,6 +60,7 @@
59 60 -type response() :: oauth2_response:response().
60 61 -type lifetime() :: non_neg_integer().
61 62 -type scope() :: list(binary()) | binary().
  63 +-type appctx() :: term().
62 64 -type error() :: access_denied | invalid_client | invalid_grant |
63 65 invalid_request | invalid_scope | unauthorized_client |
64 66 unsupported_response_type | server_error |
@@ -68,8 +70,8 @@
68 70 %%%_ * API -------------------------------------------------------------
69 71 %% @doc Authorizes a resource owner's credentials. Useful for
70 72 %% Resource Owner Password Credentials Grant and Implicit Grant.
71   --spec authorize_password(binary(), binary(), scope(), term())
72   - -> {ok, auth()} | {error, error()}.
  73 +-spec authorize_password(binary(), binary(), scope(), appctx())
  74 + -> {ok, {appctx(), auth()}} | {error, error()}.
73 75 authorize_password(UId, Pwd, Scope, AppCtx1) ->
74 76 case ?BACKEND:authenticate_username_password(UId, Pwd, AppCtx1) of
75 77 {error, _} -> {error, access_denied};
@@ -90,8 +92,8 @@ authorize_password(UId, Pwd, Scope, AppCtx1) ->
90 92 %% of a public client identifier and a shared client secret.
91 93 %% Should only be used for confidential clients; see the OAuth2 draft
92 94 %% for clarification.
93   --spec authorize_client_credentials(binary(), binary(), scope(), term())
94   - -> {ok, auth()} | {error, error()}.
  95 +-spec authorize_client_credentials(binary(), binary(), scope(), appctx())
  96 + -> {ok, {appctx(), auth()}} | {error, error()}.
95 97 authorize_client_credentials(CId, CSecret, Scope, AppCtx1) ->
96 98 case ?BACKEND:authenticate_client(CId, CSecret, AppCtx1) of
97 99 {error, _} -> {error, invalid_client};
@@ -115,8 +117,8 @@ authorize_client_credentials(CId, CSecret, Scope, AppCtx1) ->
115 117 %%
116 118 %% Then verify the supplied RedirectionUri and Code and if valid issue
117 119 %% an Access Token and an optional Refresh Token
118   --spec authorize_code_grant(binary(), binary(), token(), binary(), term())
119   - -> {ok, auth()} | {error, error()}.
  120 +-spec authorize_code_grant(binary(), binary(), token(), binary(), appctx())
  121 + -> {ok, {appctx(), auth()}} | {error, error()}.
120 122 authorize_code_grant(CId, CSecret, Code, RedirUri, AppCtx1) ->
121 123 case ?BACKEND:authenticate_client(CId, CSecret, AppCtx1) of
122 124 {error, _} -> {error, invalid_client};
@@ -149,7 +151,8 @@ authorize_code_grant(CId, CSecret, Code, RedirUri, AppCtx1) ->
149 151 , binary()
150 152 , binary()
151 153 , scope()
152   - , term()) -> {ok, auth()} | {error, error()}.
  154 + , appctx())
  155 + -> {ok, {appctx(), auth()}} | {error, error()}.
153 156 authorize_code_request(CId, RedirUri, UId, Pwd, Scope, AppCtx1) ->
154 157 case ?BACKEND:get_client_identity(CId, AppCtx1) of
155 158 {error, _} -> {error, unauthorized_client};
@@ -178,7 +181,7 @@ authorize_code_request(CId, RedirUri, UId, Pwd, Scope, AppCtx1) ->
178 181 end
179 182 end.
180 183
181   --spec issue_code(auth(), term()) -> response().
  184 +-spec issue_code(auth(), appctx()) -> {ok, {appctx(), response()}}.
182 185 issue_code(#authorization{client = Client, resowner = ResOwner,
183 186 scope = Scope, ttl = TTL}, AppCtx1) ->
184 187 ExpiryAbsolute = seconds_since_epoch(TTL),
@@ -194,7 +197,7 @@ issue_code(#authorization{client = Client, resowner = ResOwner,
194 197 , <<>>
195 198 , AccessCode )}}.
196 199
197   --spec issue_token(auth(), term()) -> response().
  200 +-spec issue_token(auth(), appctx()) -> {ok, {appctx(), response()}}.
198 201 issue_token(#authorization{client = Client, resowner = ResOwner,
199 202 scope = Scope, ttl = TTL}, AppCtx1) ->
200 203 ExpiryAbsolute = seconds_since_epoch(TTL),
@@ -208,7 +211,8 @@ issue_token(#authorization{client = Client, resowner = ResOwner,
208 211 %% @doc Issue an Access Token and a Refresh Token.
209 212 %% The OAuth2 specification forbids or discourages issuing a refresh token
210 213 %% when no resource owner is authenticated (See 4.2.2 and 4.4.3)
211   --spec issue_token_and_refresh(auth(), term()) -> response().
  214 +-spec issue_token_and_refresh(auth(), appctx())
  215 + -> {ok, {appctx(), response()}}.
212 216 issue_token_and_refresh(#authorization{client = Client, resowner = ResOwner,
213 217 scope = Scope, ttl = TTL}, AppCtx1)
214 218 when ResOwner /= undefined ->
@@ -227,7 +231,8 @@ issue_token_and_refresh(#authorization{client = Client, resowner = ResOwner,
227 231
228 232 %% @doc Verifies an access code AccessCode, returning its associated
229 233 %% context if successful. Otherwise, an OAuth2 error code is returned.
230   --spec verify_access_code(token(), term()) -> {ok, context()} | {error, error()}.
  234 +-spec verify_access_code(token(), appctx())
  235 + -> {ok, {appctx(), context()}} | {error, error()}.
231 236 verify_access_code(AccessCode, AppCtx1) ->
232 237 case ?BACKEND:resolve_access_code(AccessCode, AppCtx1) of
233 238 {ok, {AppCtx2, GrantCtx}} ->
@@ -243,8 +248,8 @@ verify_access_code(AccessCode, AppCtx1) ->
243 248 %% @doc Verifies an access code AccessCode and it's corresponding Identity,
244 249 %% returning its associated context if successful. Otherwise, an OAuth2
245 250 %% error code is returned.
246   --spec verify_access_code(token(), term(), term())
247   - -> {ok, context()} | {error, error()}.
  251 +-spec verify_access_code(token(), term(), appctx())
  252 + -> {ok, {appctx(), context()}} | {error, error()}.
248 253 verify_access_code(AccessCode, Client, AppCtx1) ->
249 254 case verify_access_code(AccessCode, AppCtx1) of
250 255 {ok, {AppCtx2, GrantCtx}} ->
@@ -257,8 +262,8 @@ verify_access_code(AccessCode, Client, AppCtx1) ->
257 262
258 263 %% @doc Verifies an refresh token RefreshToken, returning a new Access Token
259 264 %% if successful. Otherwise, an OAuth2 error code is returned.
260   --spec refresh_access_token(binary(), binary(), token(), scope(), term())
261   - -> {ok, {term(), response()}} | {error, error()}.
  265 +-spec refresh_access_token(binary(), binary(), token(), scope(), appctx())
  266 + -> {ok, {appctx(), response()}} | {error, error()}.
262 267 refresh_access_token(CId, CSecret, RefreshToken, Scope, AppCtx1) ->
263 268 case ?BACKEND:authenticate_client(CId, CSecret, AppCtx1) of
264 269 {ok, {AppCtx2, Client}} ->
@@ -298,8 +303,8 @@ refresh_access_token(CId, CSecret, RefreshToken, Scope, AppCtx1) ->
298 303
299 304 %% @doc Verifies an access token AccessToken, returning its associated
300 305 %% context if successful. Otherwise, an OAuth2 error code is returned.
301   --spec verify_access_token(token(), term())
302   - -> {ok, context()} | {error, error()}.
  306 +-spec verify_access_token(token(), appctx())
  307 + -> {ok, {appctx(), context()}} | {error, error()}.
303 308 verify_access_token(AccessToken, AppCtx1) ->
304 309 case ?BACKEND:resolve_access_token(AccessToken, AppCtx1) of
305 310 {ok, {AppCtx2, GrantCtx}} ->
43 src/oauth2_backend.erl
@@ -22,93 +22,92 @@
22 22
23 23 %%%_ * Types -----------------------------------------------------------
24 24 -type grantctx() :: oauth2:context().
25   --type appctx() :: term().
26   --type token() :: binary().
27   --type scope() :: list(binary()) | binary().
  25 +-type appctx() :: oauth2:appctx().
  26 +-type token() :: oauth2:token().
  27 +-type scope() :: oauth2:scope().
28 28
29 29 %%%_* Behaviour ========================================================
30 30 %% @doc Authenticates a combination of username and password.
31 31 %% Returns the resource owner identity if the credentials are valid.
32 32 -callback authenticate_username_password(binary(), binary(), appctx()) ->
33   - {ok, term()} | {error, notfound | badpass}.
  33 + {ok, {appctx(), term()}} | {error, notfound | badpass}.
34 34
35 35 %% @doc Authenticates a client's credentials for a given scope.
36 36 -callback authenticate_client(binary(), binary(), appctx()) ->
37   - {ok, term()} | {error, notfound | badsecret}.
  37 + {ok, {appctx(), term()}} | {error, notfound | badsecret}.
38 38
39 39 %% @doc Stores a new access code token(), associating it with Context.
40 40 %% The context is a proplist carrying information about the identity
41 41 %% with which the code is associated, when it expires, etc.
42 42 -callback associate_access_code(token(), grantctx(), appctx()) ->
43   - ok | {error, notfound}.
  43 + {ok, appctx()} | {error, notfound}.
44 44
45 45 %% @doc Stores a new access token token(), associating it with Context.
46 46 %% The context is a proplist carrying information about the identity
47 47 %% with which the token is associated, when it expires, etc.
48 48 -callback associate_access_token(token(), grantctx(), appctx()) ->
49   - ok | {error, notfound}.
  49 + {ok, appctx()} | {error, notfound}.
50 50
51 51 %% @doc Stores a new refresh token token(), associating it with
52 52 %% grantctx(). The context is a proplist carrying information about the
53 53 %% identity with which the token is associated, when it expires, etc.
54 54 -callback associate_refresh_token(token(), grantctx(), appctx()) ->
55   - ok | {error, notfound}.
  55 + {ok, appctx()} | {error, notfound}.
56 56
57 57 %% @doc Looks up an access token token(), returning the corresponding
58 58 %% context if a match is found.
59 59 -callback resolve_access_token(token(), appctx()) ->
60   - {ok, grantctx()} | {error, notfound}.
  60 + {ok, {appctx(), grantctx()}} | {error, notfound}.
61 61
62 62 %% @doc Looks up an access code token(), returning the corresponding
63 63 %% context if a match is found.
64 64 -callback resolve_access_code(token(), appctx()) ->
65   - {ok, grantctx()} | {error, notfound}.
  65 + {ok, {appctx(), grantctx()}} | {error, notfound}.
66 66
67 67 %% @doc Looks up an refresh token token(), returning the corresponding
68 68 %% context if a match is found.
69 69 -callback resolve_refresh_token(token(), appctx()) ->
70   - {ok, grantctx()} | {error, notfound}.
  70 + {ok, {appctx(), grantctx()}} | {error, notfound}.
71 71
72 72 %% @doc Revokes an access token token(), so that it cannot be used again.
73 73 -callback revoke_access_token(token(), appctx()) ->
74   - ok | {error, notfound}.
  74 + {ok, appctx()} | {error, notfound}.
75 75
76 76 %% @doc Revokes an access code token(), so that it cannot be used again.
77 77 -callback revoke_access_code(token(), appctx()) ->
78   - ok | {error, notfound}.
  78 + {ok, appctx()} | {error, notfound}.
79 79
80 80 %% @doc Revokes an refresh token token(), so that it cannot be used again.
81 81 -callback revoke_refresh_token(token(), appctx()) ->
82   - ok | {error, notfound}.
  82 + {ok, appctx()} | {error, notfound}.
83 83
84 84 %% @doc Returns the redirection URI associated with the client ClientId.
85 85 -callback get_redirection_uri(binary(), appctx()) ->
86   - {error, notfound} | {ok, binary()}.
  86 + {error, notfound} | {ok, {appctx(), binary()}}.
87 87
88 88 %% @doc Returns a client identity for a given id.
89 89 -callback get_client_identity(binary(), appctx()) ->
90   - {ok, term()} | {error, notfound | badsecret}.
  90 + {ok, {appctx(), term()}} | {error, notfound | badsecret}.
91 91
92 92 %% @doc Verifies that RedirectionUri is a valid redirection URI for the
93 93 %% client identified by Identity.
94 94 -callback verify_redirection_uri(term(), binary(), appctx()) ->
95   - ok | {error, notfound | baduri}.
  95 + {ok, appctx()} | {error, notfound | baduri}.
96 96
97 97 %% @doc Verifies that scope() is a valid scope for the client identified
98 98 %% by Identity.
99 99 -callback verify_client_scope(term(), scope(), appctx()) ->
100   - {ok, scope()} | {error, notfound | badscope}.
  100 + {ok, {appctx(), scope()}} | {error, notfound | badscope}.
101 101
102 102 %% @doc Verifies that scope() is a valid scope for the resource
103 103 %% owner identified by Identity.
104 104 -callback verify_resowner_scope(term(), scope(), appctx()) ->
105   - {ok, scope()} | {error, notfound | badscope}.
  105 + {ok, {appctx(), scope()}} | {error, notfound | badscope}.
106 106
107 107 %% @doc Verifies that scope() is a valid scope of the set of scopes defined
108   -%% by Validscope()s.
109   -%% @end
  108 +%% by Validscope()s.
110 109 -callback verify_scope(scope(), scope(), appctx()) ->
111   - {ok, scope()} | {error, notfound | badscope}.
  110 + {ok, {appctx(), scope()}} | {error, notfound | badscope}.
112 111
113 112 %%%_* Tests ============================================================
114 113 -ifdef(TEST).

0 comments on commit 7052b70

Please sign in to comment.
Something went wrong with that request. Please try again.