mirror of
https://github.com/valitydev/api-key-mgmt-v2.git
synced 2024-11-06 02:15:19 +00:00
TD-799: Adds explicit woody dependency (#21)
This commit is contained in:
parent
211f16c46f
commit
4ad8fcac67
@ -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) ->
|
||||||
|
perform_request(Host, Port, <<"issue_key">>, fun(ConnPid, Headers) ->
|
||||||
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys">>,
|
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys">>,
|
||||||
Body = jsx:encode(ApiKey),
|
Body = jsx:encode(ApiKey),
|
||||||
Headers = [
|
post(ConnPid, Path, Headers, Body)
|
||||||
{<<"X-Request-ID">>, <<"issue_key">>},
|
end).
|
||||||
{<<"content-type">>, <<"application/json; charset=utf-8">>},
|
|
||||||
{<<"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) ->
|
||||||
|
perform_request(Host, Port, <<"get_key">>, fun(ConnPid, Headers) ->
|
||||||
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys/", ApiKeyId/binary>>,
|
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys/", ApiKeyId/binary>>,
|
||||||
Headers = [
|
get(ConnPid, Path, Headers)
|
||||||
{<<"X-Request-ID">>, <<"get_key">>},
|
end).
|
||||||
{<<"content-type">>, <<"application/json; charset=utf-8">>},
|
|
||||||
{<<"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) ->
|
||||||
|
perform_request(Host, Port, <<"list_keys">>, fun(ConnPid, Headers) ->
|
||||||
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys">>,
|
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys">>,
|
||||||
Headers = [
|
|
||||||
{<<"X-Request-ID">>, <<"list_keys">>},
|
|
||||||
{<<"content-type">>, <<"application/json; charset=utf-8">>},
|
|
||||||
{<<"Authorization">>, <<"Bearer sffsdfsfsdfsdfs">>}
|
|
||||||
],
|
|
||||||
PathWithQuery = maybe_query(Path, QsList),
|
PathWithQuery = maybe_query(Path, QsList),
|
||||||
ConnPid = connect(Host, Port),
|
get(ConnPid, PathWithQuery, Headers)
|
||||||
Answer = get(ConnPid, PathWithQuery, Headers),
|
end).
|
||||||
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) ->
|
||||||
|
perform_request(Host, Port, <<"request_revoke">>, fun(ConnPid, Headers) ->
|
||||||
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys/", ApiKeyId/binary, "/status">>,
|
Path = <<"/apikeys/v2/orgs/", PartyId/binary, "/api-keys/", ApiKeyId/binary, "/status">>,
|
||||||
Headers = [
|
|
||||||
{<<"X-Request-ID">>, <<"request_revoke">>},
|
|
||||||
{<<"content-type">>, <<"application/json; charset=utf-8">>},
|
|
||||||
{<<"Authorization">>, <<"Bearer sffsdfsfsdfsdfs">>}
|
|
||||||
],
|
|
||||||
Body = jsx:encode(#{<<"status">> => <<"revoked">>}),
|
Body = jsx:encode(#{<<"status">> => <<"revoked">>}),
|
||||||
ConnPid = connect(Host, Port),
|
put(ConnPid, Path, Headers, Body)
|
||||||
Answer = put(ConnPid, Path, Headers, Body),
|
end).
|
||||||
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, #{}).
|
||||||
|
@ -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) ->
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
10
rebar.lock
10
rebar.lock
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user