diff options
author | Simon MacMullen <simon@rabbitmq.com> | 2010-12-14 15:03:44 +0000 |
---|---|---|
committer | Simon MacMullen <simon@rabbitmq.com> | 2010-12-14 15:03:44 +0000 |
commit | 2f43ffd37fc7fd8ecfdc2e421c6834740e080748 (patch) | |
tree | 21c7bf2e7832d280cc756b44150df3802999b156 /src | |
parent | 2376a52d1655385a9ae6f9656bcff4ca70d20ba2 (diff) | |
parent | 8d0f82119fb6b45f9dd0d0acebee4440e8bdf340 (diff) | |
download | rabbitmq-server-2f43ffd37fc7fd8ecfdc2e421c6834740e080748.tar.gz |
Merge from default
Diffstat (limited to 'src')
-rw-r--r-- | src/rabbit_access_control.erl | 169 | ||||
-rw-r--r-- | src/rabbit_auth_backend.erl | 48 | ||||
-rw-r--r-- | src/rabbit_auth_backend_internal.erl | 112 | ||||
-rw-r--r-- | src/rabbit_auth_mechanism_external.erl | 2 | ||||
-rw-r--r-- | src/rabbit_channel.erl | 30 | ||||
-rw-r--r-- | src/rabbit_channel_sup.erl | 4 | ||||
-rw-r--r-- | src/rabbit_mnesia.erl | 6 | ||||
-rw-r--r-- | src/rabbit_reader.erl | 4 | ||||
-rw-r--r-- | src/rabbit_registry.erl | 3 | ||||
-rw-r--r-- | src/rabbit_types.erl | 16 | ||||
-rw-r--r-- | src/rabbit_upgrade_functions.erl | 15 |
11 files changed, 300 insertions, 109 deletions
diff --git a/src/rabbit_access_control.erl b/src/rabbit_access_control.erl index 2bc946db..8c550e35 100644 --- a/src/rabbit_access_control.erl +++ b/src/rabbit_access_control.erl @@ -33,8 +33,9 @@ -include_lib("stdlib/include/qlc.hrl"). -include("rabbit.hrl"). --export([user_pass_login/2, check_user_pass_login/2, make_salt/0, - check_vhost_access/2, check_resource_access/3]). +-export([user_pass_login/2, check_user_pass_login/2, check_user_login/2, + make_salt/0, check_password/2, check_vhost_access/2, + check_resource_access/3, list_vhosts/1]). -export([add_user/2, delete_user/1, change_password/2, set_admin/1, clear_admin/1, list_users/0, lookup_user/1, clear_password/1]). -export([change_password_hash/2, hash_password/1]). @@ -47,7 +48,7 @@ -ifdef(use_specs). --export_type([username/0, password/0, password_hash/0]). +-export_type([username/0, password/0, password_hash/0, permission_atom/0]). -type(permission_atom() :: 'configure' | 'read' | 'write'). -type(username() :: binary()). @@ -61,11 +62,12 @@ (username(), password()) -> {'ok', rabbit_types:user()} | {'refused', string(), [any()]}). -spec(make_salt/0 :: () -> binary()). +-spec(check_password/2 :: (password(), password_hash()) -> boolean()). -spec(check_vhost_access/2 :: (rabbit_types:user(), rabbit_types:vhost()) -> 'ok' | rabbit_types:channel_exit()). -spec(check_resource_access/3 :: - (username(), rabbit_types:r(atom()), permission_atom()) + (rabbit_types:user(), rabbit_types:r(atom()), permission_atom()) -> 'ok' | rabbit_types:channel_exit()). -spec(add_user/2 :: (username(), password()) -> 'ok'). -spec(delete_user/1 :: (username()) -> 'ok'). @@ -77,7 +79,7 @@ -spec(clear_admin/1 :: (username()) -> 'ok'). -spec(list_users/0 :: () -> [{username(), boolean()}]). -spec(lookup_user/1 :: - (username()) -> rabbit_types:ok(rabbit_types:user()) + (username()) -> rabbit_types:ok(rabbit_types:internal_user()) | rabbit_types:error('not_found')). -spec(add_vhost/1 :: (rabbit_types:vhost()) -> 'ok'). -spec(delete_vhost/1 :: (rabbit_types:vhost()) -> 'ok'). @@ -109,88 +111,94 @@ user_pass_login(User, Pass) -> U end. -check_user_pass_login(Username, Pass) -> - Refused = {refused, "user '~s' - invalid credentials", [Username]}, - case lookup_user(Username) of - {ok, User} -> - case check_password(Pass, User#user.password_hash) of - true -> {ok, User}; - _ -> Refused - end; - {error, not_found} -> - Refused - end. - -internal_lookup_vhost_access(Username, VHostPath) -> - %% TODO: use dirty ops instead - rabbit_misc:execute_mnesia_transaction( - fun () -> - case mnesia:read({rabbit_user_permission, - #user_vhost{username = Username, - virtual_host = VHostPath}}) of - [] -> not_found; - [R] -> {ok, R} - end - end). - -check_vhost_access(#user{username = Username}, VHostPath) -> +check_user_pass_login(Username, Password) -> + check_user_login(Username, [{password, Password}]). + +check_user_login(Username, AuthProps) -> + {ok, Modules} = application:get_env(rabbit, auth_backends), + lists:foldl( + fun(Module, {refused, _, _}) -> + case Module:check_user_login(Username, AuthProps) of + {error, E} -> + {refused, "~s failed authenticating ~s: ~p~n", + [Module, Username, E]}; + Else -> + Else + end; + (_, {ok, User}) -> + {ok, User} + end, {refused, "No modules checked '~s'", [Username]}, Modules). + +check_vhost_access(User = #user{ username = Username, + auth_backend = Module }, VHostPath) -> ?LOGDEBUG("Checking VHost access for ~p to ~p~n", [Username, VHostPath]), - case internal_lookup_vhost_access(Username, VHostPath) of - {ok, _R} -> + check_access( + fun() -> + vhost_exists(VHostPath) andalso + Module:check_vhost_access(User, VHostPath, write) + end, + "~s failed checking vhost access to ~s for ~s: ~p~n", + [Module, VHostPath, Username], + "access to vhost '~s' refused for user '~s'", + [VHostPath, Username]). + +check_resource_access(User, R = #resource{kind = exchange, name = <<"">>}, + Permission) -> + check_resource_access(User, R#resource{name = <<"amq.default">>}, + Permission); +check_resource_access(User = #user{username = Username, auth_backend = Module}, + Resource, Permission) -> + check_access( + fun() -> Module:check_resource_access(User, Resource, Permission) end, + "~s failed checking resource access to ~p for ~s: ~p~n", + [Module, Resource, Username], + "access to ~s refused for user '~s'", + [rabbit_misc:rs(Resource), Username]). + +check_access(Fun, ErrStr, ErrArgs, RefStr, RefArgs) -> + Allow = case Fun() of + {error, _} = E -> + rabbit_log:error(ErrStr, ErrArgs ++ [E]), + false; + Else -> + Else + end, + case Allow of + true -> ok; - not_found -> - rabbit_misc:protocol_error( - access_refused, "access to vhost '~s' refused for user '~s'", - [VHostPath, Username]) + false -> + rabbit_misc:protocol_error(access_refused, RefStr, RefArgs) end. -permission_index(configure) -> #permission.configure; -permission_index(write) -> #permission.write; -permission_index(read) -> #permission.read. +list_vhosts(User = #user{username = Username, auth_backend = Module}) -> + lists:filter( + fun(VHost) -> + case Module:check_vhost_access(User, VHost, read) of + {error, _} = E -> + rabbit_log:warning("~w failed checking vhost access " + "to ~s for ~s: ~p~n", + [Module, VHost, Username, E]), + false; + Else -> + Else + end + end, list_vhosts()). -check_resource_access(Username, - R = #resource{kind = exchange, name = <<"">>}, - Permission) -> - check_resource_access(Username, - R#resource{name = <<"amq.default">>}, - Permission); -check_resource_access(Username, - R = #resource{virtual_host = VHostPath, name = Name}, - Permission) -> - Res = case mnesia:dirty_read({rabbit_user_permission, - #user_vhost{username = Username, - virtual_host = VHostPath}}) of - [] -> - false; - [#user_permission{permission = P}] -> - PermRegexp = - case element(permission_index(Permission), P) of - %% <<"^$">> breaks Emacs' erlang mode - <<"">> -> <<$^, $$>>; - RE -> RE - end, - case re:run(Name, PermRegexp, [{capture, none}]) of - match -> true; - nomatch -> false - end - end, - if Res -> ok; - true -> rabbit_misc:protocol_error( - access_refused, "access to ~s refused for user '~s'", - [rabbit_misc:rs(R), Username]) - end. +%% TODO move almost everything below this line to rabbit_auth_backend_internal +%%---------------------------------------------------------------------------- add_user(Username, Password) -> R = rabbit_misc:execute_mnesia_transaction( fun () -> case mnesia:wread({rabbit_user, Username}) of [] -> - ok = mnesia:write(rabbit_user, - #user{username = Username, - password_hash = - hash_password(Password), - is_admin = false}, - write); + ok = mnesia:write( + rabbit_user, + #internal_user{username = Username, + password_hash = + hash_password(Password), + is_admin = false}, + write); _ -> mnesia:abort({user_already_exists, Username}) end @@ -226,7 +234,8 @@ clear_password(Username) -> change_password_hash(Username, PasswordHash) -> R = update_user(Username, fun(User) -> - User#user{ password_hash = PasswordHash } + User#internal_user{ + password_hash = PasswordHash } end), rabbit_log:info("Changed password for user ~p~n", [Username]), R. @@ -257,7 +266,7 @@ clear_admin(Username) -> set_admin(Username, IsAdmin) -> R = update_user(Username, fun(User) -> - User#user{is_admin = IsAdmin} + User#internal_user{is_admin = IsAdmin} end), rabbit_log:info("Set user admin flag for user ~p to ~p~n", [Username, IsAdmin]), @@ -274,8 +283,8 @@ update_user(Username, Fun) -> list_users() -> [{Username, IsAdmin} || - #user{username = Username, is_admin = IsAdmin} <- - mnesia:dirty_match_object(rabbit_user, #user{_ = '_'})]. + #internal_user{username = Username, is_admin = IsAdmin} <- + mnesia:dirty_match_object(rabbit_user, #internal_user{_ = '_'})]. lookup_user(Username) -> rabbit_misc:dirty_read({rabbit_user, Username}). diff --git a/src/rabbit_auth_backend.erl b/src/rabbit_auth_backend.erl new file mode 100644 index 00000000..18f32873 --- /dev/null +++ b/src/rabbit_auth_backend.erl @@ -0,0 +1,48 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License at +%% http://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +%% License for the specific language governing rights and limitations +%% under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developers of the Original Code are LShift Ltd, +%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd. +%% +%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, +%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd +%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial +%% Technologies LLC, and Rabbit Technologies Ltd. +%% +%% Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift +%% Ltd. Portions created by Cohesive Financial Technologies LLC are +%% Copyright (C) 2007-2010 Cohesive Financial Technologies +%% LLC. Portions created by Rabbit Technologies Ltd are Copyright +%% (C) 2007-2010 Rabbit Technologies Ltd. +%% +%% All Rights Reserved. +%% +%% Contributor(s): ______________________________________. +%% + +-module(rabbit_auth_backend). + +-export([behaviour_info/1]). + +behaviour_info(callbacks) -> + [ + %% A description (TODO should this be here if we're not using registry?). + {description, 0}, + + {check_user_login, 2}, + + {check_vhost_access, 3}, + + {check_resource_access, 3} + ]; +behaviour_info(_Other) -> + undefined. diff --git a/src/rabbit_auth_backend_internal.erl b/src/rabbit_auth_backend_internal.erl new file mode 100644 index 00000000..df5a0ace --- /dev/null +++ b/src/rabbit_auth_backend_internal.erl @@ -0,0 +1,112 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License at +%% http://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +%% License for the specific language governing rights and limitations +%% under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developers of the Original Code are LShift Ltd, +%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd. +%% +%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, +%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd +%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial +%% Technologies LLC, and Rabbit Technologies Ltd. +%% +%% Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift +%% Ltd. Portions created by Cohesive Financial Technologies LLC are +%% Copyright (C) 2007-2010 Cohesive Financial Technologies +%% LLC. Portions created by Rabbit Technologies Ltd are Copyright +%% (C) 2007-2010 Rabbit Technologies Ltd. +%% +%% All Rights Reserved. +%% +%% Contributor(s): ______________________________________. +%% + +-module(rabbit_auth_backend_internal). +-include("rabbit.hrl"). + +-behaviour(rabbit_auth_backend). + +-export([description/0]). +-export([check_user_login/2, check_vhost_access/3, check_resource_access/3]). + +-include("rabbit_auth_backend_spec.hrl"). + +%% Our internal user database + +description() -> + [{name, <<"Internal">>}, + {description, <<"Internal user / password database">>}]. + +check_user_login(Username, []) -> + internal_check_user_login(Username, fun() -> true end); +check_user_login(Username, [{password, Password}]) -> + internal_check_user_login( + Username, + fun(#internal_user{password_hash = Hash}) -> + rabbit_access_control:check_password(Password, Hash) + end); +check_user_login(Username, AuthProps) -> + exit({unknown_auth_props, Username, AuthProps}). + +internal_check_user_login(Username, Fun) -> + Refused = {refused, "user '~s' - invalid credentials", [Username]}, + case rabbit_access_control:lookup_user(Username) of + {ok, User = #internal_user{is_admin = IsAdmin}} -> + case Fun(User) of + true -> {ok, #user{username = Username, + is_admin = IsAdmin, + auth_backend = ?MODULE, + impl = User}}; + _ -> Refused + end; + {error, not_found} -> + Refused + end. + +check_vhost_access(#user{is_admin = true}, _VHostPath, read) -> + true; + +check_vhost_access(#user{username = Username}, VHostPath, write) -> + %% TODO: use dirty ops instead + rabbit_misc:execute_mnesia_transaction( + fun () -> + case mnesia:read({rabbit_user_permission, + #user_vhost{username = Username, + virtual_host = VHostPath}}) of + [] -> false; + [_R] -> true + end + end). + +check_resource_access(#user{username = Username}, + #resource{virtual_host = VHostPath, name = Name}, + Permission) -> + case mnesia:dirty_read({rabbit_user_permission, + #user_vhost{username = Username, + virtual_host = VHostPath}}) of + [] -> + false; + [#user_permission{permission = P}] -> + PermRegexp = + case element(permission_index(Permission), P) of + %% <<"^$">> breaks Emacs' erlang mode + <<"">> -> <<$^, $$>>; + RE -> RE + end, + case re:run(Name, PermRegexp, [{capture, none}]) of + match -> true; + nomatch -> false + end + end. + +permission_index(configure) -> #permission.configure; +permission_index(write) -> #permission.write; +permission_index(read) -> #permission.read. diff --git a/src/rabbit_auth_mechanism_external.erl b/src/rabbit_auth_mechanism_external.erl index 6572f786..1c4e5c15 100644 --- a/src/rabbit_auth_mechanism_external.erl +++ b/src/rabbit_auth_mechanism_external.erl @@ -81,7 +81,7 @@ handle_response(_Response, #state{username = Username}) -> {refused, _, _} = E -> E; _ -> - case rabbit_access_control:lookup_user(Username) of + case rabbit_access_control:check_user_login(Username, []) of {ok, User} -> {ok, User}; {error, not_found} -> diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl index 4e9bd4b1..d50599c1 100644 --- a/src/rabbit_channel.erl +++ b/src/rabbit_channel.erl @@ -47,7 +47,7 @@ -record(ch, {state, channel, reader_pid, writer_pid, limiter_pid, start_limiter_fun, transaction_id, tx_participants, next_tag, uncommitted_ack_q, unacked_message_q, - username, virtual_host, most_recently_declared_queue, + user, virtual_host, most_recently_declared_queue, consumer_mapping, blocking, queue_collector_pid, stats_timer, confirm_enabled, publish_seqno, confirm_multiple, confirm_tref, held_confirms, unconfirmed, queues_for_msg}). @@ -83,7 +83,7 @@ -type(channel_number() :: non_neg_integer()). -spec(start_link/7 :: - (channel_number(), pid(), pid(), rabbit_access_control:username(), + (channel_number(), pid(), pid(), rabbit_types:user(), rabbit_types:vhost(), pid(), fun ((non_neg_integer()) -> rabbit_types:ok(pid()))) -> rabbit_types:ok_pid_or_error()). @@ -111,9 +111,9 @@ %%---------------------------------------------------------------------------- -start_link(Channel, ReaderPid, WriterPid, Username, VHost, CollectorPid, +start_link(Channel, ReaderPid, WriterPid, User, VHost, CollectorPid, StartLimiterFun) -> - gen_server2:start_link(?MODULE, [Channel, ReaderPid, WriterPid, Username, + gen_server2:start_link(?MODULE, [Channel, ReaderPid, WriterPid, User, VHost, CollectorPid, StartLimiterFun], []). do(Pid, Method) -> @@ -168,7 +168,7 @@ emit_stats(Pid) -> %%--------------------------------------------------------------------------- -init([Channel, ReaderPid, WriterPid, Username, VHost, CollectorPid, +init([Channel, ReaderPid, WriterPid, User, VHost, CollectorPid, StartLimiterFun]) -> process_flag(trap_exit, true), ok = pg_local:join(rabbit_channels, self()), @@ -184,7 +184,7 @@ init([Channel, ReaderPid, WriterPid, Username, VHost, CollectorPid, next_tag = 1, uncommitted_ack_q = queue:new(), unacked_message_q = queue:new(), - username = Username, + user = User, virtual_host = VHost, most_recently_declared_queue = <<>>, consumer_mapping = dict:new(), @@ -371,7 +371,7 @@ return_queue_declare_ok(#resource{name = ActualName}, message_count = MessageCount, consumer_count = ConsumerCount}). -check_resource_access(Username, Resource, Perm) -> +check_resource_access(User, Resource, Perm) -> V = {Resource, Perm}, Cache = case get(permission_cache) of undefined -> []; @@ -381,7 +381,7 @@ check_resource_access(Username, Resource, Perm) -> case lists:member(V, Cache) of true -> lists:delete(V, Cache); false -> ok = rabbit_access_control:check_resource_access( - Username, Resource, Perm), + User, Resource, Perm), lists:sublist(Cache, ?MAX_PERMISSION_CACHE_SIZE - 1) end, put(permission_cache, [V | CacheTail]), @@ -391,14 +391,14 @@ clear_permission_cache() -> erase(permission_cache), ok. -check_configure_permitted(Resource, #ch{username = Username}) -> - check_resource_access(Username, Resource, configure). +check_configure_permitted(Resource, #ch{user = User}) -> + check_resource_access(User, Resource, configure). -check_write_permitted(Resource, #ch{username = Username}) -> - check_resource_access(Username, Resource, write). +check_write_permitted(Resource, #ch{user = User}) -> + check_resource_access(User, Resource, write). -check_read_permitted(Resource, #ch{username = Username}) -> - check_resource_access(Username, Resource, read). +check_read_permitted(Resource, #ch{user = User}) -> + check_resource_access(User, Resource, read). expand_queue_name_shortcut(<<>>, #ch{most_recently_declared_queue = <<>>}) -> rabbit_misc:protocol_error( @@ -1300,7 +1300,7 @@ infos(Items, State) -> [{Item, i(Item, State)} || Item <- Items]. i(pid, _) -> self(); i(connection, #ch{reader_pid = ReaderPid}) -> ReaderPid; i(number, #ch{channel = Channel}) -> Channel; -i(user, #ch{username = Username}) -> Username; +i(user, #ch{user = User}) -> User#user.username; i(vhost, #ch{virtual_host = VHost}) -> VHost; i(transactional, #ch{transaction_id = TxnKey}) -> TxnKey =/= none; i(consumer_count, #ch{consumer_mapping = ConsumerMapping}) -> diff --git a/src/rabbit_channel_sup.erl b/src/rabbit_channel_sup.erl index 02199a65..e11f8a3e 100644 --- a/src/rabbit_channel_sup.erl +++ b/src/rabbit_channel_sup.erl @@ -56,7 +56,7 @@ %%---------------------------------------------------------------------------- -start_link({Protocol, Sock, Channel, FrameMax, ReaderPid, Username, VHost, +start_link({Protocol, Sock, Channel, FrameMax, ReaderPid, User, VHost, Collector}) -> {ok, SupPid} = supervisor2:start_link(?MODULE, []), {ok, WriterPid} = @@ -69,7 +69,7 @@ start_link({Protocol, Sock, Channel, FrameMax, ReaderPid, Username, VHost, supervisor2:start_child( SupPid, {channel, {rabbit_channel, start_link, - [Channel, ReaderPid, WriterPid, Username, VHost, + [Channel, ReaderPid, WriterPid, User, VHost, Collector, start_limiter_fun(SupPid)]}, intrinsic, ?MAX_WAIT, worker, [rabbit_channel]}), {ok, FramingChannelPid} = diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl index dadfc16e..1f2d4d7d 100644 --- a/src/rabbit_mnesia.erl +++ b/src/rabbit_mnesia.erl @@ -154,10 +154,10 @@ nodes_of_type(Type) -> table_definitions() -> [{rabbit_user, - [{record_name, user}, - {attributes, record_info(fields, user)}, + [{record_name, internal_user}, + {attributes, record_info(fields, internal_user)}, {disc_copies, [node()]}, - {match, #user{_='_'}}]}, + {match, #internal_user{_='_'}}]}, {rabbit_user_permission, [{record_name, user_permission}, {attributes, record_info(fields, user_permission)}, diff --git a/src/rabbit_reader.erl b/src/rabbit_reader.erl index 41b14771..c542ea66 100644 --- a/src/rabbit_reader.erl +++ b/src/rabbit_reader.erl @@ -969,12 +969,12 @@ send_to_new_channel(Channel, AnalyzedFrame, State) -> channel_sup_sup_pid = ChanSupSup, connection = #connection{protocol = Protocol, frame_max = FrameMax, - user = #user{username = Username}, + user = User, vhost = VHost}} = State, {ok, ChSupPid, ChFrPid} = rabbit_channel_sup_sup:start_channel( ChanSupSup, {Protocol, Sock, Channel, FrameMax, - self(), Username, VHost, Collector}), + self(), User, VHost, Collector}), erlang:monitor(process, ChSupPid), put({channel, Channel}, {ch_fr_pid, ChFrPid}), put({ch_sup_pid, ChSupPid}, {{channel, Channel}, {ch_fr_pid, ChFrPid}}), diff --git a/src/rabbit_registry.erl b/src/rabbit_registry.erl index 7a3fcb51..ca300e72 100644 --- a/src/rabbit_registry.erl +++ b/src/rabbit_registry.erl @@ -111,7 +111,8 @@ sanity_check_module(ClassModule, Module) -> end. class_module(exchange) -> rabbit_exchange_type; -class_module(auth_mechanism) -> rabbit_auth_mechanism. +class_module(auth_mechanism) -> rabbit_auth_mechanism; +class_module(auth_backend) -> rabbit_auth_backend. %%--------------------------------------------------------------------------- diff --git a/src/rabbit_types.erl b/src/rabbit_types.erl index 548014be..15e71ee4 100644 --- a/src/rabbit_types.erl +++ b/src/rabbit_types.erl @@ -42,8 +42,8 @@ vhost/0, ctag/0, amqp_error/0, r/1, r2/2, r3/3, listener/0, binding/0, binding_source/0, binding_destination/0, amqqueue/0, exchange/0, - connection/0, protocol/0, user/0, ok/1, error/1, ok_or_error/1, - ok_or_error2/2, ok_pid_or_error/0, channel_exit/0, + connection/0, protocol/0, user/0, internal_user/0, ok/1, error/1, + ok_or_error/1, ok_or_error2/2, ok_pid_or_error/0, channel_exit/0, connection_exit/0]). -type(channel_exit() :: no_return()). @@ -151,9 +151,15 @@ -type(protocol() :: rabbit_framing:protocol()). -type(user() :: - #user{username :: rabbit_access_control:username(), - password_hash :: rabbit_access_control:password_hash(), - is_admin :: boolean()}). + #user{username :: rabbit_access_control:username(), + is_admin :: boolean(), + auth_backend :: atom(), + impl :: any()}). + +-type(internal_user() :: + #internal_user{username :: rabbit_access_control:username(), + password_hash :: rabbit_access_control:password_hash(), + is_admin :: boolean()}). -type(ok(A) :: {'ok', A}). -type(error(A) :: {'error', A}). diff --git a/src/rabbit_upgrade_functions.erl b/src/rabbit_upgrade_functions.erl index 1c56d51d..5dd4c558 100644 --- a/src/rabbit_upgrade_functions.erl +++ b/src/rabbit_upgrade_functions.erl @@ -27,6 +27,7 @@ -rabbit_upgrade({remove_user_scope, []}). -rabbit_upgrade({hash_passwords, []}). -rabbit_upgrade({add_ip_to_listener, []}). +-rabbit_upgrade({user_to_internal_user, []}). %% ------------------------------------------------------------------- @@ -35,6 +36,7 @@ -spec(remove_user_scope/0 :: () -> 'ok'). -spec(hash_passwords/0 :: () -> 'ok'). -spec(add_ip_to_listener/0 :: () -> 'ok'). +-spec(user_to_internal_user/0 :: () -> 'ok'). -endif. @@ -71,8 +73,21 @@ add_ip_to_listener() -> end, [node, protocol, host, ip_address, port]). +user_to_internal_user() -> + mnesia( + rabbit_user, + fun({user, Username, PasswordHash, IsAdmin}) -> + {internal_user, Username, PasswordHash, IsAdmin} + end, + [username, password_hash, is_admin], internal_user). + %%-------------------------------------------------------------------- mnesia(TableName, Fun, FieldList) -> {atomic, ok} = mnesia:transform_table(TableName, Fun, FieldList), ok. + +mnesia(TableName, Fun, FieldList, NewRecordName) -> + {atomic, ok} = mnesia:transform_table(TableName, Fun, FieldList, + NewRecordName), + ok. |