Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions config/sys.config
Original file line number Diff line number Diff line change
Expand Up @@ -84,23 +84,13 @@
%% Configuration for how to extract said context
methods => [
%% Create bouncer context from various legacy data the token has to offer
%% Avaiable options are: `phony_api_key`, `user_session_token`,
%% `invoice_template_access_token`, `detect_token`
%% Avaiable options are: `user_session_token`, `detect_token`
%% - `user_session_token` requires `user_realm` option to be set
%% - `invoice_template_access_token` requires
%% `domain` option to be set (refer to legacy uac auth options)
%% - `detect_token` tries to determine wether the token is an
%% `phony_api_key` or `user_session_token` based on token's source context and
%% `user_session_token` based on token's source context and
%% `user_session_token_origins` option
%% ALL extractor types require `metadata_ns` to be set
{detect_token, #{
%% phony_api_key options to use (can be used standalone)
phony_api_key_opts => #{
%% Where to put metadata
metadata_mappings => #{
party_id => <<"test.rbkmoney.party.id">>
}
},
%% user_session_token options to use (can be used standalone)
user_session_token_opts => #{
%% Realm of the user
Expand Down
12 changes: 1 addition & 11 deletions src/tk_blacklist.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
%% API

-export([is_blacklisted/2]).
-export([is_user_blacklisted/2]).

%% Supervisor callbacks

Expand All @@ -24,7 +23,6 @@
%%

-define(TAB, ?MODULE).
-define(USER_TAB, user_blacklist).

%%

Expand All @@ -40,34 +38,26 @@ child_spec(Options) ->
is_blacklisted(TokenID, AuthorityID) ->
check_entry(?TAB, {AuthorityID, TokenID}).

-spec is_user_blacklisted(binary(), tk_token:authority_id()) -> boolean().
is_user_blacklisted(UserID, AuthorityID) ->
check_entry(?USER_TAB, {AuthorityID, UserID}).

%%

