Skip to content

Commit

Permalink
Add user and group support
Browse files Browse the repository at this point in the history
  • Loading branch information
DeadZen committed Feb 6, 2012
1 parent 8f112ff commit 434c519
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 16 deletions.
13 changes: 13 additions & 0 deletions apps/htoad/include/stdlib.hrl
Expand Up @@ -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 = ""
}).
Expand Down
79 changes: 67 additions & 12 deletions apps/htoad/src/htoad_lfs.erl
Expand Up @@ -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{}) ->
Expand All @@ -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{
Expand All @@ -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 ->
Expand All @@ -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;
Expand Down
12 changes: 8 additions & 4 deletions apps/htoad/src/htoad_shell.erl
Expand Up @@ -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"}) ->
Expand Down

0 comments on commit 434c519

Please sign in to comment.