You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2019/03/26 21:09:08 UTC

[couchdb] branch prototype/fdb-layer updated: Fix compiler errors

This is an automated email from the ASF dual-hosted git repository.

davisp pushed a commit to branch prototype/fdb-layer
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/prototype/fdb-layer by this push:
     new 628795a  Fix compiler errors
628795a is described below

commit 628795ab535e05531fd35db29564979284184b2f
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Tue Mar 26 16:09:28 2019 -0500

    Fix compiler errors
---
 src/fabric/include/fabric.hrl           |   4 -
 src/fabric/src/fabric2.erl              | 116 ---------------------
 src/fabric/{include => src}/fabric2.hrl |  11 +-
 src/fabric/src/fabric2_db.erl           | 173 ++++++++++++++++++++++++++++----
 src/fabric/src/fabric2_fdb.erl          |  34 +++----
 src/fabric/src/fabric2_security.erl     | 142 --------------------------
 src/fabric/src/fabric2_server.erl       |   8 +-
 src/fabric/src/fabric2_util.erl         |  38 ++++---
 8 files changed, 202 insertions(+), 324 deletions(-)

diff --git a/src/fabric/include/fabric.hrl b/src/fabric/include/fabric.hrl
index 202304a..7292538 100644
--- a/src/fabric/include/fabric.hrl
+++ b/src/fabric/include/fabric.hrl
@@ -13,10 +13,6 @@
 -include_lib("eunit/include/eunit.hrl").
 
 
