kvs_acl.erl 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. -module(kvs_acl).
  2. -copyright('Synrc Research Center s.r.o.').
  3. -compile(export_all).
  4. -include_lib("kvs/include/acls.hrl").
  5. -include_lib("kvs/include/users.hrl").
  6. -include_lib("kvs/include/groups.hrl").
  7. -include_lib("kvs/include/feeds.hrl").
  8. define_access(default = Accessor, Resource, Action) -> do_define_access(Accessor, Resource, Action);
  9. define_access({user, _Username} = Accessor, Resource, Action) -> do_define_access(Accessor, Resource, Action);
  10. define_access({user_type, _Usertype} = Accessor, Resource, Action) -> do_define_access(Accessor, Resource, Action);
  11. define_access({ip, _Ip} = Accessor, Resource, Action) -> do_define_access(Accessor, Resource, Action).
  12. do_define_access(Accessor, Resource, Action) -> acl_add_entry(select_type(Resource), Accessor, Action).
  13. check(Keys) ->
  14. Acls = [Acl || {ok, Acl = #acl_entry{}} <- [kvs:get(acl_entry, Key) || Key <- Keys]],
  15. case Acls of
  16. [] -> none;
  17. [#acl_entry{action = Action} | _] -> Action end.
  18. check_access(#user{email = UId, type = UType}, #feed{id = FId}) ->
  19. Feed = {feed, FId},
  20. Query = [ {{user, UId}, Feed}, {{user_type, UType}, Feed}, {default, Feed}],
  21. check(Query);
  22. check_access(#user{email = UId, type = UType}, #group{id = GId}) ->
  23. Group = {group, GId},
  24. Query = [ {{user, UId}, Group}, {{user_type, UType}, Group}, {default, Group}],
  25. check(Query);
  26. check_access(#user{email = AId, type = AType}, #user{email = RId}) ->
  27. User = {user, RId},
  28. Query = [ {{user, AId}, User}, {{user_type, AType}, User}, {default, User} ],
  29. check(Query);
  30. check_access({user_type, Type}, #user{email = RId}) ->
  31. User = {user, RId},
  32. Query = [ {{user_type, Type}, User}, {default, User} ],
  33. check(Query);
  34. check_access({user_type, Type}, #feed{id = FId}) ->
  35. Feed = {feed, FId},
  36. Query = [ {{user_type, Type}, Feed}, {default, Feed} ],
  37. check(Query);
  38. check_access({user_type, Type}, #group{id = GId}) ->
  39. Group = {group, GId},
  40. Query = [{{user_type, Type}, Group}, {default, Group}],
  41. check(Query);
  42. check_access({ip, _Ip} = Accessor, {feature, _Feature} = Resource) ->
  43. Query = [{Accessor, Resource}, {default, Resource}],
  44. check(Query);
  45. check_access(#user{email = AId, type = AType}, {feature, _Feature} = R) ->
  46. Query = [ {{user, AId}, R}, {{user_type, AType}, R}, {default, R} ],
  47. check(Query);
  48. check_access(UId, {feature, _Feature} = Resource) ->
  49. case kvs:get(user, UId) of
  50. {ok, User} -> check_access(User, Resource);
  51. E -> E
  52. end.
  53. select_type({user, Id}) -> {user, Id};
  54. select_type({group, Id}) -> {group, Id};
  55. select_type({product, Id}) -> {product, Id};
  56. select_type({feed, FId}) -> {feed, FId};
  57. select_type({feature, Feature}) -> {feature, Feature}.
  58. entries(AclId) -> case kvs:get(acl, AclId) of {ok,RO} -> read_entries(RO#acl.top, []); {error, _} -> [] end.
  59. read_entries(undefined, Result) -> Result;
  60. read_entries(Next, Result) -> case kvs:get(acl_entry, Next) of {ok,RO} -> read_entries(RO#acl_entry.prev, Result ++ [RO]); {error, _} -> Result end.
  61. acl_add_entry(Resource, Accessor, Action) ->
  62. Acl = case kvs:get(acl, Resource) of {ok, A} -> A;
  63. {error, _} -> A = #acl{id = Resource, resource=Resource}, kvs:put(A), A end,
  64. EntryId = {Accessor, Resource},
  65. case kvs:get(acl_entry, EntryId) of {error, _} ->
  66. Next = undefined,
  67. Prev = case Acl#acl.top of undefined -> undefined;
  68. Top -> case kvs:get(acl_entry, Top) of {ok, TopEntry} ->
  69. EditedEntry = TopEntry#acl_entry{next = EntryId},
  70. kvs:put(EditedEntry), % update prev entry
  71. TopEntry#acl_entry.id;
  72. {error, _} -> undefined end end,
  73. %% update acl with top of acl entries list
  74. kvs:put(Acl#acl{top = EntryId}),
  75. Entry = #acl_entry{id = EntryId,
  76. entry_id = EntryId,
  77. accessor = Accessor,
  78. action = Action,
  79. next = Next,
  80. prev = Prev},
  81. ok = kvs:put(Entry),
  82. Entry;
  83. %% if acl entry for Accessor and Acl is defined - just change action
  84. {ok, AclEntry} -> kvs:put(AclEntry#acl_entry{action = Action}), AclEntry end.