HG-129: primitive access control implemented (#59)

This commit is contained in:
Evgeny Levenets 2017-01-17 15:49:57 +03:00 committed by GitHub
parent 3af4a8bd0b
commit 70a3658beb
5 changed files with 199 additions and 81 deletions

View File

@ -0,0 +1,19 @@
-module(hg_access_control).
-include_lib("dmsl/include/dmsl_payment_processing_thrift.hrl").
%%% HG access controll
-export([check_user_info/2]).
%%
-spec check_user_info(dmsl_payment_processing_thrift:'UserInfo'(), dmsl_domain_thrift:'PartyID'()) ->
ok | invalid_user.
check_user_info(#payproc_UserInfo{id = PartyID, type = {external_user, #payproc_ExternalUser{}}}, PartyID) ->
ok;
check_user_info(#payproc_UserInfo{id = _AnyID, type = {internal_user, #payproc_InternalUser{}}}, _PartyID) ->
ok;
check_user_info(#payproc_UserInfo{id = _AnyID, type = {service_user, #payproc_ServiceUser{}}}, _PartyID) ->
ok;
check_user_info(_, _) ->
invalid_user.

View File

@ -72,8 +72,14 @@
term() | no_return().
handle_function('Create', [UserInfo, InvoiceParams], _Opts) ->
ID = hg_utils:unique_id(),
#payproc_InvoiceParams{party_id = PartyID, shop_id = ShopID} = InvoiceParams,
case hg_access_control:check_user_info(UserInfo, PartyID) of
ok ->
ok;
invalid_user ->
throw(#payproc_InvalidUser{})
end,
ID = hg_utils:unique_id(),
Party = get_party(UserInfo, PartyID),
Shop = validate_party_shop(ShopID, Party),
ok = validate_invoice_params(InvoiceParams, Shop),
@ -81,22 +87,25 @@ handle_function('Create', [UserInfo, InvoiceParams], _Opts) ->
ID;
handle_function('Get', [UserInfo, InvoiceID], _Opts) ->
St = get_state(UserInfo, InvoiceID),
ok = validate_access(UserInfo, InvoiceID),
St = get_state(InvoiceID),
_Party = get_party(UserInfo, get_party_id(St)),
get_invoice_state(St);
handle_function('GetEvents', [UserInfo, InvoiceID, Range], _Opts) ->
%% TODO access control
get_public_history(UserInfo, InvoiceID, Range);
ok = validate_access(UserInfo, InvoiceID),
get_public_history(InvoiceID, Range);
handle_function('StartPayment', [UserInfo, InvoiceID, PaymentParams], _Opts) ->
St0 = get_initial_state(UserInfo, InvoiceID),
ok = validate_access(UserInfo, InvoiceID),
St0 = get_initial_state(InvoiceID),
Party = get_party(UserInfo, get_party_id(St0)),
_Shop = validate_party_shop(get_shop_id(St0), Party),
call(InvoiceID, {start_payment, PaymentParams});
handle_function('GetPayment', [UserInfo, InvoiceID, PaymentID], _Opts) ->
St = get_state(UserInfo, InvoiceID),
ok = validate_access(UserInfo, InvoiceID),
St = get_state(InvoiceID),
case get_payment_session(PaymentID, St) of
PaymentSession when PaymentSession /= undefined ->
hg_invoice_payment:get_payment(PaymentSession);
@ -104,12 +113,12 @@ handle_function('GetPayment', [UserInfo, InvoiceID, PaymentID], _Opts) ->
throw(#payproc_InvoicePaymentNotFound{})
end;
handle_function('Fulfill', [_UserInfo, InvoiceID, Reason], _Opts) ->
%% TODO access control
handle_function('Fulfill', [UserInfo, InvoiceID, Reason], _Opts) ->
ok = validate_access(UserInfo, InvoiceID),
call(InvoiceID, {fulfill, Reason});
handle_function('Rescind', [_UserInfo, InvoiceID, Reason], _Opts) ->
%% TODO access control
handle_function('Rescind', [UserInfo, InvoiceID, Reason], _Opts) ->
ok = validate_access(UserInfo, InvoiceID),
call(InvoiceID, {rescind, Reason}).
get_party(UserInfo, PartyID) ->
@ -150,23 +159,23 @@ process_callback(Tag, Callback) ->
%%
get_history(_UserInfo, InvoiceID) ->
get_history(InvoiceID) ->
map_history_error(hg_machine:get_history(?NS, InvoiceID)).
get_history(_UserInfo, InvoiceID, AfterID, Limit) ->
get_history(InvoiceID, AfterID, Limit) ->
map_history_error(hg_machine:get_history(?NS, InvoiceID, AfterID, Limit)).
get_state(UserInfo, InvoiceID) ->
{History, _LastID} = get_history(UserInfo, InvoiceID),
get_state(InvoiceID) ->
{History, _LastID} = get_history(InvoiceID),
collapse_history(History).
get_initial_state(UserInfo, InvoiceID) ->
{History, _LastID} = get_history(UserInfo, InvoiceID, undefined, 1),
get_initial_state(InvoiceID) ->
{History, _LastID} = get_history(InvoiceID, undefined, 1),
collapse_history(History).
get_public_history(UserInfo, InvoiceID, #payproc_EventRange{'after' = AfterID, limit = Limit}) ->
get_public_history(InvoiceID, #payproc_EventRange{'after' = AfterID, limit = Limit}) ->
hg_history:get_public_history(
fun (ID, Lim) -> get_history(UserInfo, InvoiceID, ID, Lim) end,
fun (ID, Lim) -> get_history(InvoiceID, ID, Lim) end,
fun (Event) -> publish_invoice_event(InvoiceID, Event) end,
AfterID, Limit
).
@ -716,3 +725,14 @@ validate_currency(Currency, Currency) ->
ok;
validate_currency(_, _) ->
throw(#'InvalidRequest'{errors = [<<"Invalid currency">>]}).
validate_access(UserInfo, InvoiceID) ->
St = get_initial_state(InvoiceID),
PartyID = get_party_id(St),
case hg_access_control:check_user_info(UserInfo, PartyID) of
ok ->
ok;
invalid_user ->
throw(#payproc_InvalidUser{})
end.

View File

@ -51,12 +51,13 @@
dmsl_domain_thrift:'Party'() | no_return().
get(UserInfo, PartyID) ->
St = get_state(UserInfo, PartyID),
get_party(St).
ok = assert_party_accessible(UserInfo, PartyID),
get_party(get_state(PartyID)).
-spec checkout(party_id(), revision()) ->
dmsl_domain_thrift:'Party'().
%% DANGER! INSECURE METHOD! USE WITH SPECIAL CARE!
checkout(PartyID, Revision) ->
{History, _LastID} = get_history(PartyID),
case checkout_history(History, Revision) of
@ -72,89 +73,114 @@ checkout(PartyID, Revision) ->
term()| no_return().
handle_function('Create', [UserInfo, PartyID], _Opts) ->
start(PartyID, {UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
start(PartyID);
handle_function('Get', [UserInfo, PartyID], _Opts) ->
St = get_state(UserInfo, PartyID),
get_party(St);
ok = assert_party_accessible(UserInfo, PartyID),
get_party(get_state(PartyID));
handle_function('CreateContract', [UserInfo, PartyID, ContractParams], _Opts) ->
call(PartyID, {create_contract, ContractParams, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {create_contract, ContractParams});
handle_function('GetContract', [UserInfo, PartyID, ContractID], _Opts) ->
St = get_state(UserInfo, PartyID),
ok = assert_party_accessible(UserInfo, PartyID),
St = get_state(PartyID),
get_contract(ContractID, get_party(St));
handle_function('TerminateContract', [UserInfo, PartyID, ContractID, Reason], _Opts) ->
call(PartyID, {terminate_contract, ContractID, Reason, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {terminate_contract, ContractID, Reason});
handle_function('CreateContractAdjustment', [UserInfo, PartyID, ContractID, Params], _Opts) ->
call(PartyID, {create_contract_adjustment, ContractID, Params, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {create_contract_adjustment, ContractID, Params});
handle_function('CreatePayoutAccount', [UserInfo, PartyID, Params], _Opts) ->
call(PartyID, {create_payout_account, Params, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {create_payout_account, Params});
handle_function('GetEvents', [UserInfo, PartyID, Range], _Opts) ->
ok = assert_party_accessible(UserInfo, PartyID),
#payproc_EventRange{'after' = AfterID, limit = Limit} = Range,
get_public_history(UserInfo, PartyID, AfterID, Limit);
get_public_history(PartyID, AfterID, Limit);
handle_function('Block', [UserInfo, PartyID, Reason], _Opts) ->
call(PartyID, {block, Reason, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {block, Reason});
handle_function('Unblock', [UserInfo, PartyID, Reason], _Opts) ->
call(PartyID, {unblock, Reason, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {unblock, Reason});
handle_function('Suspend', [UserInfo, PartyID], _Opts) ->
call(PartyID, {suspend, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, suspend);
handle_function('Activate', [UserInfo, PartyID], _Opts) ->
call(PartyID, {activate, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, activate);
handle_function('CreateShop', [UserInfo, PartyID, Params], _Opts) ->
call(PartyID, {create_shop, Params, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {create_shop, Params});
handle_function('GetShop', [UserInfo, PartyID, ID], _Opts) ->
St = get_state(UserInfo, PartyID),
ok = assert_party_accessible(UserInfo, PartyID),
St = get_state(PartyID),
get_shop(ID, get_party(St));
handle_function('UpdateShop', [UserInfo, PartyID, ID, Update], _Opts) ->
call(PartyID, {update_shop, ID, Update, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {update_shop, ID, Update});
handle_function('BlockShop', [UserInfo, PartyID, ID, Reason], _Opts) ->
call(PartyID, {block_shop, ID, Reason, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {block_shop, ID, Reason});
handle_function('UnblockShop', [UserInfo, PartyID, ID, Reason], _Opts) ->
call(PartyID, {unblock_shop, ID, Reason, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {unblock_shop, ID, Reason});
handle_function('SuspendShop', [UserInfo, PartyID, ID], _Opts) ->
call(PartyID, {suspend_shop, ID, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {suspend_shop, ID});
handle_function('ActivateShop', [UserInfo, PartyID, ID], _Opts) ->
call(PartyID, {activate_shop, ID, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {activate_shop, ID});
handle_function('GetClaim', [UserInfo, PartyID, ID], _Opts) ->
St = get_state(UserInfo, PartyID),
ok = assert_party_accessible(UserInfo, PartyID),
St = get_state(PartyID),
get_claim(ID, St);
handle_function('GetPendingClaim', [UserInfo, PartyID], _Opts) ->
St = get_state(UserInfo, PartyID),
ok = assert_party_accessible(UserInfo, PartyID),
St = get_state(PartyID),
ensure_claim(get_pending_claim(St));
handle_function('AcceptClaim', [UserInfo, PartyID, ID], _Opts) ->
call(PartyID, {accept_claim, ID, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {accept_claim, ID});
handle_function('DenyClaim', [UserInfo, PartyID, ID, Reason], _Opts) ->
call(PartyID, {deny_claim, ID, Reason, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {deny_claim, ID, Reason});
handle_function('RevokeClaim', [UserInfo, PartyID, ID, Reason], _Opts) ->
call(PartyID, {revoke_claim, ID, Reason, UserInfo});
ok = assert_party_accessible(UserInfo, PartyID),
call(PartyID, {revoke_claim, ID, Reason});
handle_function('GetAccountState', [UserInfo, PartyID, AccountID], _Opts) ->
St = get_state(UserInfo, PartyID),
ok = assert_party_accessible(UserInfo, PartyID),
St = get_state(PartyID),
get_account_state(AccountID, St);
handle_function('GetShopAccount', [UserInfo, PartyID, ShopID], _Opts) ->
St = get_state(UserInfo, PartyID),
ok = assert_party_accessible(UserInfo, PartyID),
St = get_state(PartyID),
get_shop_account(ShopID, St).
get_history(PartyID) ->
@ -163,7 +189,7 @@ get_history(PartyID) ->
get_history(PartyID, AfterID, Limit) ->
map_history_error(hg_machine:get_history(?NS, PartyID, AfterID, Limit)).
get_state(_UserInfo, PartyID) ->
get_state(PartyID) ->
{History, _LastID} = get_history(PartyID),
collapse_history(assert_nonempty_history(History)).
@ -174,15 +200,23 @@ assert_nonempty_history([_ | _] = Result) ->
assert_nonempty_history([]) ->
throw(#payproc_PartyNotFound{}).
get_public_history(_UserInfo, PartyID, AfterID, Limit) ->
assert_party_accessible(UserInfo, PartyID) ->
case hg_access_control:check_user_info(UserInfo, PartyID) of
ok ->
ok;
invalid_user ->
throw(#payproc_InvalidUser{})
end.
get_public_history(PartyID, AfterID, Limit) ->
hg_history:get_public_history(
fun (ID, Lim) -> get_history(PartyID, ID, Lim) end,
fun (Event) -> publish_party_event({party, PartyID}, Event) end,
AfterID, Limit
).
start(ID, Args) ->
map_start_error(hg_machine:start(?NS, ID, Args)).
start(ID) ->
map_start_error(hg_machine:start(?NS, ID, {})).
call(ID, Args) ->
map_error(hg_machine:call(?NS, {id, ID}, Args)).
@ -190,12 +224,12 @@ call(ID, Args) ->
map_start_error({ok, _}) ->
ok;
map_start_error({error, exists}) ->
hg_woody_wrapper:raise(#payproc_PartyExists{}).
throw(#payproc_PartyExists{}).
map_history_error({ok, Result}) ->
Result;
map_history_error({error, notfound}) ->
hg_woody_wrapper:raise(#payproc_PartyNotFound{});
throw(#payproc_PartyNotFound{});
map_history_error({error, Reason}) ->
error(Reason).
@ -207,7 +241,7 @@ map_error({ok, CallResult}) ->
throw(Reason)
end;
map_error({error, notfound}) ->
hg_woody_wrapper:raise(#payproc_PartyNotFound{});
throw(#payproc_PartyNotFound{});
map_error({error, Reason}) ->
error(Reason).
@ -260,10 +294,10 @@ publish_event(_InvoiceID, _) ->
namespace() ->
?NS.
-spec init(party_id(), {user_info()}) ->
-spec init(party_id(), {}) ->
hg_machine:result(ev()).
init(ID, {_UserInfo}) ->
init(ID, {}) ->
{ok, StEvents} = create_party(ID, {#st{}, []}),
Revision = hg_domain:head(),
TestContractTemplpate = get_test_template(Revision),
@ -306,7 +340,7 @@ process_signal({repair, _}, _History) ->
ok().
-type call() ::
{suspend | activate, user_info()}.
{suspend | activate}.
-type response() ::
ok | {ok, term()} | {exception, term()}.
@ -328,35 +362,35 @@ process_call(Call, History) ->
raise(What) ->
throw({exception, What}).
handle_call({block, Reason, _UserInfo}, StEvents0) ->
handle_call({block, Reason}, StEvents0) ->
ok = assert_unblocked(StEvents0),
{ClaimID, StEvents1} = create_claim([{blocking, ?blocked(Reason)}], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({unblock, Reason, _UserInfo}, StEvents0) ->
handle_call({unblock, Reason}, StEvents0) ->
ok = assert_blocked(StEvents0),
{ClaimID, StEvents1} = create_claim([{blocking, ?unblocked(Reason)}], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({suspend, _UserInfo}, StEvents0) ->
handle_call(suspend, StEvents0) ->
ok = assert_unblocked(StEvents0),
ok = assert_active(StEvents0),
{ClaimID, StEvents1} = create_claim([{suspension, ?suspended()}], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({activate, _UserInfo}, StEvents0) ->
handle_call(activate, StEvents0) ->
ok = assert_unblocked(StEvents0),
ok = assert_suspended(StEvents0),
{ClaimID, StEvents1} = create_claim([{suspension, ?active()}], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({create_contract, ContractParams, _UserInfo}, StEvents0) ->
handle_call({create_contract, ContractParams}, StEvents0) ->
ok = assert_operable(StEvents0),
Changeset = create_contract(ContractParams, StEvents0),
{ClaimID, StEvents1} = create_claim(Changeset, StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({terminate_contract, ID, Reason, _UserInfo}, StEvents0 = {St, _}) ->
handle_call({terminate_contract, ID, Reason}, StEvents0 = {St, _}) ->
ok = assert_operable(StEvents0),
Contract = get_contract(ID, get_party(St)),
ok = assert_contract_active(Contract, hg_datetime:format_now()),
@ -364,7 +398,7 @@ handle_call({terminate_contract, ID, Reason, _UserInfo}, StEvents0 = {St, _}) ->
{ClaimID, StEvents1} = create_claim([?contract_termination(ID, TerminatedAt, Reason)], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({create_contract_adjustment, ID, Params, _UserInfo}, StEvents0 = {St, _}) ->
handle_call({create_contract_adjustment, ID, Params}, StEvents0 = {St, _}) ->
ok = assert_operable(StEvents0),
Contract = get_contract(ID, get_party(St)),
ok = assert_contract_active(Contract, hg_datetime:format_now()),
@ -372,56 +406,56 @@ handle_call({create_contract_adjustment, ID, Params, _UserInfo}, StEvents0 = {St
{ClaimID, StEvents1} = create_claim(Changeset, StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({create_payout_account, Params, _UserInfo}, StEvents0) ->
handle_call({create_payout_account, Params}, StEvents0) ->
ok = assert_operable(StEvents0),
Changeset = create_payout_account(Params, StEvents0),
{ClaimID, StEvents1} = create_claim(Changeset, StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({create_shop, Params, _UserInfo}, StEvents0) ->
handle_call({create_shop, Params}, StEvents0) ->
ok = assert_operable(StEvents0),
Revision = hg_domain:head(),
Changeset = create_shop(Params, Revision, StEvents0),
{ClaimID, StEvents1} = create_claim(Changeset, StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({update_shop, ID, Update, _UserInfo}, StEvents0) ->
handle_call({update_shop, ID, Update}, StEvents0) ->
ok = assert_operable(StEvents0),
ok = assert_shop_modification_allowed(ID, StEvents0),
{ClaimID, StEvents1} = create_claim([?shop_modification(ID, {update, Update})], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({block_shop, ID, Reason, _UserInfo}, StEvents0) ->
handle_call({block_shop, ID, Reason}, StEvents0) ->
ok = assert_shop_unblocked(ID, StEvents0),
{ClaimID, StEvents1} = create_claim([?shop_modification(ID, {blocking, ?blocked(Reason)})], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({unblock_shop, ID, Reason, _UserInfo}, StEvents0) ->
handle_call({unblock_shop, ID, Reason}, StEvents0) ->
ok = assert_shop_blocked(ID, StEvents0),
{ClaimID, StEvents1} = create_claim([?shop_modification(ID, {blocking, ?unblocked(Reason)})], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({suspend_shop, ID, _UserInfo}, StEvents0) ->
handle_call({suspend_shop, ID}, StEvents0) ->
ok = assert_shop_unblocked(ID, StEvents0),
ok = assert_shop_active(ID, StEvents0),
{ClaimID, StEvents1} = create_claim([?shop_modification(ID, {suspension, ?suspended()})], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({activate_shop, ID, _UserInfo}, StEvents0) ->
handle_call({activate_shop, ID}, StEvents0) ->
ok = assert_shop_unblocked(ID, StEvents0),
ok = assert_shop_suspended(ID, StEvents0),
{ClaimID, StEvents1} = create_claim([?shop_modification(ID, {suspension, ?active()})], StEvents0),
respond(get_claim_result(ClaimID, StEvents1), StEvents1);
handle_call({accept_claim, ID, _UserInfo}, StEvents0) ->
handle_call({accept_claim, ID}, StEvents0) ->
{ID, StEvents1} = accept_claim(ID, StEvents0),
respond(ok, StEvents1);
handle_call({deny_claim, ID, Reason, _UserInfo}, StEvents0) ->
handle_call({deny_claim, ID, Reason}, StEvents0) ->
{ID, StEvents1} = finalize_claim(ID, ?denied(Reason), StEvents0),
respond(ok, StEvents1);
handle_call({revoke_claim, ID, Reason, _UserInfo}, StEvents0) ->
handle_call({revoke_claim, ID, Reason}, StEvents0) ->
ok = assert_operable(StEvents0),
{ID, StEvents1} = finalize_claim(ID, ?revoked(Reason), StEvents0),
respond(ok, StEvents1).
@ -921,7 +955,7 @@ get_contract(ID, #domain_Party{contracts = Contracts}) ->
#domain_Contract{} ->
Contract;
undefined ->
hg_woody_wrapper:raise(#payproc_ContractNotFound{})
throw(#payproc_ContractNotFound{})
end.
set_contract(Contract = #domain_Contract{id = ID}, Party = #domain_Party{contracts = Contracts}) ->
@ -936,14 +970,14 @@ set_shop(Shop = #domain_Shop{id = ID}, Party = #domain_Party{shops = Shops}) ->
ensure_shop(Shop = #domain_Shop{}) ->
Shop;
ensure_shop(undefined) ->
hg_woody_wrapper:raise(#payproc_ShopNotFound{}).
throw(#payproc_ShopNotFound{}).
get_shop_account(ShopID, St = #st{}) ->
Shop = get_shop(ShopID, get_party(St)),
get_shop_account(Shop).
get_shop_account(#domain_Shop{account = undefined}) ->
hg_woody_wrapper:raise(#payproc_ShopAccountNotFound{});
throw(#payproc_ShopAccountNotFound{});
get_shop_account(#domain_Shop{account = Account}) ->
Account.
@ -971,7 +1005,7 @@ ensure_account(AccountID, #domain_Party{shops = Shops}) ->
#domain_ShopAccount{} ->
ok;
undefined ->
hg_woody_wrapper:raise(#payproc_AccountNotFound{})
throw(#payproc_AccountNotFound{})
end.
find_shop_account(_ID, []) ->
@ -1006,7 +1040,7 @@ set_claim(Claim = #payproc_Claim{id = ID}, St = #st{claims = Claims}) ->
ensure_claim(Claim = #payproc_Claim{}) ->
Claim;
ensure_claim(undefined) ->
hg_woody_wrapper:raise(#payproc_ClaimNotFound{}).
throw(#payproc_ClaimNotFound{}).
apply_accepted_claim(Claim = #payproc_Claim{status = ?accepted(AcceptedAt)}, St) ->
apply_claim(Claim, St#st{revision = AcceptedAt});

View File

@ -55,6 +55,8 @@
-export([consistent_history/1]).
-export([party_access_control/1]).
%%
-define(c(Key, C), begin element(2, lists:keyfind(Key, 1, C)) end).
@ -69,6 +71,7 @@
all() ->
[
{group, party_access_control},
{group, party_creation},
{group, party_revisioning},
{group, party_blocking_suspension},
@ -90,6 +93,10 @@ groups() ->
party_already_exists,
party_retrieval
]},
{party_access_control, [sequence], [
party_creation,
party_access_control
]},
{party_revisioning, [sequence], [
party_creation,
party_revisioning
@ -178,7 +185,6 @@ end_per_suite(C) ->
init_per_group(shop_blocking_suspension, C) ->
C;
init_per_group(Group, C) ->
PartyID = list_to_binary(lists:concat([Group, ".", erlang:system_time()])),
Client = hg_client_party:start(make_userinfo(PartyID), PartyID, hg_client_api:new(?c(root_url, C))),
@ -207,6 +213,8 @@ end_per_testcase(_Name, _C) ->
-define(shop_w_status(ID, Blocking, Suspension),
#domain_Shop{id = ID, blocking = Blocking, suspension = Suspension}).
-define(invalid_user(),
{exception, #payproc_InvalidUser{}}).
-define(party_not_found(),
{exception, #payproc_PartyNotFound{}}).
-define(party_exists(),
@ -283,6 +291,7 @@ end_per_testcase(_Name, _C) ->
-spec shop_already_active(config()) -> _ | no_return().
-spec shop_account_set_retrieval(config()) -> _ | no_return().
-spec shop_account_retrieval(config()) -> _ | no_return().
-spec party_access_control(config()) -> _ | no_return().
party_creation(C) ->
Client = ?c(client, C),
@ -620,6 +629,42 @@ shop_account_retrieval(C) ->
{shop_account_set_retrieval, #domain_ShopAccount{guarantee = AccountID}} = ?config(saved_config, C),
#payproc_AccountState{account_id = AccountID} = hg_client_party:get_account_state(AccountID, Client).
%% Access control tests
party_access_control(C) ->
PartyID = ?c(party_id, C),
% External Success
GoodExternalClient = ?c(client, C),
#domain_Party{id = PartyID} = hg_client_party:get(GoodExternalClient),
% External Reject
BadExternalClient = hg_client_party:start(
#payproc_UserInfo{id = <<"FakE1D">>, type = {external_user, #payproc_ExternalUser{}}},
PartyID,
hg_client_api:new(?c(root_url, C))
),
?invalid_user() = hg_client_party:get(BadExternalClient),
hg_client_party:stop(BadExternalClient),
% Internal Success
GoodInternalClient = hg_client_party:start(
#payproc_UserInfo{id = <<"F4KE1D">>, type = {internal_user, #payproc_InternalUser{}}},
PartyID,
hg_client_api:new(?c(root_url, C))
),
#domain_Party{id = PartyID} = hg_client_party:get(GoodInternalClient),
hg_client_party:stop(GoodInternalClient),
% Service Success
GoodServiceClient = hg_client_party:start(
#payproc_UserInfo{id = <<"fAkE1D">>, type = {service_user, #payproc_ServiceUser{}}},
PartyID,
hg_client_api:new(?c(root_url, C))
),
#domain_Party{id = PartyID} = hg_client_party:get(GoodServiceClient),
hg_client_party:stop(GoodServiceClient),
ok.
get_last_shop(Client) ->
#domain_Party{shops = Shops} = hg_client_party:get(Client),
ShopID = lists:last(lists:sort(maps:keys(Shops))),

View File

@ -30,7 +30,7 @@ handle_function(Func, Args, Context, #{handler := Handler} = Opts) ->
{ok, Result}
catch
throw:Reason ->
woody_error:raise(business, Reason)
raise(Reason)
after
hg_context:cleanup()
end.