PageRenderTime 133ms CodeModel.GetById 60ms app.highlight 19ms RepoModel.GetById 51ms app.codeStats 1ms

/ucengine/src/models/uce_role.erl

http://github.com/AF83/ucengine
Erlang | 175 lines | 128 code | 24 blank | 23 comment | 0 complexity | d977a1618683554b4be24e9f8b707081 MD5 | raw file
  1%%
  2%%  U.C.Engine - Unified Collaboration Engine
  3%%  Copyright (C) 2011 af83
  4%%
  5%%  This program is free software: you can redistribute it and/or modify
  6%%  it under the terms of the GNU Affero General Public License as published by
  7%%  the Free Software Foundation, either version 3 of the License, or
  8%%  (at your option) any later version.
  9%%
 10%%  This program is distributed in the hope that it will be useful,
 11%%  but WITHOUT ANY WARRANTY; without even the implied warranty of
 12%%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13%%  GNU Affero General Public License for more details.
 14%%
 15%%  You should have received a copy of the GNU Affero General Public License
 16%%  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 17%%
 18-module(uce_role).
 19
 20-export([add/2,
 21         delete/2,
 22         update/2,
 23         get/2,
 24         exists/2,
 25         acl/2,
 26         add_access/3,
 27         delete_access/3,
 28         drop/1]).
 29
 30-include("uce.hrl").
 31
 32%
 33% Public api
 34%
 35
 36-spec add(domain(), role()) -> {ok, created} | erlang:throw({error, conflict}).
 37add(Domain, #uce_role{id=Id} = Role) ->
 38    case exists(Domain, Id) of
 39        true ->
 40            throw({error, conflict});
 41        false ->
 42            internal_add(Domain, Role)
 43    end.
 44
 45-spec update(domain(), role()) -> {ok, updated} | erlang:throw({error, not_found}).
 46update(Domain, #uce_role{id=Id} = Role) ->
 47    case exists(Domain, Id) of
 48        true ->
 49            internal_update(Domain, Role);
 50        false ->
 51            throw({error, not_found})
 52    end.
 53
 54-spec delete(domain(), role_id()) -> {ok, deleted} | erlang:throw({error, not_found}).
 55delete(Domain, Id) ->
 56    case exists(Domain, Id) of
 57        true ->
 58            internal_delete(Domain, Id);
 59        false ->
 60            throw({error, not_found})
 61    end.
 62
 63-spec get(domain(), role_id()) -> {ok, role()} | erlang:throw({error, not_found}).
 64get(Domain, Id) ->
 65    internal_get(Domain, Id).
 66
 67-spec exists(domain(), role_id()) -> true | false | erlang:throw({error, atom()}).
 68exists(Domain, Id) ->
 69    case catch get(Domain, Id) of
 70        {error, not_found} ->
 71            false;
 72        {error, Reason} ->
 73            throw({error, Reason});
 74        _ ->
 75            true
 76    end.
 77
 78-spec acl(domain(), role_id()) -> {ok, updated} | erlang:throw({error, not_found}).
 79acl(Domain, Id) ->
 80    {ok, Role} = get(Domain, Id),
 81    {ok, Role#uce_role.acl}.
 82
 83-spec add_access(domain(), role_id(), access()) -> {ok, updated} | erlang:throw({error, not_found}).
 84add_access(Domain, Id, #uce_access{} = Access) ->
 85    {ok, Role} = get(Domain, Id),
 86    case uce_access:exists(Access, Role#uce_role.acl) of
 87        true ->
 88            {ok, updated};
 89        false ->
 90            update(Domain, Role#uce_role{acl=(Role#uce_role.acl ++ [Access])})
 91    end.
 92
 93-spec delete_access(domain(), role_id(), access()) -> {ok, updated} | erlang:throw({error, not_found}).
 94delete_access(Domain, Id, #uce_access{} = Access) ->
 95    {ok, Role} = get(Domain, Id),
 96    ACL = case uce_access:exists(Access, Role#uce_role.acl) of
 97              true ->
 98                  uce_access:delete(Access, Role#uce_role.acl);
 99              false ->
100                  Role#uce_role.acl
101          end,
102    update(Domain, Role#uce_role{acl=ACL}).
103
104-spec drop(domain()) -> true.
105drop(_Domain) ->
106    delete_table().
107
108%
109% Private functions
110%
111
112-define(TAB, uce_role_cache).
113
114init_table() ->
115    case ets:info(?TAB) of
116        undefined ->
117            ets:new(?TAB, [set, public, {keypos, 1}, named_table]);
118        _ ->
119            ok
120    end.
121
122delete_table() ->
123    case ets:info(?TAB) of
124        undefined ->
125            ok;
126        _ ->
127            ets:delete(?TAB)
128    end.
129
130cache_add(Domain, #uce_role{id=Id} = Role) ->
131    ets:insert(?TAB, {{Domain, Id}, Role}).
132
133cache_update(Domain, Role) ->
134    cache_add(Domain, Role).
135
136cache_delete(Domain, Id) ->
137    ets:delete(?TAB, {Domain, Id}).
138
139cache_get(Domain, Id) ->
140    case ets:lookup(?TAB, {Domain, Id}) of
141        [] ->
142            undefined;
143        [{{Domain, Id}, Role}] ->
144            Role
145    end.
146
147internal_add(Domain, Role) ->
148    init_table(),
149    cache_add(Domain, Role),
150    (db:get(?MODULE, Domain)):add(Domain, Role).
151
152internal_update(Domain, Role) ->
153    init_table(),
154    cache_update(Domain, Role),
155    (db:get(?MODULE, Domain)):update(Domain, Role).
156
157internal_delete(Domain, Id) ->
158    init_table(),
159    cache_delete(Domain, Id),
160    (db:get(?MODULE, Domain)):delete(Domain, Id).
161
162internal_get(Domain, Id) ->
163    init_table(),
164    case cache_get(Domain, Id) of
165        undefined ->
166            case (db:get(?MODULE, Domain)):get(Domain, Id) of
167                {ok, Role} ->
168                    cache_add(Domain, Role),
169                    {ok, Role};
170                Error ->
171                    Error
172            end;
173        Role ->
174            {ok, Role}
175    end.