Skip to content

Commit 8450b8f

Browse files
refactor: Fix version, update elvis config and variable renaming (#17)
* no-release: Fix id_token version but skip the release process * Simplify maintenance of Elvis linter rules * rebar3_lint: fix for consistent_variable_casing * rebar3_lint: fix for no_trailing_whitespace * rebar3_lint: "fix" for no_block_expressions A proper fix would probably be to not avoid it, but 1. that'd change code, which is not our priority here, 2. that might not be easy to achieve when macros are involved * rebar3_lint: fix for used_ignored_variable * rebar3_lint: fix for operator_spaces * rebar3_lint: "fix" for no_debug_call Instead of an actual fix we work around it by allowing it; on the other hand I'm not sure why it exists in the code but it's not our priority to check that now * Make all Jw[<lowercase>] JW[<uppercase>] for readability * Delete unwarranted push --------- Co-authored-by: Paulo F. Oliveira <[email protected]>
1 parent 982b2ee commit 8450b8f

12 files changed

+53
-132
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,3 @@ _build
1818
rebar3.crashdump
1919
*~
2020
.edts
21-
.elvis

Makefile

+1-28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
ELVIS_IN_PATH := $(shell elvis --version 2> /dev/null)
2-
ELVIS_LOCAL := $(shell .elvis/_build/default/bin/elvis --version 2> /dev/null)
3-
41
all: compile
52

63
compile:
@@ -33,29 +30,5 @@ unlock:
3330
lock:
3431
rebar3 lock
3532

36-
elvis:
37-
ifdef ELVIS_IN_PATH
38-
elvis git-branch origin/HEAD -V
39-
else ifdef ELVIS_LOCAL
40-
.elvis/_build/default/bin/elvis git-branch origin/HEAD -V
41-
else
42-
$(MAKE) compile_elvis
43-
.elvis/_build/default/bin/elvis git-branch origin/HEAD -V
44-
endif
45-
4633
elvis_rock:
47-
ifdef ELVIS_IN_PATH
48-
elvis rock
49-
else ifdef ELVIS_LOCAL
50-
.elvis/_build/default/bin/elvis rock
51-
else
52-
$(MAKE) compile_elvis
53-
.elvis/_build/default/bin/elvis rock
54-
endif
55-
56-
compile_elvis:
57-
git clone https://github.com/inaka/elvis.git .elvis && \
58-
cd .elvis && \
59-
rebar3 compile && \
60-
rebar3 escriptize && \
61-
cd ..
34+
rebar3 lint

elvis.config

+6-60
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,19 @@
11
%% -*- erlang -*-
22
[ {elvis,
33
[ {config,
4-
[ #{dirs => [ "src/*"
5-
, "src"
4+
[ #{dirs => [ "src"
65
],
76
filter => "*.erl",
8-
ignore => [],
9-
ruleset => [{elvis_style, state_record_and_type, disable}],
10-
rules => [ {elvis_text_style, line_length,
11-
#{ limit => 100,
12-
skip_comments => false
13-
}}
14-
, {elvis_text_style, no_tabs}
15-
, {elvis_text_style, no_trailing_whitespace}
16-
, {elvis_style, macro_module_names}
17-
, {elvis_style, nesting_level,
18-
#{ level => 3,
19-
ignore => [
20-
]
21-
}}
22-
, {elvis_style, god_modules,
23-
#{ limit => 25,
24-
ignore => [
25-
]
26-
}}
27-
, {elvis_style, no_nested_try_catch,
28-
#{ignore => [
29-
]
30-
}}
31-
, {elvis_style, invalid_dynamic_call,
32-
#{ignore => [
33-
]
34-
}}
35-
, {elvis_style, used_ignored_variable}
36-
, {elvis_style, no_behavior_info}
37-
, {elvis_style, module_naming_convention,
38-
#{ ignore => [],
39-
regex => "^([a-z][a-z0-9]*_?)([a-z0-9]*_?)*$"
40-
}}
41-
, {elvis_style, function_naming_convention,
42-
#{ regex => "^([a-z][a-z0-9]*_?)([a-z0-9]*_?)*$"
43-
}}
44-
, {elvis_style, variable_naming_convention,
45-
#{ regex => "^_?([A-Z][0-9a-zA-Z_]*)$"
46-
}}
47-
, {elvis_style, state_record_and_type}
48-
, {elvis_style, no_spec_with_records}
49-
, {elvis_style, dont_repeat_yourself,
50-
#{ min_complexity => 25,
51-
ignore => [
52-
]
53-
}}
7+
ruleset => erl_files,
8+
rules => [ {elvis_style, no_block_expressions, disable}
549
]
5510
},
5611
#{dirs => [ "test"
5712
],
5813
filter => "*.erl",
59-
rules => [ {elvis_text_style, line_length,
60-
#{ limit => 100,
61-
skip_comments => false
62-
}}
63-
, {elvis_text_style, no_tabs}
64-
, {elvis_text_style, no_trailing_whitespace}
65-
, {elvis_style, macro_module_names}
66-
, {elvis_style, no_debug_call,
67-
#{ignore => [ prop_pubkeys_storage,
68-
prop_id_token_sign
69-
]
70-
}}
14+
ruleset => erl_files,
15+
rules => [ {elvis_style, no_block_expressions, disable}
16+
, {elvis_style, no_debug_call, disable}
7117
]
7218
}
7319
]