--define(uint2bin(I), binary:encode_unsigned(I, little)).
--define(bin2uint(I), binary:decode_unsigned(I, little)).
-
-
 -record(collector, {
     db_name=nil,
     query_args,
diff --git a/src/fabric/src/fabric2.erl b/src/fabric/src/fabric2.erl
deleted file mode 100644
index 6acf23f..0000000
--- a/src/fabric/src/fabric2.erl
+++ /dev/null
@@ -1,116 +0,0 @@
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
--module(fabric2).
-
-
-
-
-
-
-
-
-
-
-open_doc(Db, DocId, Options) ->
-    fabric2_db:with_tx(Db, fun(TxDb) ->
-        case fabric2_doc:get_fdi(TxDb, DocId) of
-            not_found ->
-                {not_found, missing};
-            #full_doc_info{} = FDI ->
-                {_, Path} = couch_doc:to_doc_info_path(FDI),
-                case fabric2_doc:open(TxDb, DocId, Path) of
-                    #doc{} = Doc -> {ok, Doc};
-                    Error -> Error
-                end
-        end
-    end).
-
-
-open_revs(Db, DocId, Revs, Options) ->
-    fabric2_db:with_tx(Db, fun(TxDb) ->
-        case fabrci2_doc:get_fdi(TxDb, DocId) of
-            not_found ->
-                {not_found, missing};
-            #full_doc_info{} = FDI ->
-                case fabric2_doc:open_revs(TxDb, FDI, Revs, Options) of
-                    [_ | _] = Opened -> {ok, Opened};
-                    Error -> Error
-                end
-        end
-    end).
-
-
-update_doc(Db, Doc, Options) ->
-    fabric2_db:with_tx(Db, fun(TxDb) ->
-        case fabric2_doc:update(TxDb, Doc, opts(Options)) of
-            {ok, []} ->
-                % replication no-op
-                #doc{revs = {Pos, [RevId | _]}} = doc(Db, Doc),
-                {ok, {Pos, RevId}};
-            {ok, NewRev} ->
-                {ok, NewRev};
-           {error, Error} ->
-               throw(Error)
-        end
-    end).
-
-
-update_docs(DbName, Docs, Options) when is_binary(DbName) ->
-    update_docs(open_db(DbName, Options), Docs, Options);
-
-update_docs(Db, Docs, Options) ->
-    fabric2_db:with_tx(Db, fun(TxDb) ->
-        {Resps, Status} = lists:mapfoldl(fun(Doc, Acc) ->
-            case fabric2_doc:update(TxDb, Doc, opts(Options)) of
-                {ok, _} = Resp ->
-                    {Resp, Acc};
-                {error, _} = Resp ->
-                    {Resp, error}
-            end
-        end, ok, Docs),
-        {Status, Resps}
-    end).
-
-
-docs(Db, Docs) ->
-    lists:map(fun(Doc) -> doc(Db, Doc) end, Docs).
-
-
-doc(_Db, #doc{} = Doc) ->
-    Doc;
-
-doc(Db, {_} = Doc) ->
-    couch_db:doc_from_json_obj_validate(Db, Doc);
-
-doc(_Db, Doc) ->
-    erlang:error({illegal_doc_format, Doc}).
-
-
-opts(Options) ->
-    lists:foldl(fun(Opt, Acc) ->
-        add_option(Opt, Acc)
-    end, Options, [user_ctx, io_priority]).
-
-
-add_option(Key, Options) ->
-    case couch_util:get_value(Key, Options) of
-        undefined ->
-            case erlang:get(Key) of
-                undefined ->
-                    Options;
-                Value ->
-                    [{Key, Value} | Options]
-            end;
-        _ ->
-            Options
-    end.
diff --git a/src/fabric/include/fabric2.hrl b/src/fabric/src/fabric2.hrl
similarity index 77%
rename from src/fabric/include/fabric2.hrl
rename to src/fabric/src/fabric2.hrl
index e56f84f..d63d350 100644
--- a/src/fabric/include/fabric2.hrl
+++ b/src/fabric/src/fabric2.hrl
@@ -11,11 +11,6 @@
 % the License.
 
 
--define(SYSTEM_DATABASES, [
-    <<"_dbs">>,
-    <<"_global_changes">>,
-    <<"_metadata">>,
-    <<"_nodes">>,
-    <<"_replicator">>,
-    <<"_users">>
-]).
+-define(uint2bin(I), binary:encode_unsigned(I, little)).
+-define(bin2uint(I), binary:decode_unsigned(I, little)).
+
diff --git a/src/fabric/src/fabric2_db.erl b/src/fabric/src/fabric2_db.erl
index 5df51dd..d172209 100644
--- a/src/fabric/src/fabric2_db.erl
+++ b/src/fabric/src/fabric2_db.erl
@@ -18,6 +18,10 @@
     open/2,
     delete/2,
 
+    is_admin/1,
+    check_is_admin/1,
+    check_is_member/1,
+
     name/1,
     get_after_doc_read_fun/1,
     get_before_doc_update_fun/1,
@@ -119,6 +123,7 @@
 ]).
 
 
+-include_lib("couch/include/couch_db.hrl").
 -include_lib("fabric/include/fabric2.hrl").
 
 
@@ -132,13 +137,13 @@
 
 
 create(DbName, Options) ->
-    Result = fabric2_util:transactional(DbName, Options, fun(TxDb) ->
+    Result = transactional(DbName, Options, fun(TxDb) ->
         case fabric2_fdb:db_exists(TxDb) of
             true ->
                 {error, file_exists};
             false ->
                 fabric2_fdb:db_create(TxDb)
-        end,
+        end
     end),
     % We cache outside of the transaction so that we're sure
     % that this request created the database
@@ -153,17 +158,17 @@ create(DbName, Options) ->
 open(DbName, Options) ->
     case fabric2_server:fetch(DbName) of
         #{} = Db ->
-            fabric2_util:transactional(Db, fun(TxDb) ->
+            with_tx(Db, fun(TxDb) ->
                 case fabric2_fdb:db_is_current(TxDb) of
                     true ->
                         Db;
                     false ->
-                        Reopend = fabric2_fdb:db_open(TxDb),
+                        Reopened = fabric2_fdb:db_open(TxDb),
                         fabric2_server:store(Reopened)
                 end
             end);
         undefined ->
-            fabric2_util:transactional(DbName, Options, fun(TxDb) ->
+            transactional(DbName, Options, fun(TxDb) ->
                 Opened = fabric2_fdb:db_open(TxDb),
                 fabric2_server:store(Opened)
             end)
@@ -178,6 +183,34 @@ delete(DbName, Options) ->
     end).
 
 
+is_admin(Db) ->
+    % TODO: Need to re-consider couch_db_plugin:check_is_admin/1
+    {SecProps} = get_security(Db),
+    UserCtx = get_user_ctx(Db),
+    {Admins} = get_admins(SecProps),
+    is_authorized(Admins, UserCtx).
+
+
+check_is_admin(Db) ->
+    case is_admin(Db) of
+        true ->
+            ok;
+        false ->
+            UserCtx = get_user_ctx(Db),
+            Reason = <<"You are not a db or server admin.">>,
+            throw_security_error(UserCtx, Reason)
+    end.
+
+
+check_is_member(Db) ->
+    case is_member(Db) of
+        true ->
+            ok;
+        false ->
+            UserCtx = get_user_ctx(Db),
+            throw_security_error(UserCtx)
+    end.
+
 
 name(#{name := DbName}) ->
     DbName.
@@ -190,7 +223,7 @@ get_after_doc_read_fun(#{after_doc_read := AfterDocRead}) ->
 get_before_doc_update_fun(#{before_doc_update := BeforeDocUpdate}) ->
     BeforeDocUpdate.
 
-get_commited_update_seq(#{} = Db) ->
+get_committed_update_seq(#{} = Db) ->
     get_update_seq(Db).
 
 
@@ -198,7 +231,7 @@ get_compacted_seq(#{} = Db) ->
     get_update_seq(Db).
 
 
-get_compactor_pid(#{} = Db) ->
+get_compactor_pid(#{} = _Db) ->
     nil.
 
 
@@ -211,7 +244,7 @@ get_db_info(#{} = Db) ->
         {cluster, {[{n, 0}, {q, 0}, {r, 0}, {w, 0}]}},
         {compact_running, false},
         {data_size, 0},
-        {db_name, DbName},
+        {db_name, name(Db)},
         {disk_format_version, 0},
         {disk_size, 0},
         {instance_start_time, <<"0">>},
@@ -246,7 +279,7 @@ get_doc_count(Db, Key) ->
     end).
 
 
-get_instance_startime(#{}) ->
+get_instance_start_time(#{}) ->
     0.
 
 
@@ -271,6 +304,10 @@ get_update_seq(#{} = Db) ->
     end.
 
 
+get_user_ctx(#{user_ctx := UserCtx}) ->
+    UserCtx.
+
+
 get_uuid(#{uuid := UUID}) ->
     UUID.
 
@@ -336,7 +373,7 @@ open_doc(#{} = Db, DocId) ->
     open_doc(Db, DocId, []).
 
 
-open_doc(#{} = Db, DocId, Options) ->
+open_doc(#{} = Db, DocId, _Options) ->
     with_tx(Db, fun(TxDb) ->
         case fabric2_fdb:get_full_doc_info(TxDb, DocId) of
             not_found ->
@@ -372,7 +409,7 @@ open_doc_revs(Db, FDI, Revs, Options) ->
                     % We have the rev in our list but know nothing about it
                     {{not_found, missing}, {Pos, Rev}};
                 _ ->
-                    case fabric2_fdb:get_doc_body(Db, Id, RevPath) of
+                    case fabric2_fdb:get_doc_body(TxDb, Id, RevPath) of
                         #doc{} = Doc -> {ok, Doc};
                         Else -> {Else, {Pos, Rev}}
                     end
@@ -400,7 +437,7 @@ update_docs(Db, Docs) ->
 update_docs(Db, Docs, Options) ->
     with_tx(Db, fun(TxDb) ->
         {Resps, Status} = lists:mapfoldl(fun(Doc, Acc) ->
-            case fabric2_doc:update(TxDb, Doc, opts(Options)) of
+            case fabric2_doc:update(TxDb, Doc, Options) of
                 {ok, _} = Resp ->
                     {Resp, Acc};
                 {error, _} = Resp ->
@@ -440,6 +477,92 @@ new_revid(Doc) ->
     Doc#doc{revs = {OldStart + 1, [Rev | OldRevs]}}.
 
 
+is_member(Db) ->
+    {SecProps} = get_security(Db),
+    case is_admin(Db) of
+        true ->
+            true;
+        false ->
+            case is_public_db(SecProps) of
+                true ->
+                    true;
+                false ->
+                    {Members} = get_members(SecProps),
+                    UserCtx = get_user_ctx(Db),
+                    is_authorized(Members, UserCtx)
+            end
+    end.
+
+
+is_authorized(Group, UserCtx) ->
+    #user_ctx{
+        name = UserName,
+        roles = UserRoles
+    } = UserCtx,
+    Names = fabric2_util:get_value(<<"names">>, Group, []),
+    Roles = fabric2_util:get_value(<<"roles">>, Group, []),
+    case check_security(roles, UserRoles, [<<"_admin">> | Roles]) of
+        true ->
+            true;
+        false ->
+            check_security(names, UserName, Names)
+    end.
+
+
+check_security(roles, [], _) ->
+    false;
+check_security(roles, UserRoles, Roles) ->
+    UserRolesSet = ordsets:from_list(UserRoles),
+    RolesSet = ordsets:from_list(Roles),
+    not ordsets:is_disjoint(UserRolesSet, RolesSet);
+check_security(names, _, []) ->
+    false;
+check_security(names, null, _) ->
+    false;
+check_security(names, UserName, Names) ->
+    lists:member(UserName, Names).
+
+
+throw_security_error(#user_ctx{name = null} = UserCtx) ->
+    Reason = <<"You are not authorized to access this db.">>,
+    throw_security_error(UserCtx, Reason);
+throw_security_error(#user_ctx{name = _} = UserCtx) ->
+    Reason = <<"You are not allowed to access this db.">>,
+    throw_security_error(UserCtx, Reason).
+
+
+throw_security_error(#user_ctx{} = UserCtx, Reason) ->
+    Error = security_error_type(UserCtx),
+    throw({Error, Reason}).
+
+
+security_error_type(#user_ctx{name = null}) ->
+    unauthorized;
+security_error_type(#user_ctx{name = _}) ->
+    forbidden.
+
+
+is_public_db(SecProps) ->
+    {Members} = get_members(SecProps),
+    Names = fabric2_util:get_value(<<"names">>, Members, []),
+    Roles = fabric2_util:get_value(<<"roles">>, Members, []),
+    Names =:= [] andalso Roles =:= [].
+
+
+get_admins(SecProps) ->
+    fabric2_util:get_value(<<"admins">>, SecProps, {[]}).
+
+
+get_members(SecProps) ->
+    % we fallback to readers here for backwards compatibility
+    case fabric2_util:get_value(<<"members">>, SecProps) of
+        undefined ->
+            fabric2_util:get_value(<<"readers">>, SecProps, {[]});
+        Members ->
+            Members
+    end.
+
+
 % TODO: Handle _local docs separately.
 update_doc_int(#{} = Db, #doc{} = Doc0, Options) ->
     UpdateType = case lists:member(replicated_changes, Options) of
@@ -449,7 +572,7 @@ update_doc_int(#{} = Db, #doc{} = Doc0, Options) ->
 
     try
         FDI1 = fabric2_fdb:get_full_doc_info(Db, Doc0#doc.id),
-        Doc1 = prep_and_validate(TxDb, FDI1, Doc0, UpdateType),
+        Doc1 = prep_and_validate(Db, FDI1, Doc0, UpdateType),
         Doc2 = case UpdateType of
             interactive_edit -> new_revid(Doc1);
             replicated_changes -> Doc1
@@ -466,7 +589,7 @@ update_doc_int(#{} = Db, #doc{} = Doc0, Options) ->
         end,
         NewExists = not FDI3#full_doc_info.deleted,
 
-        ok = fabric2_fdb:write_doc(Db, FDI3, Doc3)
+        ok = fabric2_fdb:write_doc(Db, FDI3, Doc3),
 
         case {OldExists, NewExists} of
             {false, true} ->
@@ -482,6 +605,9 @@ update_doc_int(#{} = Db, #doc{} = Doc0, Options) ->
         % Need to count design documents
         % Need to track db size changes
 
+        #doc{
+            revs = {RevStart, [Rev | _]}
+        } = Doc3,
         {ok, {RevStart, Rev}}
     catch throw:{?MODULE, Return} ->
         Return
@@ -526,9 +652,9 @@ prep_and_validate(Db, FDI, Doc, interactive_edit) ->
                     ?RETURN({error, conflict})
             end
     end,
-    prep_and_validate(TxDb, Doc, GetDocFun);
+    prep_and_validate(Db, Doc, GetDocFun);
 
-prep_and_validate(TxDb, FDI, Doc, replicated_changes) ->
+prep_and_validate(Db, FDI, Doc, replicated_changes) ->
     #full_doc_info{
         rev_tree = RevTree
     } = FDI,
@@ -570,7 +696,7 @@ prep_and_validate(TxDb, FDI, Doc, replicated_changes) ->
             ?RETURN({ok, []})
     end,
 
-    prep_and_validate(TxDb, Doc, GetDocFun).
+    prep_and_validate(Db, Doc, GetDocFun).
 
 
 prep_and_validate(Db, Doc, GetDocBody) ->
@@ -606,7 +732,7 @@ merge_rev_tree(FDI, Doc, interactive_edit) when FDI#full_doc_info.deleted ->
             % Update the new doc based on revisions in OldInfo
             #doc_info{revs=[WinningRev | _]} = couch_doc:to_doc_info(FDI),
             #rev_info{rev={OldPos, OldRev}} = WinningRev,
-            Body = case couch_util:get_value(comp_body, Doc#doc.meta) of
+            Body = case fabric2_util:get_value(comp_body, Doc#doc.meta) of
                 CompBody when is_binary(CompBody) ->
                     couch_compress:decompress(CompBody);
                 _ ->
@@ -676,9 +802,6 @@ merge_rev_tree(FDI, Doc, replicated_changes) ->
 
 
 validate_doc_update(Db, #doc{id = <<"_design/", _/binary>>} = Doc, _) ->
-    #{
-        security_doc := Security
-    } = Db,
     case catch check_is_admin(Db) of
         ok -> validate_ddoc(Db, Doc);
         Error -> ?RETURN(Error)
@@ -693,7 +816,7 @@ validate_doc_update(Db, Doc, GetDiskDocFun) ->
     } = Db,
     Fun = fun() ->
         DiskDoc = GetDiskDocFun(),
-        JsonCtx = fabric2_util:user_ctx_to_json(TxDb),
+        JsonCtx = fabric2_util:user_ctx_to_json(UserCtx),
         try
             lists:map(fun(VDU) ->
                 case VDU(Doc, DiskDoc, JsonCtx, Security) of
@@ -742,6 +865,12 @@ find_prev_known_rev(Pos, [{_Rev, #leaf{}} | _] = DocPath) ->
     {Pos, [Rev || {Rev, _Val} <- DocPath]}.
 
 
+transactional(DbName, Options, Fun) ->
+    fabric2_util:transactional(fun(Tx) ->
+        Fun(fabric2_fdb:init(Tx, DbName, Options))
+    end).
+
+
 with_tx(#{tx := undefined} = Db, Fun) ->
     fabric2_util:transactional(fun(Tx) ->
         Fun(Db#{tx => Tx})
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index 4764331..e5bd81a 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -38,6 +38,10 @@
 ]).
 
 
+-include("couch/include/couch_db.hrl").
+-include("fabric2.hrl").
+
+
 % This will eventually be the `\xFFmetadataVersion` key that is
 % currently only available in FoundationDB master.
 %
@@ -55,18 +59,20 @@
 -define(CLUSTER_CONFIG, 0).
 -define(ALL_DBS, 1).
 -define(DBS, 15).
+
 -define(DB_CONFIG, 16).
 -define(DB_STATS, 17).
 -define(DB_ALL_DOCS, 18).
 -define(DB_CHANGES, 19).
--define(DB_DOCS, 20).
--define(DB_REVS, 21).
+-define(DB_REVS, 20).
+-define(DB_DOCS, 21).
+-define(DB_LOCAL_DOCS, 22).
 
 
 % Various utility macros
 
 -define(REQUIRE_TX(Db), {erlfdb_transaction, _} = maps:get(Db, tx)).
--define(REQUIRE_CURRENT(Db), true = db_is_current(Db)).
+-define(REQUIRE_CURRENT(Db), true = is_current(Db)).
 
 -define(UNSET_VS, {versionstamp, 16#FFFFFFFFFFFFFFFF, 16#FFFF}).
 
@@ -95,7 +101,7 @@ create(#{} = Db) ->
     % we're just using the DbName so that debugging is easier.
     DbKey = erlfdb_tuple:pack({?ALL_DBS, DbName}, LayerPrefix),
     DbPrefix = erlfdb_tuple:pack({?DBS, DbName}, LayerPrefix),
-    ets:set(Tx, DbKey, DbPrefix),
+    erlfdb:set(Tx, DbKey, DbPrefix),
 
     UUID = fabric2_util:uuid(),
 
@@ -121,7 +127,7 @@ create(#{} = Db) ->
         db_prefix => DbPrefix,
         version => Version,
         revs_limit => 1000,
-        security_doc => {[]}
+        security_doc => {[]},
         validate_doc_update_funs => [],
 
         user_ctx => #user_ctx{},
@@ -161,7 +167,6 @@ open(#{} = Db0) ->
         after_doc_read => undefined
     },
 
-    Config = db_get_config(Db1),
     lists:foldl(fun({Key, Val}) ->
         case Key of
             <<"uuid">> ->
@@ -171,7 +176,7 @@ open(#{} = Db0) ->
             <<"security_doc">> ->
                 Db1#{security_doc => ?JSON_DECODE(Val)}
         end
-    end, Db1, db_get_config(Db1)).
+    end, Db1, get_config(Db1)).
 
 
 delete(#{} = Db) ->
@@ -186,7 +191,7 @@ delete(#{} = Db) ->
     DbKey = erlfdb_tuple:pack({?DBS, DbName}, LayerPrefix),
     erlfdb:clear(Tx, DbKey),
     erlfdb:clear_range_startswith(Tx, DbPrefix),
-    bump_metadata_version(),
+    bump_metadata_version(Db),
     ok.
 
 
@@ -207,7 +212,7 @@ exists(#{name := DbName} = Db) when is_binary(DbName) ->
 is_current(#{} = Db) ->
     ?REQUIRE_TX(Db),
     #{
-        name := DbName,
+        tx := Tx,
         md_version := MetaDataVersion
     } = Db,
 
@@ -220,7 +225,6 @@ is_current(#{} = Db) ->
 get_info(#{} = Db) ->
     ?REQUIRE_CURRENT(Db),
     #{
-        name := DbName,
         tx := Tx,
         db_prefix := DbPrefix
     } = Db,
@@ -361,10 +365,6 @@ store_doc(#{} = Db, #full_doc_info{} = FDI, #doc{} = Doc) ->
         update_seq = OldUpdateSeq
     } = FDI,
 
-    #doc{
-        revs = {RevStart, [Rev | _]}
-    } = Doc,
-
     % Delete old entry in changes feed
     OldSeqKey = erlfdb_tuple:pack({?DB_CHANGES, OldUpdateSeq}, DbPrefix),
     erlfdb:clear(Tx, OldSeqKey),
@@ -378,7 +378,7 @@ store_doc(#{} = Db, #full_doc_info{} = FDI, #doc{} = Doc) ->
     erlfdb:set(Tx, NewDocKey, NewDocVal),
 
     % Update revision tree entry
-    {NewFDIKey, NewFDIVal} = fdi_to_fdb(TxDb, FDI),
+    {NewFDIKey, NewFDIVal} = fdi_to_fdb(Db, FDI),
     erlfdb:set_versionstamped_value(Tx, NewFDIKey, NewFDIVal).
 
 
@@ -453,7 +453,7 @@ fdi_to_fdb(Db, #full_doc_info{} = FDI) ->
     ValTuple = {
         Deleted,
         RevTreeBin,
-        {versionstamp, 16#FFFFFFFFFFFFFFFF, 16#FFFF}
+        ?UNSET_VS
     },
     Val = erlfdb_tuple:pack_vs(ValTuple),
     {Key, Val}.
@@ -487,4 +487,4 @@ fdb_to_fdi(_Db, Id, Bin) when is_binary(Bin) ->
         update_seq = UpdateSeq
     };
 fdb_to_fdi(_Db, _Id, not_found) ->
-    not_found.
\ No newline at end of file
+    not_found.
diff --git a/src/fabric/src/fabric2_security.erl b/src/fabric/src/fabric2_security.erl
deleted file mode 100644
index b3f1388..0000000
--- a/src/fabric/src/fabric2_security.erl
+++ /dev/null
@@ -1,142 +0,0 @@
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
--module(fabric_security).
-
-
--export([
-    check_is_admin/2,
-    check_is_member/2,
-
-    is_admin/2,
-    is_member/2
-]).
-
-
--include_lib("couch/include/couch_db.hrl").
-
-
-check_is_admin(DbName, UserCtx) ->
-    case is_admin(DbName, UserCtx) of
-        true ->
-            ok;
-        false ->
-            Reason = <<"You are not a db or server admin.">>,
-            throw_security_error(UserCtx, Reason)
-    end.
-
-
-check_is_member(DbName, UserCtx) ->
-    case is_member(DbName, UserCtx) of
-        true ->
-            ok;
-        false ->
-            throw_security_error(UserCtx)
-    end.
-
-
-is_admin(DbName, UserCtx) when is_binary(DbName) ->
-    {SecProps} = fabric2:get_security(DbName),
-    is_admin(SecProps, UserCtx);
-
-is_admin(SecProps, UserCtx) ->
-    % Need to re-consider couch_db_plugin:check_is_admin/1
-    {Admins} = get_admins(SecProps),
-    is_authorized(Admins, UserCtx).
-
-
-is_member(DbName, UserCtx) when is_binary(DbName) ->
-    {SecProps} = fabric2:get_security(DbName),
-    is_member(SecProps, UserCtx);
-
-is_member(SecProps, UserCtx) ->
-    case is_admin(SecProps, UserCtx) of
-        true ->
-            true;
-        false ->
-            case is_public_db(SecProps) of
-                true ->
-                    true;
-                false ->
-                    {Members} = get_members(SecProps),
-                    is_authorized(Members, UserCtx)
-            end
-    end.
-
-
-is_authorized(Group, UserCtx) ->
-    #user_ctx{
-        name = UserName,
-        roles = UserRoles
-    } = UserCtx,
-    Names = couch_util:get_value(<<"names">>, Group, []),
-    Roles = couch_util:get_value(<<"roles">>, Group, []),
-    case check_security(roles, UserRoles, [<<"_admin">> | Roles]) of
-        true ->
-            true;
-        false ->
-            check_security(names, UserName, Names)
-    end.
-
-
-check_security(roles, [], _) ->
-    false;
-check_security(roles, UserRoles, Roles) ->
-    UserRolesSet = ordsets:from_list(UserRoles),
-    RolesSet = ordsets:from_list(Roles),
-    not ordsets:is_disjoint(UserRolesSet, RolesSet);
-check_security(names, _, []) ->
-    false;
-check_security(names, null, _) ->
-    false;
-check_security(names, UserName, Names) ->
-    lists:member(UserName, Names).
-
-
-throw_security_error(#user_ctx{name=null}=UserCtx) ->
-    Reason = <<"You are not authorized to access this db.">>,
-    throw_security_error(UserCtx, Reason);
-throw_security_error(#user_ctx{name=_}=UserCtx) ->
-    Reason = <<"You are not allowed to access this db.">>,
-    throw_security_error(UserCtx, Reason).
-
-
-throw_security_error(#user_ctx{}=UserCtx, Reason) ->
-    Error = security_error_type(UserCtx),
-    throw({Error, Reason}).
-
-
-security_error_type(#user_ctx{name=null}) ->
-    unauthorized;
-security_error_type(#user_ctx{name=_}) ->
-    forbidden.
-
-
-is_public_db(SecProps) ->
-    {Members} = get_members(SecProps),
-    Names = couch_util:get_value(<<"names">>, Members, []),
-    Roles = couch_util:get_value(<<"roles">>, Members, []),
-    Names =:= [] andalso Roles =:= [].
-
-
-get_admins(SecProps) ->
-    couch_util:get_value(<<"admins">>, SecProps, {[]}).
-
-
-get_members(SecProps) ->
-    % we fallback to readers here for backwards compatibility
-    case couch_util:get_value(<<"members">>, SecProps) of
-        undefined ->
-            couch_util:get_value(<<"readers">>, SecProps, {[]});
-        Members ->
-            Members
-    end.
diff --git a/src/fabric/src/fabric2_server.erl b/src/fabric/src/fabric2_server.erl
index 5822331..9a0e4fa 100644
--- a/src/fabric/src/fabric2_server.erl
+++ b/src/fabric/src/fabric2_server.erl
@@ -32,6 +32,9 @@
 ]).
 
 
+-include_lib("couch/include/couch_db.hrl").
+
+
 -define(CLUSTER_FILE, "/usr/local/etc/foundationdb/fdb.cluster").
 
 
@@ -41,7 +44,7 @@ start_link() ->
 
 fetch(DbName) when is_binary(DbName) ->
     case ets:lookup(?MODULE, DbName) of
-        [{DbName, #{} = Db] -> Db;
+        [{DbName, #{} = Db}] -> Db;
         [] -> undefined
     end.
 
@@ -51,7 +54,7 @@ store(#{name := DbName} = Db0) when is_binary(DbName) ->
         tx => undefined,
         user_ctx => #user_ctx{}
     },
-    true = ets:insert(?MODULE, {DbName, Db1}}),
+    true = ets:insert(?MODULE, {DbName, Db1}),
     Db1.
 
 
@@ -66,7 +69,6 @@ init(_) ->
     ClusterStr = config:get("erlfdb", "cluster_file", ?CLUSTER_FILE),
     Db = erlfdb:open(iolist_to_binary(ClusterStr)),
     application:set_env(fabric, db, Db),
-    init_cluster(Db),
 
     {ok, nil}.
 
diff --git a/src/fabric/src/fabric2_util.erl b/src/fabric/src/fabric2_util.erl
index 1c47222..230a584 100644
--- a/src/fabric/src/fabric2_util.erl
+++ b/src/fabric/src/fabric2_util.erl
@@ -14,26 +14,28 @@
 
 
 -export([
-    transactional/2,
-    transactional/3,
-
+    transactional/1,
     get_db_handle/0,
 
     user_ctx_to_json/1,
 
-    uuid/0,
-
+    get_value/2,
+    get_value/3,
     to_hex/1,
+    uuid/0,
 
     debug_cluster/0,
     debug_cluster/2
 ]).
 
 
+-include_lib("couch/include/couch_db.hrl").
+
+
 -define(PDICT_DB_KEY, '$erlfdb_handle').
 
 
-trasactional(Fun) when is_function(Fun, 1) ->
+transactional(Fun) when is_function(Fun, 1) ->
     Db = get_db_handle(),
     erlfdb:transactional(Db, Fun).
 
@@ -53,14 +55,22 @@ user_ctx_to_json(Db) ->
     UserCtx = fabric2_db:get_user_ctx(Db),
     {[
         {<<"db">>, fabric2_db:name(Db)},
-        {<<"name">>, Ctx#user_ctx.name},
-        {<<"roles">>, Ctx#user_ctx.roles}
+        {<<"name">>, UserCtx#user_ctx.name},
+        {<<"roles">>, UserCtx#user_ctx.roles}
     ]}.
 
 
+get_value(Key, List) ->
+    get_value(Key, List, undefined).
 
-uuid() ->
-    to_hex(crypto:strong_rand_bytes(16)).
+
+get_value(Key, List, Default) ->
+    case lists:keysearch(Key, 1, List) of
+        {value, {Key,Value}} ->
+            Value;
+        false ->
+            Default
+    end.
 
 
 to_hex(Bin) ->
@@ -70,7 +80,7 @@ to_hex(Bin) ->
 to_hex_int(<<>>) ->
     [];
 to_hex_int(<<Hi:4, Lo:4, Rest/binary>>) ->
-    [nibble_to_hex(Hi), nibble_to_hex(Lo) | to_hex(Rest)];
+    [nibble_to_hex(Hi), nibble_to_hex(Lo) | to_hex(Rest)].
 
 
 nibble_to_hex(I) ->
@@ -94,6 +104,10 @@ nibble_to_hex(I) ->
     end.
 
 
+uuid() ->
+    to_hex(crypto:strong_rand_bytes(16)).
+
+
 debug_cluster() ->
     debug_cluster(<<>>, <<16#FE, 16#FF, 16#FF>>).
 
@@ -106,4 +120,4 @@ debug_cluster(Start, End) ->
                     erlfdb_util:repr(Val)
                 ])
         end, erlfdb:get_range(Tx, Start, End))
-    end).
\ No newline at end of file
+    end).