-spec init(options()) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}.
init(Options) ->
_ = init_tab(?TAB),
_ = init_tab(?USER_TAB),
_ = load_blacklist_conf(maps:get(path, Options, undefined)),
{ok, {#{}, []}}.

init_tab(Name) ->
ets:new(Name, [set, protected, named_table, {read_concurrency, true}]).

-define(ENTRIES_KEY, "entries").
-define(USER_ENTRIES_KEY, "user_entries").

load_blacklist_conf(undefined) ->
_ = logger:warning("No token blacklist file specified! Blacklisting functionality will be disabled."),
ok;
load_blacklist_conf(Filename) ->
[Mappings] = yamerl_constr:file(Filename),
Entries = process_entries(proplists:get_value(?ENTRIES_KEY, Mappings)),
put_entires(?TAB, Entries),
UserEntries = process_entries(proplists:get_value(?USER_ENTRIES_KEY, Mappings, [])),
put_entires(?USER_TAB, UserEntries).
put_entires(?TAB, Entries).

process_entries(Entries) ->
lists:foldl(
Expand Down
10 changes: 4 additions & 6 deletions src/tk_context_extractor.erl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
-type methods() :: [method_opts()].
-type method_opts() ::
{detect_token, tk_context_extractor_detect_token:opts()}
| {phony_api_key, tk_context_extractor_phony_api_key:opts()}
| {user_session_token, tk_context_extractor_user_session_token:opts()}.
-type extracted_context() :: {context_fragment(), tk_authdata:metadata() | undefined}.

Expand All @@ -27,17 +26,16 @@
-type context_fragment() :: bouncer_context_helpers:context_fragment().
-type opts() ::
tk_context_extractor_detect_token:opts()
| tk_context_extractor_phony_api_key:opts()
| tk_context_extractor_user_session_token:opts().

%% API functions

-spec extract_context(method_opts(), token_data()) -> extracted_context() | undefined.
extract_context({detect_token, Opts}, TokenData) ->
tk_context_extractor_detect_token:extract_context(TokenData, Opts);
extract_context({phony_api_key, Opts}, TokenData) ->
tk_context_extractor_phony_api_key:extract_context(TokenData, Opts);
extract_context({phony_api_key, _}, _TokenData) ->
%% NOTE This clause is left behind as a fallback placeholder in place of
%% now-removed phony api key detection.
undefined;
extract_context({user_session_token, Opts}, TokenData) ->
tk_context_extractor_user_session_token:extract_context(TokenData, Opts).

%% Internal functions
5 changes: 2 additions & 3 deletions src/tk_context_extractor_detect_token.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
%% API Types

-type opts() :: #{
phony_api_key_opts := tk_context_extractor_phony_api_key:opts(),
user_session_token_opts := tk_context_extractor_user_session_token:opts(),
user_session_token_origins := list(binary())
}.
Expand Down Expand Up @@ -42,5 +41,5 @@ make_method_opts(TokenType, Opts) ->

get_opts(user_session_token, #{user_session_token_opts := Opts}) ->
Opts;
get_opts(phony_api_key, #{phony_api_key_opts := Opts}) ->
Opts.
get_opts(phony_api_key, _) ->
undefined.
81 changes: 0 additions & 81 deletions src/tk_context_extractor_phony_api_key.erl

This file was deleted.

62 changes: 19 additions & 43 deletions test/token_keeper_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@
-export([authenticate_invalid_token_key_fail/1]).
-export([authenticate_no_payload_claims_fail/1]).
-export([authenticate_user_session_token_no_payload_claims_fail/1]).
-export([authenticate_phony_api_key_token_ok/1]).
-export([authenticate_user_session_token_not_detected/1]).
-export([authenticate_user_session_token_ok/1]).
-export([authenticate_user_session_token_w_exp_ok/1]).
-export([authenticate_user_session_token_no_exp_fail/1]).
-export([authenticate_user_session_token_w_resource_access/1]).
-export([authenticate_blacklisted_jti_fail/1]).
-export([authenticate_non_blacklisted_jti_ok/1]).
-export([authenticate_blacklisted_user_fail/1]).
-export([authenticate_ephemeral_claim_token_ok/1]).
-export([issue_ephemeral_token_ok/1]).
-export([authenticate_offline_token_not_found_fail/1]).
Expand Down Expand Up @@ -98,7 +97,7 @@ groups() ->
authenticate_invalid_token_key_fail,
authenticate_no_payload_claims_fail,
authenticate_user_session_token_no_payload_claims_fail,
authenticate_phony_api_key_token_ok,
authenticate_user_session_token_not_detected,
authenticate_user_session_token_ok,
authenticate_user_session_token_w_exp_ok,
authenticate_user_session_token_no_exp_fail,
Expand Down Expand Up @@ -130,8 +129,7 @@ groups() ->
]},
{blacklist, [parallel], [
authenticate_blacklisted_jti_fail,
authenticate_non_blacklisted_jti_ok,
authenticate_blacklisted_user_fail
authenticate_non_blacklisted_jti_ok
]}
].

Expand Down Expand Up @@ -441,21 +439,17 @@ authenticate_no_payload_claims_fail(C) ->
Token = issue_token(Claims, C),
?assertThrow(#token_keeper_AuthDataNotFound{}, call_authenticate(Token, ?TOKEN_SOURCE_CONTEXT, C)).

-spec authenticate_phony_api_key_token_ok(config()) -> _.
authenticate_phony_api_key_token_ok(C) ->
-spec authenticate_user_session_token_not_detected(config()) -> _.
authenticate_user_session_token_not_detected(C) ->
JTI = unique_id(),
SubjectID = unique_id(),
Claims = get_phony_api_key_claims(JTI, SubjectID),
SubjectEmail = <<"test@test.test">>,
Claims = get_user_session_token_claims(JTI, 0, SubjectID, SubjectEmail),
Token = issue_token(Claims, C),
#token_keeper_AuthData{
id = undefined,
token = Token,
status = active,
context = Context,
metadata = #{?META_PARTY_ID := SubjectID},
authority = ?TK_AUTHORITY_KEYCLOAK
} = call_authenticate(Token, ?TOKEN_SOURCE_CONTEXT, C),
_ = assert_context({api_key_token, #{jti => JTI, subject_id => SubjectID}}, Context).
?assertThrow(
#token_keeper_AuthDataNotFound{},
call_authenticate(Token, ?TOKEN_SOURCE_CONTEXT, C)
).

-spec authenticate_user_session_token_ok(config()) -> _.
authenticate_user_session_token_ok(C) ->
Expand Down Expand Up @@ -556,25 +550,21 @@ authenticate_user_session_token_no_payload_claims_fail(C) ->
authenticate_blacklisted_jti_fail(C) ->
JTI = <<"MYCOOLKEY">>,
SubjectID = unique_id(),
Claims = get_phony_api_key_claims(JTI, SubjectID),
SubjectEmail = <<"test@test.test">>,
Claims = get_user_session_token_claims(JTI, 0, SubjectID, SubjectEmail),
Token = issue_token_with(Claims, get_filename("keys/local/private.pem", C)),
?assertThrow(#token_keeper_AuthDataRevoked{}, call_authenticate(Token, ?TOKEN_SOURCE_CONTEXT, C)).
?assertThrow(
#token_keeper_AuthDataRevoked{}, call_authenticate(Token, ?TOKEN_SOURCE_CONTEXT(?USER_TOKEN_SOURCE), C)
).

-spec authenticate_non_blacklisted_jti_ok(config()) -> _.
authenticate_non_blacklisted_jti_ok(C) ->
JTI = <<"MYCOOLKEY">>,
SubjectID = unique_id(),
Claims = get_phony_api_key_claims(JTI, SubjectID),
SubjectEmail = <<"test@test.test">>,
Claims = get_user_session_token_claims(JTI, 0, SubjectID, SubjectEmail),
Token = issue_token_with(Claims, get_filename("keys/secondary/private.pem", C)),
?assertMatch(#token_keeper_AuthData{}, call_authenticate(Token, ?TOKEN_SOURCE_CONTEXT, C)).

-spec authenticate_blacklisted_user_fail(config()) -> _.
authenticate_blacklisted_user_fail(C) ->
JTI = unique_id(),
SubjectID = <<"PARTYID">>,
Claims = get_phony_api_key_claims(JTI, SubjectID),
Token = issue_token_with(Claims, get_filename("keys/local/private.pem", C)),
?assertThrow(#token_keeper_AuthDataNotFound{}, call_authenticate(Token, ?TOKEN_SOURCE_CONTEXT, C)).
?assertMatch(#token_keeper_AuthData{}, call_authenticate(Token, ?TOKEN_SOURCE_CONTEXT(?USER_TOKEN_SOURCE), C)).

-spec authenticate_ephemeral_claim_token_ok(config()) -> _.
authenticate_ephemeral_claim_token_ok(C) ->
Expand Down Expand Up @@ -746,9 +736,6 @@ get_base_claims(JTI, Exp) ->
<<"exp">> => Exp
}.

get_phony_api_key_claims(JTI, SubjectID) ->
maps:merge(#{<<"sub">> => SubjectID}, get_base_claims(JTI)).

get_user_session_token_claims(JTI, Exp, SubjectID, SubjectEmail) ->
get_user_session_token_claims(JTI, Exp, SubjectID, SubjectEmail, undefined).

Expand Down Expand Up @@ -855,10 +842,6 @@ assert_context(TokenInfo, EncodedContextFragment) ->
assert_auth({claim_token, #{jti := JTI}}, Auth) ->
?assertEqual(<<"ClaimToken">>, Auth#ctx_v1_Auth.method),
?assertMatch(#ctx_v1_Token{id = JTI}, Auth#ctx_v1_Auth.token);
assert_auth({api_key_token, #{jti := JTI, subject_id := SubjectID}}, Auth) ->
?assertEqual(<<"ApiKeyToken">>, Auth#ctx_v1_Auth.method),
?assertMatch(#ctx_v1_Token{id = JTI}, Auth#ctx_v1_Auth.token),
?assertMatch([#ctx_v1_AuthScope{party = ?CTX_ENTITY(SubjectID)}], Auth#ctx_v1_Auth.scope);
assert_auth({user_session_token, #{jti := JTI} = TokenInfo}, Auth) ->
?assertEqual(<<"SessionToken">>, Auth#ctx_v1_Auth.method),
Exp = maps:get(exp, TokenInfo, undefined),
Expand All @@ -880,8 +863,6 @@ assert_auth({user_session_token, #{jti := JTI} = TokenInfo}, Auth) ->

assert_user({claim_token, _}, undefined) ->
ok;
assert_user({api_key_token, _}, undefined) ->
ok;
assert_user({user_session_token, #{subject_id := SubjectID, subject_email := SubjectEmail}}, User) ->
?assertEqual(SubjectID, User#ctx_v1_User.id),
?assertEqual(SubjectEmail, User#ctx_v1_User.email),
Expand Down Expand Up @@ -961,11 +942,6 @@ extract_method_detect_token() ->
{extract_context, #{
methods => [
{detect_token, #{
phony_api_key_opts => #{
metadata_mappings => #{
party_id => ?META_PARTY_ID
}
},
user_session_token_opts => #{
user_realm => <<"external">>,
metadata_mappings => #{
Expand Down
3 changes: 0 additions & 3 deletions test/token_keeper_SUITE_data/blacklisted_keys.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
entries:
blacklisting_authority:
- "MYCOOLKEY"
user_entries:
blacklisting_authority:
- "PARTYID"
Loading