rebar.config

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
{apps, [id_token]}
99
]}.
1010

11-
{project_plugins, [rebar3_proper]}.
11+
{project_plugins, [
12+
{rebar3_proper, "0.12.1"},
13+
{rebar3_lint, "3.2.6"}
14+
]}.
1215

1316
{profiles,
1417
[{test, [

src/id_token.app.src

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{application, id_token,
22
[{description, "An OTP application to validate Id tokens"},
3-
{vsn, "0.1.1"},
3+
{vsn, git},
44
{registered, []},
55
{mod, {id_token_app, []}},
66
{applications,

src/id_token_jwks.erl

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ get_pub_keys(Uri) ->
3333
get_jwks_uri(Uri) ->
3434
case hackney:request(get, Uri, [], <<>>, [with_body]) of
3535
{ok, 200, _Headers, Body} ->
36-
#{<<"jwks_uri">> := JwksUri} = jsx:decode(Body, [return_maps]),
37-
{ok, JwksUri};
36+
#{<<"jwks_uri">> := JWKSUri} = jsx:decode(Body, [return_maps]),
37+
{ok, JWKSUri};
3838
{ok, _, _, _} ->
3939
{error, service_unavailable};
4040
{error, Reason} ->

src/id_token_jws.erl

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[generate_key_for/1, generate_key_for/2,
55
sign/2, sign/3,
66
validate/1, validate/2,
7-
extract_kid/1]).
7+
extract_kid/1]).
88
-ignore_xref(?API_CALLS).
99
-export(?API_CALLS).
1010

@@ -72,12 +72,12 @@ generate_key_for(Alg, Options) ->
7272
<<"ES", _S/binary>> -> generate_ec_key(Alg, Options);
7373
_ -> generate_rsa_key(Alg, Options)
7474
end,
75-
Jwk0 = jose_jwk:from_key(Key),
76-
Jwk = Jwk0#jose_jwk{fields = #{<<"kid">> => kid(Options),
75+
JWK0 = jose_jwk:from_key(Key),
76+
JWK = JWK0#jose_jwk{fields = #{<<"kid">> => kid(Options),
7777
<<"use">> => <<"sig">>,
7878
<<"iat">> => iat(Options)}},
79-
{_, PublicKeyMap} = jose_jwk:to_public_map(Jwk),
80-
{Jwk, PublicKeyMap}.
79+
{_, PublicKeyMap} = jose_jwk:to_public_map(JWK),
80+
{JWK, PublicKeyMap}.
8181

8282
extract_kid(IdToken) ->
8383
Protected = jose_jwt:peek_protected(IdToken),
@@ -91,7 +91,7 @@ extract_kid(IdToken) ->
9191

9292
validate_signature(Key, IdToken) ->
9393
case jose_jwt:verify(Key, IdToken) of
94-
{true, #jose_jwt{fields = Claims}, _Jws} ->
94+
{true, #jose_jwt{fields = Claims}, _JWS} ->
9595
{ok, Claims};
9696
{false, _, _} ->
9797
{error, invalid_signature}

src/id_token_sign.erl

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ handle_info(_Request, Timers0) ->
7575
%%% Internal functions
7676
%%%===================================================================
7777
put_key_for(Alg, Options) ->
78-
{Jwk, PublicKeyMap} = id_token_jws:generate_key_for(Alg, Options),
79-
SignKeyFun = fun() -> Jwk end,
78+
{JWK, PublicKeyMap} = id_token_jws:generate_key_for(Alg, Options),
79+
SignKeyFun = fun() -> JWK end,
8080
#{<<"kid">> := Kid, <<"iat">> := Iat} = PublicKeyMap,
8181
TTU = maps:get(ttu, Options, ?TTU),
8282
Exp = Iat + TTU,

test/id_token_SUITE.erl

+14-14
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,26 @@ init_per_suite(Config) ->
1919
end_per_suite(_Config) -> ok.
2020

2121
init_per_testcase(_TestCase, Config) ->
22-
{Jwk, PublicKeyMap} =
22+
{JWK, PublicKeyMap} =
2323
id_token_jws:generate_key_for(<<"RS256">>, #{key_size => 1024}),
2424
Claims = #{ <<"exp">> => erlang:system_time(second) + 10},
25-
Jwt = id_token_jws:sign(Claims, Jwk),
25+
JWT = id_token_jws:sign(Claims, JWK),
2626
mock_id_provider(PublicKeyMap, 0),
2727
application:ensure_all_started(id_token),
28-
[{jwt, Jwt}, {pubkeys, [PublicKeyMap]} | Config].
28+
[{jwt, JWT}, {pubkeys, [PublicKeyMap]} | Config].
2929
end_per_testcase(_TestCase, Config) ->
3030
application:stop(id_token),
3131
meck:unload([id_token_jwks, hackney]),
3232
Config.
3333

3434
validate_jwt(Config) ->
35-
Jwt = ?config(jwt, Config),
36-
?assertMatch({ok, _}, id_token:validate(?ID_PROVIDER, Jwt)).
35+
JWT = ?config(jwt, Config),
36+
?assertMatch({ok, _}, id_token:validate(?ID_PROVIDER, JWT)).
3737

3838
keys_are_cached(Config) ->
39-
Jwt = ?config(jwt, Config),
40-
?assertMatch({ok, _}, id_token:validate(?ID_PROVIDER, Jwt)),
41-
?assertMatch({ok, _}, id_token:validate(?ID_PROVIDER, Jwt)),
39+
JWT = ?config(jwt, Config),
40+
?assertMatch({ok, _}, id_token:validate(?ID_PROVIDER, JWT)),
41+
?assertMatch({ok, _}, id_token:validate(?ID_PROVIDER, JWT)),
4242
1 = meck:num_calls(id_token_jwks, get_pub_keys, 1),
4343
ok.
4444

@@ -49,24 +49,24 @@ keys_are_only_refreshed_once_per_kid(Config) ->
4949
ok = meck:expect(id_token_provider, get_cached_keys, 1, CurrentKeyCache),
5050

5151
%% create JWT with kid that's not yet in the pubkey cache
52-
{Jwk, NewPubkey} = id_token_jws:generate_key_for(<<"RS256">>, #{key_size => 1024}),
52+
{JWK, NewPubkey} = id_token_jws:generate_key_for(<<"RS256">>, #{key_size => 1024}),
5353
Claims = #{ <<"exp">> => erlang:system_time(second) + 10 },
54-
Jwt = id_token_jws:sign(Claims, Jwk),
54+
JWT = id_token_jws:sign(Claims, JWK),
5555

5656
%% set up provider to return new pubkeys with a 50 ms delay
5757
HttpReponseDelay = 50,
5858
mock_id_provider(NewPubkey, HttpReponseDelay),
5959
?assertEqual(0, meck:num_calls(id_token_jwks, get_pub_keys, 1)),
6060

6161
%% try to validate multiple JWTs based on kid that's not yet in the key cache
62-
spawn(fun() -> id_token:validate(?ID_PROVIDER, Jwt) end),
63-
spawn(fun() -> id_token:validate(?ID_PROVIDER, Jwt) end),
64-
spawn(fun() -> id_token:validate(?ID_PROVIDER, Jwt) end),
62+
spawn(fun() -> id_token:validate(?ID_PROVIDER, JWT) end),
63+
spawn(fun() -> id_token:validate(?ID_PROVIDER, JWT) end),
64+
spawn(fun() -> id_token:validate(?ID_PROVIDER, JWT) end),
6565
timer:sleep(10 * HttpReponseDelay),
6666

6767
%% ensure that the pubkey cache was only refreshed once
6868
?assertEqual(1, meck:num_calls(id_token_jwks, get_pub_keys, 1)),
69-
?assertMatch({ok, _}, id_token:validate(?ID_PROVIDER, Jwt)),
69+
?assertMatch({ok, _}, id_token:validate(?ID_PROVIDER, JWT)),
7070

7171
meck:unload([id_token_provider]).
7272

test/prop_id_token_jwt.erl

+11-11
Original file line numberDiff line numberDiff line change
@@ -26,36 +26,36 @@ eunit_test_() ->
2626
%%% Properties %%%
2727
%%%%%%%%%%%%%%%%%%
2828
prop_valid_signature() ->
29-
?FORALL({{Jwk, PublicKeyMap}, Claims},
29+
?FORALL({{JWK, PublicKeyMap}, Claims},
3030
{key_pair(), jwt_claims()},
3131
begin
3232
#{<<"exp">> := Exp} = Claims,
33-
Jwt = id_token_jws:sign(Claims, Jwk),
34-
Result = id_token_jws:validate(Jwt, [PublicKeyMap]),
33+
JWT = id_token_jws:sign(Claims, JWK),
34+
Result = id_token_jws:validate(JWT, [PublicKeyMap]),
3535
Exp =< erlang:system_time(second)
3636
andalso {error, expired} =:= Result
3737
orelse {ok, Claims} =:= Result
3838
end).
3939

4040
prop_invalid_signature() ->
41-
?FORALL({{Jwk, _PublicKeyMap}, {OtherJwk, OtherPublicKeyMap}, Claims},
41+
?FORALL({{JWK, PublicKeyMap}, {OtherJWK, OtherPublicKeyMap}, Claims},
4242
{key_pair(), key_pair(), jwt_claims()},
4343
begin
44-
#jose_jwk{fields = OtherFields} = OtherJwk,
45-
JwkWithChangedKid = Jwk#jose_jwk{fields = OtherFields},
46-
Jwt = id_token_jws:sign(Claims, JwkWithChangedKid),
44+
#jose_jwk{fields = OtherFields} = OtherJWK,
45+
JWKWithChangedKid = JWK#jose_jwk{fields = OtherFields},
46+
JWT = id_token_jws:sign(Claims, JWKWithChangedKid),
4747
{error, invalid_signature}
48-
=:= id_token_jws:validate(Jwt, [OtherPublicKeyMap])
48+
=:= id_token_jws:validate(JWT, [OtherPublicKeyMap])
4949
end).
5050

5151
prop_no_matching_key() ->
52-
?FORALL({[{Jwk, _PublicKeyMap} | OtherKeys], Claims},
52+
?FORALL({[{JWK, PublicKeyMap} | OtherKeys], Claims},
5353
{non_empty(list(key_pair())), jwt_claims()},
5454
begin
55-
Jwt = id_token_jws:sign(Claims, Jwk),
55+
JWT = id_token_jws:sign(Claims, JWK),
5656
PublicKeys = lists:map(fun({_, Key}) -> Key end, OtherKeys),
5757
{error, no_public_key_matches}
58-
=:= id_token_jws:validate(Jwt, PublicKeys)
58+
=:= id_token_jws:validate(JWT, PublicKeys)
5959
end).
6060

6161
%%%%%%%%%%%%%%%%%%

test/prop_id_token_sign.erl

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ prop_test() ->
2727
{History, State, Result} = run_commands(?MODULE, Cmds),
2828
id_token_sign:stop(),
2929
?WHENFAIL(io:format("History: ~p\nState: ~p\nResult: ~p\n",
30-
[History,State,Result]),
30+
[History, State, Result]),
3131
aggregate(command_names(Cmds), Result =:= ok))
3232
end).
3333

test/prop_pubkeys_storage.erl

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ prop_test() ->
2323
{History, State, Result} = run_commands(?MODULE, Cmds),
2424
id_token_pubkeys_storage:stop(),
2525
?WHENFAIL(io:format("History: ~p\nState: ~p\nResult: ~p\n",
26-
[History,State,Result]),
26+
[History, State, Result]),
2727
aggregate(command_names(Cmds), Result =:= ok))
2828
end).
2929

@@ -37,9 +37,9 @@ initial_state() ->
3737
%% @doc List of possible commands to run against the system
3838
command(_State) ->
3939
frequency([{1, {call, id_token_pubkeys_storage, get_all, []}},
40-
{1, {call, id_token_pubkeys_storage, get,[kid()]}},
41-
{3, {call, id_token_pubkeys_storage, put,[key()]}},
42-
{1, {call, id_token_pubkeys_storage, delete,[kid()]}}
40+
{1, {call, id_token_pubkeys_storage, get, [kid()]}},
41+
{3, {call, id_token_pubkeys_storage, put, [key()]}},
42+
{1, {call, id_token_pubkeys_storage, delete, [kid()]}}
4343
]).
4444

4545
%% @doc Determines whether a command should be valid under the
@@ -84,7 +84,7 @@ key() ->
8484
end).
8585

8686
kid() ->
87-
?LET(Int, integer(1,10), integer_to_binary(Int)).
87+
?LET(Int, integer(1, 10), integer_to_binary(Int)).
8888

8989
%%%_* Emacs ============================================================
9090
%%% Local Variables:

0 commit comments

Comments
 (0)