TD-799: Adds explicit woody dependency (#21)

This commit is contained in:
Aleksey Kashapov 2023-11-09 13:50:42 +03:00 committed by GitHub
parent 211f16c46f
commit 4ad8fcac67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 102 additions and 92 deletions

View File

@ -1,5 +1,8 @@
-module(akm_client). -module(akm_client).
-include_lib("opentelemetry_api/include/otel_tracer.hrl").
-include_lib("opentelemetry_api/include/opentelemetry.hrl").
%% API %% API
-export([ -export([
issue_key/4, issue_key/4,
@ -12,30 +15,18 @@
-spec issue_key(inet:hostname() | inet:ip_address(), inet:port_number(), binary(), map()) -> any(). -spec issue_key(inet:hostname() | inet:ip_address(), inet:port_number(), binary(), map()) -> any().
issue_key(Host, Port, PartyId, ApiKey) -> issue_key(Host, Port, PartyId, ApiKey) ->
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys">>, perform_request(Host, Port, <<"issue_key">>, fun(ConnPid, Headers) ->
Body = jsx:encode(ApiKey), Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys">>,
Headers = [ Body = jsx:encode(ApiKey),
{<<"X-Request-ID">>, <<"issue_key">>}, post(ConnPid, Path, Headers, Body)
{<<"content-type">>, <<"application/json; charset=utf-8">>}, end).
{<<"Authorization">>, <<"Bearer sffsdfsfsdfsdfs">>}
],
ConnPid = connect(Host, Port),
Answer = post(ConnPid, Path, Headers, Body),
disconnect(ConnPid),
parse(Answer).
-spec get_key(inet:hostname() | inet:ip_address(), inet:port_number(), binary(), binary()) -> any(). -spec get_key(inet:hostname() | inet:ip_address(), inet:port_number(), binary(), binary()) -> any().
get_key(Host, Port, PartyId, ApiKeyId) -> get_key(Host, Port, PartyId, ApiKeyId) ->
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys/", ApiKeyId/binary>>, perform_request(Host, Port, <<"get_key">>, fun(ConnPid, Headers) ->
Headers = [ Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys/", ApiKeyId/binary>>,
{<<"X-Request-ID">>, <<"get_key">>}, get(ConnPid, Path, Headers)
{<<"content-type">>, <<"application/json; charset=utf-8">>}, end).
{<<"Authorization">>, <<"Bearer sffsdfsfsdfsdfs">>}
],
ConnPid = connect(Host, Port),
Answer = get(ConnPid, Path, Headers),
disconnect(ConnPid),
parse(Answer).
-spec list_keys(inet:hostname() | inet:ip_address(), inet:port_number(), binary()) -> any(). -spec list_keys(inet:hostname() | inet:ip_address(), inet:port_number(), binary()) -> any().
list_keys(Host, Port, PartyId) -> list_keys(Host, Port, PartyId) ->
@ -43,46 +34,45 @@ list_keys(Host, Port, PartyId) ->
-spec list_keys(inet:hostname() | inet:ip_address(), inet:port_number(), binary(), list()) -> any(). -spec list_keys(inet:hostname() | inet:ip_address(), inet:port_number(), binary(), list()) -> any().
list_keys(Host, Port, PartyId, QsList) -> list_keys(Host, Port, PartyId, QsList) ->
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys">>, perform_request(Host, Port, <<"list_keys">>, fun(ConnPid, Headers) ->
Headers = [ Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys">>,
{<<"X-Request-ID">>, <<"list_keys">>}, PathWithQuery = maybe_query(Path, QsList),
{<<"content-type">>, <<"application/json; charset=utf-8">>}, get(ConnPid, PathWithQuery, Headers)
{<<"Authorization">>, <<"Bearer sffsdfsfsdfsdfs">>} end).
],
PathWithQuery = maybe_query(Path, QsList),
ConnPid = connect(Host, Port),
Answer = get(ConnPid, PathWithQuery, Headers),
disconnect(ConnPid),
parse(Answer).
-spec request_revoke_key(inet:hostname() | inet:ip_address(), inet:port_number(), binary(), binary()) -> any(). -spec request_revoke_key(inet:hostname() | inet:ip_address(), inet:port_number(), binary(), binary()) -> any().
request_revoke_key(Host, Port, PartyId, ApiKeyId) -> request_revoke_key(Host, Port, PartyId, ApiKeyId) ->
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys/", ApiKeyId/binary, "/status">>, perform_request(Host, Port, <<"request_revoke">>, fun(ConnPid, Headers) ->
Headers = [ Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys/", ApiKeyId/binary, "/status">>,
{<<"X-Request-ID">>, <<"request_revoke">>}, Body = jsx:encode(#{<<"status">> => <<"revoked">>}),
{<<"content-type">>, <<"application/json; charset=utf-8">>}, put(ConnPid, Path, Headers, Body)
{<<"Authorization">>, <<"Bearer sffsdfsfsdfsdfs">>} end).
],
Body = jsx:encode(#{<<"status">> => <<"revoked">>}),
ConnPid = connect(Host, Port),
Answer = put(ConnPid, Path, Headers, Body),
disconnect(ConnPid),
parse(Answer).
-spec revoke_key(inet:hostname() | inet:ip_address(), inet:port_number(), binary()) -> any(). -spec revoke_key(inet:hostname() | inet:ip_address(), inet:port_number(), binary()) -> any().
revoke_key(Host, Port, PathWithQuery) -> revoke_key(Host, Port, PathWithQuery) ->
Headers = [ perform_request(Host, Port, <<"revoke_key">>, fun(ConnPid, Headers) ->
{<<"X-Request-ID">>, <<"request_revoke">>}, get(ConnPid, PathWithQuery, Headers)
{<<"content-type">>, <<"application/json; charset=utf-8">>}, end).
{<<"Authorization">>, <<"Bearer sffsdfsfsdfsdfs">>}
],
ConnPid = connect(Host, Port),
Answer = get(ConnPid, PathWithQuery, Headers),
disconnect(ConnPid),
parse(Answer).
% Internal functions % Internal functions
perform_request(Host, Port, RequestID, F) ->
SpanName = iolist_to_binary(["client ", RequestID]),
?with_span(SpanName, #{kind => ?SPAN_KIND_CLIENT}, fun(_SpanCtx) ->
Headers = prepare_headers(RequestID),
ConnPid = connect(Host, Port),
Answer = F(ConnPid, Headers),
disconnect(ConnPid),
parse(Answer)
end).
prepare_headers(RequestID) ->
otel_propagator_text_map:inject([
{<<"X-Request-ID">>, RequestID},
{<<"content-type">>, <<"application/json; charset=utf-8">>},
{<<"Authorization">>, <<"Bearer sffsdfsfsdfsdfs">>}
]).
-spec connect(inet:hostname() | inet:ip_address(), inet:port_number()) -> any(). -spec connect(inet:hostname() | inet:ip_address(), inet:port_number()) -> any().
connect(Host, Port) -> connect(Host, Port) ->
connect(Host, Port, #{}). connect(Host, Port, #{}).

View File

@ -2,6 +2,8 @@
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
-include_lib("bouncer_proto/include/bouncer_ctx_thrift.hrl"). -include_lib("bouncer_proto/include/bouncer_ctx_thrift.hrl").
-include_lib("bouncer_proto/include/bouncer_decision_thrift.hrl").
-include_lib("token_keeper_proto/include/tk_token_keeper_thrift.hrl").
-type config() :: [{atom(), term()}]. -type config() :: [{atom(), term()}].
-type test_case_name() :: atom(). -type test_case_name() :: atom().
@ -19,16 +21,16 @@
]). ]).
-define(ACCESS_TOKEN, <<"some.access.token">>). -define(ACCESS_TOKEN, <<"some.access.token">>).
-define(AUTH_CTX, #{ -define(AUTH_CTX, #token_keeper_AuthData{
id => <<"auth_data_id">>, id = <<"auth_data_id">>,
token => ?ACCESS_TOKEN, token = ?ACCESS_TOKEN,
status => active, status = active,
context => #ctx_ContextFragment{type = 'v1_thrift_binary'}, context = #ctx_ContextFragment{type = 'v1_thrift_binary'},
metadata => #{ metadata = #{
<<"dev.vality.party.id">> => <<"some_party">>, <<"dev.vality.party.id">> => <<"some_party">>,
<<"dev.vality.user.email">> => <<"box@mail.ru">> <<"dev.vality.user.email">> => <<"box@mail.ru">>
}, },
authority => <<"authority_id">> authority = <<"authority_id">>
}). }).
-spec init(_, _) -> _. -spec init(_, _) -> _.
@ -86,6 +88,7 @@ prepare_config(State) ->
{transport, thrift}, {transport, thrift},
{bouncer_ruleset_id, <<"service/authz/api">>}, {bouncer_ruleset_id, <<"service/authz/api">>},
{vault_token_path, WorkDir ++ "/rebar.config"}, {vault_token_path, WorkDir ++ "/rebar.config"},
{authority_id, <<"authority_id">>},
{health_check, #{ {health_check, #{
disk => {erl_health, disk, ["/", 99]}, disk => {erl_health, disk, ["/", 99]},
memory => {erl_health, cg_memory, [99]}, memory => {erl_health, cg_memory, [99]},
@ -111,9 +114,33 @@ prepare_config(State) ->
}} }}
]}, ]},
{bouncer_client, [
{service_clients, #{
bouncer => #{url => <<"http://bouncer/v1/arbiter">>},
org_management => #{url => <<"http://org-management/org/v1/auth-context">>}
}}
]},
{token_keeper_client, [
{service_clients, #{
authenticator => #{url => <<"http://authenticator/v2/authenticator">>},
authorities => #{
offline => #{
<<"authority_id">> => #{
url => <<"http://authenticator/v2/authority/com.empayre.apikey">>
}
}
}
}}
]},
{canal, [ {canal, [
{url, "http://vault:8200"}, {url, "http://vault:8200"},
{engine, kvv2} {engine, kvv2}
]},
{opentelemetry, [
{span_processor, simple}
]} ]}
], ],
@ -147,37 +174,23 @@ mock_services(State) ->
} }
end end
), ),
meck:expect( meck:expect(
bouncer_client, woody_client,
judge, call,
fun(_, _, _) -> allowed end fun
), (_Request = {{_, 'Arbiter'}, 'Judge', _}, _Options, _Context) ->
meck:expect( {ok, #decision_Judgement{resolution = {allowed, #decision_ResolutionAllowed{}}}};
token_keeper_authority_offline, (_Request = {{_, 'TokenAuthenticator'}, 'Authenticate', _}, _Options, _Context) ->
create, {ok, ?AUTH_CTX};
fun(_ID, _ContextFragment, _Metadata, _Client) -> (_Request = {{_, 'TokenAuthority'}, 'Create', _}, _Options, _Context) ->
{ok, #{token => ?ACCESS_TOKEN}} {ok, ?AUTH_CTX};
(_Request = {{_, 'TokenAuthority'}, 'Revoke', _}, _Options, _Context) ->
{ok, ok};
(Request, Options, Context) ->
meck:passthrough([Request, Options, Context])
end end
), ),
meck:expect(
token_keeper_authority_offline,
revoke,
fun(_ID, _Client) ->
{ok, ok}
end
),
meck:expect(
token_keeper_authenticator,
authenticate,
fun(_PreAuthContext, _TokenContext, _WoodyContext) ->
{ok, ?AUTH_CTX}
end
),
meck:expect(
token_keeper_client,
offline_authority,
fun(_, _) -> #{} end
),
State. State.
start_akm(State) -> start_akm(State) ->

View File

@ -3,6 +3,12 @@ services:
depends_on: depends_on:
jaeger: jaeger:
condition: service_healthy condition: service_healthy
environment:
- OTEL_SERVICE_NAME=api-key-mgmt-v2
- OTEL_TRACES_EXPORTER=otlp
- OTEL_TRACES_SAMPLER=parentbased_always_on
- OTEL_EXPORTER_OTLP_PROTOCOL=http_protobuf
- OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318
jaeger: jaeger:
image: jaegertracing/all-in-one:1.47 image: jaegertracing/all-in-one:1.47

View File

@ -40,6 +40,7 @@
{bouncer_proto, {git, "https://github.com/valitydev/bouncer-proto.git", {branch, "master"}}}, {bouncer_proto, {git, "https://github.com/valitydev/bouncer-proto.git", {branch, "master"}}},
{bouncer_client, {git, "https://github.com/valitydev/bouncer-client-erlang", {branch, "master"}}}, {bouncer_client, {git, "https://github.com/valitydev/bouncer-client-erlang", {branch, "master"}}},
{token_keeper_client, {git, "https://github.com/valitydev/token-keeper-client", {branch, "master"}}}, {token_keeper_client, {git, "https://github.com/valitydev/token-keeper-client", {branch, "master"}}},
{woody, {git, "https://github.com/valitydev/woody_erlang.git", {branch, master}}},
%% Libraries generated with swagger-codegen-erlang from valitydev/swag-api-keys %% Libraries generated with swagger-codegen-erlang from valitydev/swag-api-keys
{swag_server_apikeys, {swag_server_apikeys,

View File

@ -10,7 +10,7 @@
0}, 0},
{<<"bouncer_client">>, {<<"bouncer_client">>,
{git,"https://github.com/valitydev/bouncer-client-erlang", {git,"https://github.com/valitydev/bouncer-client-erlang",
{ref,"4f89634d9a009cac807cf86a0eff9e80d33318ea"}}, {ref,"f7ab2fdf3bd39d447d4dd039280ef98937ce7c87"}},
0}, 0},
{<<"bouncer_proto">>, {<<"bouncer_proto">>,
{git,"https://github.com/valitydev/bouncer-proto.git", {git,"https://github.com/valitydev/bouncer-proto.git",
@ -131,7 +131,7 @@
1}, 1},
{<<"org_management_proto">>, {<<"org_management_proto">>,
{git,"https://github.com/valitydev/org-management-proto", {git,"https://github.com/valitydev/org-management-proto",
{ref,"03a269df4805fa604e8fd2d04241619a739e2ae3"}}, {ref,"04de2f4ad697430c75f8efa04716d30753bd7c4b"}},
1}, 1},
{<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.1">>},1}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.4.1">>},1},
{<<"pooler">>,{pkg,<<"pooler">>,<<"1.5.3">>},1}, {<<"pooler">>,{pkg,<<"pooler">>,<<"1.5.3">>},1},
@ -170,11 +170,11 @@
1}, 1},
{<<"token_keeper_client">>, {<<"token_keeper_client">>,
{git,"https://github.com/valitydev/token-keeper-client", {git,"https://github.com/valitydev/token-keeper-client",
{ref,"417916aab09baf0cd7f1a2a174945446203ea0bf"}}, {ref,"642b20e622ef5d3ed41127bdc9b2b0fc1d43c7e5"}},
0}, 0},
{<<"token_keeper_proto">>, {<<"token_keeper_proto">>,
{git,"https://github.com/valitydev/token-keeper-proto.git", {git,"https://github.com/valitydev/token-keeper-proto.git",
{ref,"094b4f05a4e220df79911c25093feffea1cb868b"}}, {ref,"8b8bb4333828350301ae2fe801c0c8de61c6529c"}},
1}, 1},
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},2},
{<<"uuid">>, {<<"uuid">>,
@ -183,7 +183,7 @@
0}, 0},
{<<"woody">>, {<<"woody">>,
{git,"https://github.com/valitydev/woody_erlang.git", {git,"https://github.com/valitydev/woody_erlang.git",
{ref,"68b191ed3655dbf40d0ba687f17f75ddd74e82da"}}, {ref,"5d46291a6bfcee0bae2a9346a7d927603a909249"}},
0}, 0},
{<<"woody_user_identity">>, {<<"woody_user_identity">>,
{git,"https://github.com/valitydev/woody_erlang_user_identity.git", {git,"https://github.com/valitydev/woody_erlang_user_identity.git",