mirror of
https://github.com/valitydev/hellgate.git
synced 2024-11-06 10:55:22 +00:00
HG-129: primitive access control implemented (#59)
This commit is contained in:
parent
3af4a8bd0b
commit
70a3658beb
19
apps/hellgate/src/hg_access_control.erl
Normal file
19
apps/hellgate/src/hg_access_control.erl
Normal 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.
|
@ -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.
|
||||
|
||||
|
@ -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});
|
||||
|
@ -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))),
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user