331000a464
Co-editor and deputy grants with mirror_to_default; personal out of search; list owned+shared. Refs EventHub/EventHubBack#73
120 lines
4.0 KiB
Erlang
120 lines
4.0 KiB
Erlang
%%%-------------------------------------------------------------------
|
|
%%% @doc Grants calendar_share: list / revoke / rights / mirror.
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-module(logic_calendar_share).
|
|
-include("records.hrl").
|
|
|
|
-export([
|
|
list/2,
|
|
revoke/3,
|
|
update_rights/4,
|
|
update_my_mirror/3,
|
|
get_rights/2,
|
|
can_manage_shares/2,
|
|
to_json/1
|
|
]).
|
|
|
|
-spec list(ActorId :: binary(), CalendarId :: binary()) ->
|
|
{ok, [#calendar_share{}]} | {error, not_found | access_denied}.
|
|
list(ActorId, CalendarId) ->
|
|
case require_can_view_shares(ActorId, CalendarId) of
|
|
{ok, _} -> {ok, core_calendar_share:list_by_calendar(CalendarId)};
|
|
Error -> Error
|
|
end.
|
|
|
|
-spec revoke(ActorId :: binary(), CalendarId :: binary(), TargetUserId :: binary()) ->
|
|
ok | {error, not_found | access_denied | term()}.
|
|
revoke(ActorId, CalendarId, TargetUserId) ->
|
|
case require_can_manage(ActorId, CalendarId) of
|
|
{ok, _} ->
|
|
case core_calendar_share:delete(CalendarId, TargetUserId) of
|
|
ok -> ok;
|
|
{error, _} = E -> E
|
|
end;
|
|
Error -> Error
|
|
end.
|
|
|
|
-spec update_rights(ActorId :: binary(), CalendarId :: binary(),
|
|
TargetUserId :: binary(), Rights :: read | write | admin) ->
|
|
{ok, #calendar_share{}} | {error, not_found | access_denied | bad_request | term()}.
|
|
update_rights(ActorId, CalendarId, TargetUserId, Rights) ->
|
|
case valid_rights(Rights) of
|
|
false -> {error, bad_request};
|
|
true ->
|
|
case require_can_manage(ActorId, CalendarId) of
|
|
{ok, _} -> core_calendar_share:update_rights(CalendarId, TargetUserId, Rights);
|
|
Error -> Error
|
|
end
|
|
end.
|
|
|
|
%% Invitee updates own mirror preference (personal shares only meaningful).
|
|
-spec update_my_mirror(UserId :: binary(), CalendarId :: binary(), Mirror :: boolean()) ->
|
|
{ok, #calendar_share{}} | {error, not_found | access_denied | term()}.
|
|
update_my_mirror(UserId, CalendarId, Mirror) when is_boolean(Mirror) ->
|
|
case core_calendar_share:get(CalendarId, UserId) of
|
|
{ok, _} -> core_calendar_share:update_mirror(CalendarId, UserId, Mirror);
|
|
{error, not_found} -> {error, not_found}
|
|
end;
|
|
update_my_mirror(_, _, _) ->
|
|
{error, bad_request}.
|
|
|
|
-spec get_rights(UserId :: binary(), CalendarId :: binary()) ->
|
|
none | read | write | admin.
|
|
get_rights(UserId, CalendarId) ->
|
|
case core_calendar_share:get(CalendarId, UserId) of
|
|
{ok, #calendar_share{rights = R}} -> R;
|
|
{error, not_found} -> none
|
|
end.
|
|
|
|
-spec can_manage_shares(UserId :: binary(), #calendar{}) -> boolean().
|
|
can_manage_shares(UserId, #calendar{owner_id = UserId, status = active}) ->
|
|
true;
|
|
can_manage_shares(UserId, #calendar{id = CalId, status = active}) ->
|
|
get_rights(UserId, CalId) =:= admin;
|
|
can_manage_shares(_, _) ->
|
|
false.
|
|
|
|
-spec to_json(#calendar_share{}) -> map().
|
|
to_json(S) ->
|
|
#{
|
|
id => S#calendar_share.id,
|
|
calendar_id => S#calendar_share.calendar_id,
|
|
user_id => S#calendar_share.user_id,
|
|
rights => S#calendar_share.rights,
|
|
mirror_to_default => S#calendar_share.mirror_to_default
|
|
}.
|
|
|
|
%%%===================================================================
|
|
%%% Internal
|
|
%%%===================================================================
|
|
|
|
require_can_view_shares(ActorId, CalendarId) ->
|
|
case core_calendar:get_by_id(CalendarId) of
|
|
{ok, #calendar{status = active} = Cal} ->
|
|
case can_manage_shares(ActorId, Cal)
|
|
orelse Cal#calendar.owner_id =:= ActorId
|
|
orelse get_rights(ActorId, CalendarId) =/= none of
|
|
true -> {ok, Cal};
|
|
false -> {error, access_denied}
|
|
end;
|
|
{ok, _} -> {error, not_found};
|
|
Error -> Error
|
|
end.
|
|
|
|
require_can_manage(ActorId, CalendarId) ->
|
|
case core_calendar:get_by_id(CalendarId) of
|
|
{ok, #calendar{status = active} = Cal} ->
|
|
case can_manage_shares(ActorId, Cal) of
|
|
true -> {ok, Cal};
|
|
false -> {error, access_denied}
|
|
end;
|
|
{ok, _} -> {error, not_found};
|
|
Error -> Error
|
|
end.
|
|
|
|
valid_rights(read) -> true;
|
|
valid_rights(write) -> true;
|
|
valid_rights(admin) -> true;
|
|
valid_rights(_) -> false.
|