Permalink
Browse files

Add user and group support

  • Loading branch information...
1 parent 8f112ff commit 434c519f561a0f772a37ff21d857d0c6c51a1772 @DeadZen committed Feb 6, 2012
Showing with 88 additions and 16 deletions.
  1. +13 −0 apps/htoad/include/stdlib.hrl
  2. +67 −12 apps/htoad/src/htoad_lfs.erl
  3. +8 −4 apps/htoad/src/htoad_shell.erl
@@ -15,11 +15,24 @@
}).
%%
+-record(user,
+ {
+ id,
+ name
+ }).
+
+-record(group,
+ {
+ id,
+ name
+ }).
-record(file,
{
type = file :: file | dir,
path :: undefined | string(),
+ user :: #user{} | string() | integer(),
+ group :: #group{} | string() | integer(),
mode,
content = ""
}).
@@ -5,7 +5,8 @@
-include_lib("kernel/include/file.hrl").
--rules([init, ensure_file_present, ensure_dir_present,
+-rules([init,
+ ensure_file_present, ensure_dir_present, ensure_path_access,
fs_file_present, fs_dir_present]).
init(Engine, #init{}) ->
@@ -16,20 +17,45 @@ ensure_file_present(Engine, {ensure, present,
#file{
type = file
} = File}) ->
- filelib:ensure_dir(File#file.path),
- file:write_file(File#file.path, File#file.content),
- lager:debug("Ensured file ~s",[File#file.path]),
- chmod(File#file.path, File#file.mode),
- htoad:assert(Engine, File).
+
+ case file:write_file(File#file.path, File#file.content) of
+ ok ->
+ lager:debug("Ensured file ~s",[File#file.path]),
+ chmod(File#file.path, File#file.mode),
+ htoad:assert(Engine, File);
+ {error, Reason} ->
+ htoad:assert(Engine, #error_report{ rule = {?MODULE, ensure_file_present},
+ fact = {ensure, present, File},
+ reason = {error, Reason} })
+ end.
+
ensure_dir_present(Engine, {ensure, present,
#file{
type = dir
} = Dir}) ->
- ok = filelib:ensure_dir(Dir#file.path ++ "/"),
- lager:debug("Ensured directory ~s",[Dir#file.path]),
- chmod(Dir#file.path, Dir#file.mode),
- htoad:assert(Engine, Dir).
+ case filelib:ensure_dir(Dir#file.path ++ "/") of
+ ok ->
+ lager:debug("Ensured directory ~s",[Dir#file.path]),
+ chmod(Dir#file.path, Dir#file.mode),
+ htoad:assert(Engine, Dir);
+ {error, Reason} ->
+ htoad:assert(Engine, #error_report{ rule = {?MODULE, ensure_dir_present},
+ fact = {ensure, present, Dir},
+ reason = {error, Reason} })
+ end.
+
+
+ensure_path_access(Engine, {ensure, present,
+ #file{
+ user = FileUser,
+ group = FileGroup
+ } = File}, #user{}=User,
+ #group{}=Group) ->
+ lager:debug("Ensured access ~s",[File#file.path]),
+ chown(File#file.path, FileUser, User),
+ chgrp(File#file.path, FileGroup, Group),
+ htoad:assert(Engine, File).
%% file system
fs_file_present(Engine, {file_request, #file{
@@ -56,6 +82,35 @@ fs_dir_present(Engine, {file_request, #file{
%% private
+
+chown(Path, FileUser, User) when is_list(FileUser), is_record(User, user) ->
+ chown(Path, #user{ id = get_uid(FileUser) }, User);
+chown(Path, FileUser, User) when is_integer(FileUser), is_record(User, user) ->
+ chown(Path, #user{ id = FileUser }, User);
+chown(_, #user{ id = Uid }, #user{ id = Uid }) ->
+ ok;
+chown(Path, #user{ id = Uid }=_FileUser, #user{ id = _ }) ->
+ lager:debug("Changed file ~s to uid ~w", [Path, Uid]),
+ file:change_owner(Path, Uid).
+
+chgrp(Path, FileGroup, Group) when is_list(FileGroup), is_record(Group, group) ->
+ chgrp(Path, #group{ id = get_gid(FileGroup) }, Group);
+chgrp(Path, FileGroup, Group) when is_integer(FileGroup), is_record(Group, group) ->
+ chgrp(Path, #group{ id = FileGroup }, Group);
+chgrp(_, #group{ id = Gid }, #group{ id = Gid }) ->
+ ok;
+chgrp(Path, #group{ id = Gid }=_FileGroup, #group{ id = _ }) ->
+ lager:debug("Changed file ~s to gid ~w", [Path, Gid]),
+ file:change_group(Path, Gid).
+
+get_uid(User) when is_list(User) ->
+ Uid = string:strip(os:cmd("id -u " ++ User), right, $\n),
+ list_to_integer(Uid).
+
+get_gid(Group) when is_list(Group) ->
+ Gid = string:strip(os:cmd("id -g " ++ Group), right, $\n),
+ list_to_integer(Gid).
+
chmod(Path, Mode) ->
case Mode of
undefined ->
@@ -66,8 +121,8 @@ chmod(Path, Mode) ->
end.
load_mode(#file{} = File) ->
- {ok, #file_info{ mode = Mode }} = file:read_file_info(File#file.path),
- File#file{ mode = Mode }.
+ {ok, #file_info{ mode = Mode, gid = Gid, uid = Uid }} = file:read_file_info(File#file.path),
+ File#file{ mode = Mode, user = #user{ id = Uid }, group = #group{ id = Gid } }.
load_content(#file{ content = dontread } = File) ->
File;
@@ -3,16 +3,20 @@
-include_lib("htoad/include/toadie.hrl").
-include_lib("htoad/include/stdlib.hrl").
+-define(REGEX, ".*uid=([^\(]*)\\(([^\)]*).*gid=([^\\(]*)\\(([^\)]*).*").
+
-rules([init, user, superuser, command_run_in_superuser,
command_run_as_superuser, command]).
init(Engine, #init{}, {operating_system_type, unix}) ->
lager:debug("Initialized htoad_shell"),
- htoad:assert(Engine, #shell{ cmd = "whoami" }).
+ htoad:assert(Engine, #shell{ cmd = "id" }).
-user(Engine, {output, #shell{ cmd = "whoami"}, User}) ->
- lager:debug("Current user: ~s", [User]),
- htoad:assert(Engine, {user, User}).
+user(Engine, {output, #shell{ cmd = "id" }, Result}) ->
+ {match, [Uid, User, Gid, Group]} = re:run(Result, ?REGEX, [{capture,[1,2,3,4],list}]),
+ lager:debug("Current User: ~s, Uid: ~s, Group: ~s, Gid: ~s", [User, Uid, Group, Gid]),
+ htoad:assert(Engine, [#user{ id = list_to_integer(Uid), name = User },
+ #group{ id = list_to_integer(Gid), name = Group }]).
superuser(Engine, #init{}, {operating_system_type, unix},
{user, "root"}) ->

0 comments on commit 434c519

Please sign in to comment.