%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1997-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. %% %% 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. %% %% %CopyrightEnd% %% %% -module(mod_auth_mnesia). -export([get_user/2, list_group_members/2, add_user/2, add_group_member/3, list_users/1, delete_user/2, list_groups/1, delete_group_member/3, delete_group/2]). -export([store_user/5, store_user/6, store_group_member/5, store_group_member/6, list_group_members/3, list_group_members/4, list_groups/2, list_groups/3, list_users/2, list_users/3, remove_user/4, remove_user/5, remove_group_member/5, remove_group_member/6, remove_group/4, remove_group/5]). -export([store_directory_data/3]). -include("httpd.hrl"). -include("mod_auth.hrl"). store_directory_data(_Directory, _DirData, _Server_root) -> %% We don't need to do anything here, we could of course check that %% the appropriate mnesia tables has been created prior to %% starting the http server. ok. %% %% API %% %% Compatibility API store_user(UserName, Password, Port, Dir, _AccessPassword) -> %% AccessPassword is ignored - was not used in previous version DirData = [{path,Dir},{port,Port}], UStruct = #httpd_user{username = UserName, password = Password}, add_user(DirData, UStruct). store_user(UserName, Password, Addr, Port, Dir, _AccessPassword) -> %% AccessPassword is ignored - was not used in previous version DirData = [{path,Dir},{bind_address,Addr},{port,Port}], UStruct = #httpd_user{username = UserName, password = Password}, add_user(DirData, UStruct). store_group_member(GroupName, UserName, Port, Dir, _AccessPassword) -> DirData = [{path,Dir},{port,Port}], add_group_member(DirData, GroupName, UserName). store_group_member(GroupName, UserName, Addr, Port, Dir, _AccessPassword) -> DirData = [{path,Dir},{bind_address,Addr},{port,Port}], add_group_member(DirData, GroupName, UserName). list_group_members(GroupName, Port, Dir) -> DirData = [{path,Dir},{port,Port}], list_group_members(DirData, GroupName). list_group_members(GroupName, Addr, Port, Dir) -> DirData = [{path,Dir},{bind_address,Addr},{port,Port}], list_group_members(DirData, GroupName). list_groups(Port, Dir) -> DirData = [{path,Dir},{port,Port}], list_groups(DirData). list_groups(Addr, Port, Dir) -> DirData = [{path,Dir},{bind_address,Addr},{port,Port}], list_groups(DirData). list_users(Port, Dir) -> DirData = [{path,Dir},{port,Port}], list_users(DirData). list_users(Addr, Port, Dir) -> DirData = [{path,Dir},{bind_address,Addr},{port,Port}], list_users(DirData). remove_user(UserName, Port, Dir, _AccessPassword) -> DirData = [{path,Dir},{port,Port}], delete_user(DirData, UserName). remove_user(UserName, Addr, Port, Dir, _AccessPassword) -> DirData = [{path,Dir},{bind_address,Addr},{port,Port}], delete_user(DirData, UserName). remove_group_member(GroupName,UserName,Port,Dir,_AccessPassword) -> DirData = [{path,Dir},{port,Port}], delete_group_member(DirData, GroupName, UserName). remove_group_member(GroupName,UserName,Addr,Port,Dir,_AccessPassword) -> DirData = [{path,Dir},{bind_address,Addr},{port,Port}], delete_group_member(DirData, GroupName, UserName). remove_group(GroupName,Port,Dir,_AccessPassword) -> DirData = [{path,Dir},{port,Port}], delete_group(DirData, GroupName). remove_group(GroupName,Addr,Port,Dir,_AccessPassword) -> DirData = [{path,Dir},{bind_address,Addr},{port,Port}], delete_group(DirData, GroupName). %% %% Storage format of users in the mnesia table: %% httpd_user records %% add_user(DirData, UStruct) -> {Addr, Port, Dir} = lookup_common(DirData), UserName = UStruct#httpd_user.username, Password = UStruct#httpd_user.password, Data = UStruct#httpd_user.user_data, User=#httpd_user{username={UserName,Addr,Port,Dir}, password=Password, user_data=Data}, case mnesia:transaction(fun() -> mnesia:write(User) end) of {aborted,Reason} -> {error,Reason}; _ -> true end. get_user(DirData, UserName) -> {Addr, Port, Dir} = lookup_common(DirData), case mnesia:transaction(fun() -> mnesia:read({httpd_user, {UserName,Addr,Port,Dir}}) end) of {aborted,Reason} -> {error, Reason}; {atomic,[]} -> {error, no_such_user}; {atomic, [Record]} when is_record(Record, httpd_user) -> {ok, Record#httpd_user{username=UserName}}; _ -> {error, no_such_user} end. list_users(DirData) -> {Addr, Port, Dir} = lookup_common(DirData), case mnesia:transaction(fun() -> mnesia:match_object({httpd_user, {'_',Addr,Port,Dir},'_','_'}) end) of {aborted,Reason} -> {error,Reason}; {atomic,Users} -> {ok, lists:foldr(fun({httpd_user, {UserName, _AnyAddr, _AnyPort, _AnyDir}, _Password, _Data}, Acc) -> [UserName|Acc] end, [], Users)} end. delete_user(DirData, UserName) -> {Addr, Port, Dir} = lookup_common(DirData), case mnesia:transaction(fun() -> mnesia:delete({httpd_user, {UserName,Addr,Port,Dir}}) end) of {aborted,Reason} -> {error,Reason}; _ -> true end. %% %% Storage of groups in the mnesia table: %% Multiple instances of {#httpd_group, User} %% add_group_member(DirData, GroupName, User) -> {Addr, Port, Dir} = lookup_common(DirData), Group=#httpd_group{name={GroupName, Addr, Port, Dir}, userlist=User}, case mnesia:transaction(fun() -> mnesia:write(Group) end) of {aborted,Reason} -> {error,Reason}; _ -> true end. list_group_members(DirData, GroupName) -> {Addr, Port, Dir} = lookup_common(DirData), case mnesia:transaction(fun() -> mnesia:read({httpd_group, {GroupName,Addr,Port,Dir}}) end) of {aborted, Reason} -> {error,Reason}; {atomic, Members} -> {ok,[UserName || {httpd_group,{AnyGroupName,AnyAddr, AnyPort,AnyDir},UserName} <- Members, AnyGroupName == GroupName, AnyAddr == Addr, AnyPort == Port, AnyDir == Dir]} end. list_groups(DirData) -> {Addr, Port, Dir} = lookup_common(DirData), case mnesia:transaction(fun() -> mnesia:match_object({httpd_group, {'_',Addr,Port,Dir}, '_'}) end) of {aborted, Reason} -> {error, Reason}; {atomic, Groups} -> GroupNames= [GroupName || {httpd_group,{GroupName,AnyAddr,AnyPort,AnyDir}, _UserName} <- Groups, AnyAddr == Addr, AnyPort == AnyPort, AnyDir == Dir], {ok, httpd_util:uniq(lists:sort(GroupNames))} end. delete_group_member(DirData, GroupName, UserName) -> {Addr, Port, Dir} = lookup_common(DirData), Group = #httpd_group{name={GroupName, Addr, Port, Dir}, userlist=UserName}, case mnesia:transaction(fun() -> mnesia:delete_object(Group) end) of {aborted,Reason} -> {error,Reason}; _ -> true end. %% THIS IS WRONG (?) ! %% Should first match out all httpd_group records for this group and then %% do mnesia:delete on those. Or ? delete_group(DirData, GroupName) -> {Addr, Port, Dir} = lookup_common(DirData), case mnesia:transaction(fun() -> mnesia:delete({httpd_group, {GroupName,Addr,Port,Dir}}) end) of {aborted,Reason} -> {error,Reason}; _ -> true end. %% Utility functions. lookup_common(DirData) -> Dir = proplists:get_value(path, DirData), Port = proplists:get_value(port, DirData), Addr = proplists:get_value(bind_address, DirData), {Addr, Port, Dir}.