diff options
Diffstat (limited to 'deps/rabbit/src/internal_user.erl')
-rw-r--r-- | deps/rabbit/src/internal_user.erl | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/deps/rabbit/src/internal_user.erl b/deps/rabbit/src/internal_user.erl new file mode 100644 index 0000000000..b2bdcb6785 --- /dev/null +++ b/deps/rabbit/src/internal_user.erl @@ -0,0 +1,216 @@ +%% This Source Code Form is subject to the terms of the Mozilla Public +%% License, v. 2.0. If a copy of the MPL was not distributed with this +%% file, You can obtain one at https://mozilla.org/MPL/2.0/. +%% +%% Copyright (c) 2020 VMware, Inc. or its affiliates. All rights reserved. +%% + +-module(internal_user). + +-include_lib("rabbit_common/include/rabbit.hrl"). + +-export([ + new/0, + new/1, + record_version_to_use/0, + fields/0, + fields/1, + upgrade/1, + upgrade_to/2, + pattern_match_all/0, + get_username/1, + get_password_hash/1, + get_tags/1, + get_hashing_algorithm/1, + get_limits/1, + create_user/3, + set_password_hash/3, + set_tags/2, + update_limits/3, + clear_limits/1 +]). + +-define(record_version, internal_user_v2). + +-type(username() :: binary()). + +-type(password_hash() :: binary()). + +-type internal_user() :: internal_user_v1:internal_user_v1() | internal_user_v2(). + +-record(internal_user, { + username :: username() | '_', + password_hash :: password_hash() | '_', + tags :: [atom()] | '_', + %% password hashing implementation module, + %% typically rabbit_password_hashing_* but can + %% come from a plugin + hashing_algorithm :: atom() | '_', + limits = #{} :: map() | '_'}). + +-type(internal_user_v2() :: + #internal_user{username :: username() | '_', + password_hash :: password_hash() | '_', + tags :: [atom()] | '_', + hashing_algorithm :: atom() | '_', + limits :: map()}). + +-type internal_user_pattern() :: internal_user_v1:internal_user_v1_pattern() | + internal_user_v2_pattern(). + +-type internal_user_v2_pattern() :: #internal_user{ + username :: username() | '_', + password_hash :: '_', + tags :: '_', + hashing_algorithm :: '_', + limits :: '_' + }. + +-export_type([username/0, + password_hash/0, + internal_user/0, + internal_user_v2/0, + internal_user_pattern/0, + internal_user_v2_pattern/0]). + +-spec new() -> internal_user(). +new() -> + case record_version_to_use() of + ?record_version -> + #internal_user{ + username = <<"">>, + password_hash = <<"">>, + tags = [] + }; + _ -> + internal_user_v1:new() + end. + +-spec new(tuple()) -> internal_user(). +new({hashing_algorithm, HashingAlgorithm}) -> + case record_version_to_use() of + ?record_version -> + #internal_user{ + username = <<"">>, + password_hash = <<"">>, + tags = [], + hashing_algorithm = HashingAlgorithm + }; + _ -> + internal_user_v1:new({hashing_algorithm, HashingAlgorithm}) + end; +new({tags, Tags}) -> + case record_version_to_use() of + ?record_version -> + #internal_user{ + username = <<"">>, + password_hash = <<"">>, + tags = Tags + }; + _ -> + internal_user_v1:new({tags, Tags}) + end. + +-spec record_version_to_use() -> internal_user_v1 | internal_user_v2. +record_version_to_use() -> + case rabbit_feature_flags:is_enabled(user_limits) of + true -> ?record_version; + false -> internal_user_v1:record_version_to_use() + end. + +-spec fields() -> list(). +fields() -> + case record_version_to_use() of + ?record_version -> fields(?record_version); + _ -> internal_user_v1:fields() + end. + +-spec fields(atom()) -> list(). +fields(?record_version) -> record_info(fields, internal_user); +fields(Version) -> internal_user_v1:fields(Version). + +-spec upgrade(internal_user()) -> internal_user(). +upgrade(#internal_user{} = User) -> User; +upgrade(OldUser) -> upgrade_to(record_version_to_use(), OldUser). + +-spec upgrade_to +(internal_user_v2, internal_user()) -> internal_user_v2(); +(internal_user_v1, internal_user_v1:internal_user_v1()) -> internal_user_v1:internal_user_v1(). + +upgrade_to(?record_version, #internal_user{} = User) -> + User; +upgrade_to(?record_version, OldUser) -> + Fields = erlang:tuple_to_list(OldUser) ++ [#{}], + #internal_user{} = erlang:list_to_tuple(Fields); +upgrade_to(Version, OldUser) -> + internal_user_v1:upgrade_to(Version, OldUser). + +-spec pattern_match_all() -> internal_user_pattern(). +pattern_match_all() -> + case record_version_to_use() of + ?record_version -> #internal_user{_ = '_'}; + _ -> internal_user_v1:pattern_match_all() + end. + +-spec get_username(internal_user()) -> username(). +get_username(#internal_user{username = Value}) -> Value; +get_username(User) -> internal_user_v1:get_username(User). + +-spec get_password_hash(internal_user()) -> password_hash(). +get_password_hash(#internal_user{password_hash = Value}) -> Value; +get_password_hash(User) -> internal_user_v1:get_password_hash(User). + +-spec get_tags(internal_user()) -> [atom()]. +get_tags(#internal_user{tags = Value}) -> Value; +get_tags(User) -> internal_user_v1:get_tags(User). + +-spec get_hashing_algorithm(internal_user()) -> atom(). +get_hashing_algorithm(#internal_user{hashing_algorithm = Value}) -> Value; +get_hashing_algorithm(User) -> internal_user_v1:get_hashing_algorithm(User). + +-spec get_limits(internal_user()) -> map(). +get_limits(#internal_user{limits = Value}) -> Value; +get_limits(User) -> internal_user_v1:get_limits(User). + +-spec create_user(username(), password_hash(), atom()) -> internal_user(). +create_user(Username, PasswordHash, HashingMod) -> + case record_version_to_use() of + ?record_version -> + #internal_user{username = Username, + password_hash = PasswordHash, + tags = [], + hashing_algorithm = HashingMod, + limits = #{} + }; + _ -> + internal_user_v1:create_user(Username, PasswordHash, HashingMod) + end. + +-spec set_password_hash(internal_user(), password_hash(), atom()) -> internal_user(). +set_password_hash(#internal_user{} = User, PasswordHash, HashingAlgorithm) -> + User#internal_user{password_hash = PasswordHash, + hashing_algorithm = HashingAlgorithm}; +set_password_hash(User, PasswordHash, HashingAlgorithm) -> + internal_user_v1:set_password_hash(User, PasswordHash, HashingAlgorithm). + +-spec set_tags(internal_user(), [atom()]) -> internal_user(). +set_tags(#internal_user{} = User, Tags) -> + User#internal_user{tags = Tags}; +set_tags(User, Tags) -> + internal_user_v1:set_tags(User, Tags). + +-spec update_limits +(add, internal_user(), map()) -> internal_user(); +(remove, internal_user(), term()) -> internal_user(). +update_limits(add, #internal_user{limits = Limits} = User, Term) -> + User#internal_user{limits = maps:merge(Limits, Term)}; +update_limits(remove, #internal_user{limits = Limits} = User, LimitType) -> + User#internal_user{limits = maps:remove(LimitType, Limits)}; +update_limits(Action, User, Term) -> + internal_user_v1:update_limits(Action, User, Term). + +-spec clear_limits(internal_user()) -> internal_user(). +clear_limits(#internal_user{} = User) -> + User#internal_user{limits = #{}}; +clear_limits(User) -> + internal_user_v1:clear_limits(User). |