diff --git a/whistle_apps/apps/crossbar/include/crossbar.hrl b/whistle_apps/apps/crossbar/include/crossbar.hrl index 13f4f90a391..4cb210e87ba 100644 --- a/whistle_apps/apps/crossbar/include/crossbar.hrl +++ b/whistle_apps/apps/crossbar/include/crossbar.hrl @@ -68,7 +68,7 @@ ,port = 8000 :: integer() ,raw_path = <<>> :: binary() ,raw_qs = <<>> :: binary() - ,method = 'GET' :: http_methods() + ,method = 'GET' :: http_method() }). -ifdef(PROFILE). diff --git a/whistle_apps/apps/crossbar/include/crossbar_types.hrl b/whistle_apps/apps/crossbar/include/crossbar_types.hrl index e84cd33d28d..48f34216bad 100644 --- a/whistle_apps/apps/crossbar/include/crossbar_types.hrl +++ b/whistle_apps/apps/crossbar/include/crossbar_types.hrl @@ -16,7 +16,7 @@ -type crossbar_content_handler() :: {atom(), [{ne_binary(), ne_binary()},...]}. -type crossbar_content_handlers() :: [crossbar_content_handler(),...] | []. --type http_method() :: 'POST' | 'GET' | 'PUT' | 'DELETE'. +-type http_method() :: 'POST' | 'GET' | 'PUT' | 'DELETE' | 'PATCH'. -type http_methods() :: [http_method()]. -type validator() :: 'required' | 'not_empty' | 'is_type' | 'is_format' | 'numeric_min' | 'numeric_max' | 'numeric_between' | 'width'. diff --git a/whistle_apps/apps/crossbar/src/modules/cb_accounts.erl b/whistle_apps/apps/crossbar/src/modules/cb_accounts.erl index 42b9f5663d9..e28fa87c7a7 100644 --- a/whistle_apps/apps/crossbar/src/modules/cb_accounts.erl +++ b/whistle_apps/apps/crossbar/src/modules/cb_accounts.erl @@ -62,16 +62,17 @@ ensure_parent_set() -> {ok, AcctJObjs} -> DefaultParentID = find_default_parent(AcctJObjs), - [ensure_parent_set(DefaultParentID, wh_json:get_value(<<"doc">>, AcctJObj)) - || AcctJObj <- AcctJObjs, - wh_json:get_value(<<"id">>, AcctJObj) =/= DefaultParentID, % not the default parent - - (Tree = wh_json:get_value([<<"doc">>, <<"pvt_tree">>], AcctJObj)) =:= [] orelse % empty tree (should have at least the parent) - Tree =:= <<>> orelse % Tree is an empty string only - Tree =:= [""] orelse % Tree is bound in the prior bit, and might be a list of an empty string - Tree =:= [<<>>] orelse % Tree is a list of an empty string - Tree =:= undefined % if the pvt_tree key doesn't exist - ]; + _ = [ensure_parent_set(DefaultParentID, wh_json:get_value(<<"doc">>, AcctJObj)) + || AcctJObj <- AcctJObjs, + wh_json:get_value(<<"id">>, AcctJObj) =/= DefaultParentID, % not the default parent + + (Tree = wh_json:get_value([<<"doc">>, <<"pvt_tree">>], AcctJObj)) =:= [] orelse % empty tree (should have at least the parent) + Tree =:= <<>> orelse % Tree is an empty string only + Tree =:= [""] orelse % Tree is bound in the prior bit, and might be a list of an empty string + Tree =:= [<<>>] orelse % Tree is a list of an empty string + Tree =:= undefined % if the pvt_tree key doesn't exist + ], + ok; {error, _}=E -> E end. diff --git a/whistle_apps/apps/crossbar/src/modules/cb_acls.erl b/whistle_apps/apps/crossbar/src/modules/cb_acls.erl index 38b7ee0319d..4b665d144e1 100644 --- a/whistle_apps/apps/crossbar/src/modules/cb_acls.erl +++ b/whistle_apps/apps/crossbar/src/modules/cb_acls.erl @@ -66,8 +66,8 @@ allowed_methods(_) -> %% /acls/foo/bar => [<<"foo">>, <<"bar">>] %% @end %%-------------------------------------------------------------------- --spec resource_exists/0 :: () -> boolean(). --spec resource_exists/1 :: (path_tokens()) -> boolean(). +-spec resource_exists/0 :: () -> 'true'. +-spec resource_exists/1 :: (path_tokens()) -> 'true'. resource_exists() -> true. resource_exists(_) -> true. diff --git a/whistle_apps/apps/crossbar/src/modules/cb_api_auth.erl b/whistle_apps/apps/crossbar/src/modules/cb_api_auth.erl index a7f6e3b6c0a..3149c37eecc 100644 --- a/whistle_apps/apps/crossbar/src/modules/cb_api_auth.erl +++ b/whistle_apps/apps/crossbar/src/modules/cb_api_auth.erl @@ -99,7 +99,7 @@ validate(#cb_context{req_data=Data, req_verb = <<"put">>}=Context) -> {fail, Errors} -> crossbar_util:response_invalid_data(Errors, Context); {pass, JObj} -> - crossbar_util:put_reqid(Context), + _ = crossbar_util:put_reqid(Context), authorize_api_key(Context, wh_json:get_value(<<"api_key">>, JObj)) end. @@ -109,7 +109,7 @@ validate(#cb_context{req_data=Data, req_verb = <<"put">>}=Context) -> %% @end %%-------------------------------------------------------------------- put(Context) -> - crossbar_util:put_reqid(Context), + _ = crossbar_util:put_reqid(Context), create_token(Context). %%%=================================================================== diff --git a/whistle_apps/apps/crossbar/src/modules/cb_braintree.erl b/whistle_apps/apps/crossbar/src/modules/cb_braintree.erl index 8fc24877700..c086f9f452b 100644 --- a/whistle_apps/apps/crossbar/src/modules/cb_braintree.erl +++ b/whistle_apps/apps/crossbar/src/modules/cb_braintree.erl @@ -30,11 +30,14 @@ -define(TRANSACTIONS_PATH_TOKEN, <<"transactions">>). -define(CREDITS_PATH_TOKEN, <<"credits">>). +-type subscription_update() :: {string(), pos_integer()}. +-type subscription_updates() :: [subscription_update(),...] | []. + %%%=================================================================== %%% API %%%=================================================================== init() -> - ssl:start(), + _ = ssl:start(), _ = crossbar_bindings:bind(<<"v1_resource.billing">>, ?MODULE, billing), _ = crossbar_bindings:bind(<<"v1_resource.allowed_methods.braintree">>, ?MODULE, allowed_methods), _ = crossbar_bindings:bind(<<"v1_resource.resource_exists.braintree">>, ?MODULE, resource_exists), @@ -128,13 +131,13 @@ validate(#cb_context{req_verb = <<"get">>, account_id=AccountId}=Context, ?CUSTO case braintree_customer:find(AccountId) of {ok, #bt_customer{}=C} -> Resp = braintree_customer:record_to_json(C), - disable_cardless_accounts(wh_json:get_value(<<"credit_cards">>, Resp, []), Context), + _ = disable_cardless_accounts(wh_json:get_value(<<"credit_cards">>, Resp, []), Context), crossbar_util:response(Resp, Context); {error, #bt_api_error{}=ApiError} -> Resp = braintree_util:bt_api_error_to_json(ApiError), crossbar_util:response(error, <<"braintree api error">>, 400, Resp, Context); {error, not_found} -> - disable_cardless_accounts([], Context), + _ = disable_cardless_accounts([], Context), create_placeholder_account(Context); {error, _} -> crossbar_util:response_db_fatal(Context) @@ -160,7 +163,7 @@ validate(#cb_context{req_verb = <<"get">>, account_id=AccountId}=Context, ?CARDS case braintree_customer:find(AccountId) of {ok, #bt_customer{credit_cards=Cards}} -> Resp = [braintree_card:record_to_json(Card) || Card <- Cards], - disable_cardless_accounts(Resp, Context), + _ = disable_cardless_accounts(Resp, Context), crossbar_util:response(Resp, Context); {error, #bt_api_error{}=ApiError} -> Resp = braintree_util:bt_api_error_to_json(ApiError), @@ -284,12 +287,12 @@ validate(#cb_context{req_verb = <<"get">>}=Context, ?TRANSACTIONS_PATH_TOKEN, Tr post(#cb_context{account_id=AccountId}=Context, ?CUSTOMER_PATH_TOKEN) -> _ = crossbar_util:put_reqid(Context), Customer = crossbar_util:fetch(braintree, Context), - create_placeholder_account(Context), + _ = create_placeholder_account(Context), case braintree_customer:update(Customer) of {ok, #bt_customer{}=C} -> - crossbar_util:enable_account(AccountId), + _ = crossbar_util:enable_account(AccountId), Resp = braintree_customer:record_to_json(C), - disable_cardless_accounts(wh_json:get_value(<<"credit_cards">>, Resp, []), Context), + _ = disable_cardless_accounts(wh_json:get_value(<<"credit_cards">>, Resp, []), Context), crossbar_util:response(Resp, Context); {error, #bt_api_error{}=ApiError} -> Resp = braintree_util:bt_api_error_to_json(ApiError), @@ -305,7 +308,7 @@ post(Context, ?CARDS_PATH_TOKEN, CardId) -> case braintree_card:update(Card) of {ok, #bt_card{}=C} -> Resp = braintree_card:record_to_json(C), - disable_cardless_accounts(Resp, Context), + _ = disable_cardless_accounts(Resp, Context), crossbar_util:response(Resp, Context); {error, #bt_api_error{}=ApiError} -> Resp = braintree_util:bt_api_error_to_json(ApiError), @@ -381,7 +384,7 @@ put(Context, ?CARDS_PATH_TOKEN) -> case braintree_card:create(Card) of {ok, #bt_card{}=C} -> Resp = braintree_card:record_to_json(C), - disable_cardless_accounts(Resp, Context), + _ = disable_cardless_accounts(Resp, Context), crossbar_util:response(Resp, Context); {error, #bt_api_error{}=ApiError} -> Resp = braintree_util:bt_api_error_to_json(ApiError), @@ -397,7 +400,7 @@ delete(Context, ?CARDS_PATH_TOKEN, CardId) -> case braintree_card:delete(CardId) of {ok, #bt_card{}=C} -> Resp = braintree_card:record_to_json(C), - disable_cardless_accounts(Resp, Context), + _ = disable_cardless_accounts(Resp, Context), crossbar_util:response(Resp, Context); {error, #bt_api_error{}=ApiError} -> Resp = braintree_util:bt_api_error_to_json(ApiError), @@ -434,7 +437,7 @@ delete(Context, ?ADDRESSES_PATH_TOKEN, AddressId) -> %% disabling all decendants... BRING THE HAMMER %% @end %%-------------------------------------------------------------------- --spec disable_cardless_accounts/2 :: (list(), #cb_context{}) -> #cb_context{}. +-spec disable_cardless_accounts/2 :: (list(), #cb_context{}) -> 'ok' | {'error', _}. disable_cardless_accounts([], #cb_context{account_id=AccountId}) -> crossbar_util:disable_account(AccountId); disable_cardless_accounts(_, #cb_context{account_id=AccountId}) -> @@ -478,7 +481,8 @@ authorize_trunkstore([], #cb_context{req_verb = <<"put">>, doc=JObj, account_id= Updates = [{"outbound_us", fun() -> ts_outbound_us_quantity(JObj) end()} ,{"did_us", fun() -> ts_did_us_quantity(JObj) end()} ,{"tollfree_us", fun() -> ts_tollfree_us_quantity(JObj) end()} - ,{"e911", fun() -> ts_e911_quantity(JObj) end()}], + ,{"e911", fun() -> ts_e911_quantity(JObj) end()} + ], BillingAccount = wh_json:get_value(<<"billing_account_id">>, JObj, AccountId), case ts_get_subscription(JObj, BillingAccount) of {ok, Subscription} -> @@ -502,7 +506,8 @@ authorize_trunkstore([_], #cb_context{req_verb = <<"post">>, doc=JObj, account_i Updates = [{"outbound_us", fun() -> ts_outbound_us_quantity(JObj) end()} ,{"did_us", fun() -> ts_did_us_quantity(JObj) end()} ,{"tollfree_us", fun() -> ts_tollfree_us_quantity(JObj) end()} - ,{"e911", fun() -> ts_e911_quantity(JObj) end()}], + ,{"e911", fun() -> ts_e911_quantity(JObj) end()} + ], BillingAccount = wh_json:get_value(<<"billing_account_id">>, JObj, AccountId), case ts_get_subscription(JObj, BillingAccount) of {ok, Subscription} -> @@ -580,7 +585,7 @@ ts_e911_quantity(JObj) -> || Server <- wh_json:get_value(<<"servers">>, JObj, [])], length(E911). --spec ts_fold_did_fun/1 :: (boolean()) -> pos_integer(). +-spec ts_fold_did_fun/1 :: (boolean()) -> fun((pos_integer(), non_neg_integer()) -> non_neg_integer()). ts_fold_did_fun(true) -> fun(Number, Count) -> case wnm_util:is_tollfree(Number) of @@ -635,7 +640,7 @@ ts_get_subscription(JObj, BillingAccount, Create) -> {error, fatal} end. --spec change_subscription/3 :: (ne_binary(), #bt_subscription{}, #cb_context{}) -> #cb_context{}. +-spec change_subscription/3 :: (subscription_updates(), #bt_subscription{}, #cb_context{}) -> #cb_context{}. change_subscription(Updates, #bt_subscription{id=undefined}=Subscription, #cb_context{doc=JObj}=Context) -> NewSubscription = lists:foldr(fun({AddOn, Quantity}, Sub) -> @@ -685,17 +690,17 @@ change_subscription(Updates, Subscription, #cb_context{doc=JObj}=Context) -> {'error', atom()} | {'inactive', ne_binary()} | {'api_error', wh_json:json_object()} - ,ne_binary()) -> {'ok', #bt_subscription{}} | - {'error', atom()} | - {'inactive', ne_binary()} | - {'api_error', wh_json:json_object()}. + ,nonempty_string()) -> {'ok', #bt_subscription{}} | + {'error', atom()} | + {'inactive', ne_binary()} | + {'api_error', wh_json:json_object()}. create_subscription({ok, Token}, Plan) -> lager:debug("creating new subscription ~s with token ~s", [Plan, Token]), {ok, #bt_subscription{payment_token=Token, plan_id=Plan, do_not_inherit=true}}; create_subscription(Error, _) -> Error. --spec get_payment_token/1 :: (ne_binary() | list()) -> {'ok', ne_binary()} | +-spec get_payment_token/1 :: (ne_binary() | list()) -> {'ok', nonempty_string()} | {'error', atom()} | {'api_error', wh_json:json_object()}. get_payment_token(BillingAccount) when not is_list(BillingAccount) -> diff --git a/whistle_apps/apps/crossbar/src/modules/cb_registrations.erl b/whistle_apps/apps/crossbar/src/modules/cb_registrations.erl index 60effaece2e..d86a04b27c6 100644 --- a/whistle_apps/apps/crossbar/src/modules/cb_registrations.erl +++ b/whistle_apps/apps/crossbar/src/modules/cb_registrations.erl @@ -79,7 +79,7 @@ collect_registrar_responses(Registrations) -> 500 -> Registrations end. --spec accumulate_unique_registrations/2 :: (wh_json:objects(), proplist()) -> proplist(). +-spec accumulate_unique_registrations/2 :: (wh_json:json_objects(), proplist()) -> proplist(). accumulate_unique_registrations([], Accumulator) -> Accumulator; accumulate_unique_registrations([Registration|Registrations], Accumulator) ->