You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2014/08/01 11:04:54 UTC

[1/9] git commit: Initial commit

Repository: couchdb-cassim
Updated Branches:
  refs/heads/windsor-merge [created] cef09097a


Initial commit


Project: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/commit/c65e074f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/tree/c65e074f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/diff/c65e074f

Branch: refs/heads/windsor-merge
Commit: c65e074fa3ee1faf65390b3564128488515a355e
Parents: 
Author: Russell Branca <ch...@gmail.com>
Authored: Mon Dec 23 13:42:29 2013 -0800
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 18:12:50 2014 +0100

----------------------------------------------------------------------
 .gitignore |   6 ++
 LICENSE    | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 README.md  |   4 ++
 3 files changed, 212 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/c65e074f/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0c20ff0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.eunit
+deps
+*.o
+*.beam
+*.plt
+erl_crash.dump

http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/c65e074f/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e06d208
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   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.
+

http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/c65e074f/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..746a868
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+cassim
+======
+
+Open Sesame


[6/9] git commit: Delete old security docs when we set security

Posted by rn...@apache.org.
Delete old security docs when we set security

When we set security, we now also call out to cleanup old docs, which
will find all docs with same meta group id, where a meta group is a
user/database/type name, or more simply, a meta id with the suffix
removed. We use the meta group to fetch all previous security docs and
then delete the non current docs.

Note that the winning security doc may not in fact have the newest
suffix, as we could get into a situation with conflicts where the
winning rev is not the newest, so instead of sorting by suffix and
deleting everything but the newest, we instead delete everything
besides the meta id we know is the winner. We know the winning meta id
because in the set_security update we fetch the current known winning
id and pass that along to cleanup_old_docs/1.

The meta id format has been changed slightly, to append the suffix at
the end of the user/database/type group name, so that we can just chop
off the suffix and have the group.

Also, this moves the security_meta_id function into the
cassim_metadata_cache module. The motivation for this is that we're
using the suffix now to distinguish between different database
versions, which is general to all potential metadata types, not just
security, and so we want to keep the id definitions local to the cache
so we can more easily ensure all future id formats end in the suffix.

BugzId: 29571


Project: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/commit/1fe57773
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/tree/1fe57773
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/diff/1fe57773

Branch: refs/heads/windsor-merge
Commit: 1fe57773c2184fe6037a82239f18b133270eaf65
Parents: 02a5c7c
Author: Russell Branca <ch...@gmail.com>
Authored: Thu May 1 11:11:10 2014 -0700
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 18:18:00 2014 +0100

----------------------------------------------------------------------
 src/cassim_metadata_cache.erl | 53 +++++++++++++++++++++++++++++++++++++-
 src/cassim_security.erl       | 13 +++-------
 2 files changed, 56 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/1fe57773/src/cassim_metadata_cache.erl
----------------------------------------------------------------------
diff --git a/src/cassim_metadata_cache.erl b/src/cassim_metadata_cache.erl
index b0246d8..ea8d25c 100644
--- a/src/cassim_metadata_cache.erl
+++ b/src/cassim_metadata_cache.erl
@@ -34,7 +34,12 @@
     load_meta/2,
     load_meta/3,
     metadata_db/0,
-    metadata_db_exists/0
+    metadata_db_exists/0,
+    cleanup_old_docs/1
+]).
+
+-export([
+    security_meta_id/1
 ]).
 
 
@@ -65,6 +70,11 @@ metadata_db_exists() ->
     end.
 
 
+security_meta_id(DbName) ->
+    Suffix = list_to_binary(mem3:shard_suffix(DbName)),
+    <<DbName/binary, "/_security", Suffix/binary>>.
+
+
 start_link() ->
     gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
 
@@ -212,3 +222,44 @@ fetch_cached_meta(MetaId) ->
             couch_log:notice("cache miss on metadata ~s", [MetaId]),
             undefined
     end.
+
+
+cleanup_old_docs(MetaId) ->
+    MetaGroupId = filename:rootname(binary_to_list(MetaId)),
+    {ok, {_MetaId, Docs}} = fabric:all_docs(
+        metadata_db(),
+        fun cleanup_old_docs_callback/2,
+        {MetaId, []},
+        [
+            {start_key, list_to_binary(MetaGroupId)},
+            {end_key, list_to_binary(MetaGroupId ++ "Z")},
+            {include_docs, true}
+        ]
+    ),
+    {ok, _Revs} = delete_meta_docs(Docs),
+    ok.
+
+
+cleanup_old_docs_callback({total_and_offset, _Total, _Offset}, {MetaId, Acc}) ->
+    {ok, {MetaId, Acc}};
+cleanup_old_docs_callback({row, {Row}}, {MetaId, Acc}) ->
+    Id = couch_util:get_value(id, Row),
+    case MetaId == Id of
+        true ->
+            {ok, {MetaId, Acc}};
+        false ->
+            Doc = couch_doc:from_json_obj(couch_util:get_value(doc, Row)),
+            {ok, {MetaId, [Doc|Acc]}}
+    end;
+cleanup_old_docs_callback(complete, {MetaId, Acc}) ->
+    {ok, {MetaId, Acc}};
+cleanup_old_docs_callback({error, Reason}, {MetaId, Acc}) ->
+    couch_log:error("Unable clean up all old docs on ~p: ~p", [MetaId, Reason]),
+    {ok, {MetaId, Acc}}.
+
+
+delete_meta_docs(Docs0) ->
+    Docs = [D#doc{deleted=true, body={[]}} || D <- Docs0],
+    Options = [{user_ctx, #user_ctx{roles=[<<"_admin">>]}}],
+    DbName = metadata_db(),
+    fabric:update_docs(DbName, Docs, Options).

http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/1fe57773/src/cassim_security.erl
----------------------------------------------------------------------
diff --git a/src/cassim_security.erl b/src/cassim_security.erl
index 6cf4c68..daa9cfb 100644
--- a/src/cassim_security.erl
+++ b/src/cassim_security.erl
@@ -28,7 +28,6 @@
 ]).
 
 -export([
-    security_meta_id/1,
     validate_security_doc/1
 ]).
 
@@ -40,11 +39,6 @@
 -define(ADMIN_CTX, {user_ctx, ?ADMIN_USER}).
 
 
-security_meta_id(DbName) ->
-    Suffix = list_to_binary(mem3:shard_suffix(DbName)),
-    <<DbName/binary, Suffix/binary, "/_security">>.
-
-
 get_security(DbName) ->
     get_security(DbName, [?ADMIN_CTX]).
 
@@ -66,7 +60,7 @@ get_security(DbName, Options) ->
 
 get_security_doc(DbName0) when is_binary(DbName0) ->
     DbName = mem3:dbname(DbName0),
-    MetaId = security_meta_id(DbName),
+    MetaId = cassim_metadata_cache:security_meta_id(DbName),
     case cassim_metadata_cache:load_meta(MetaId) of
         undefined ->
             SecProps = fabric:get_security(DbName),
@@ -85,7 +79,7 @@ set_security(#db{name=DbName0}=Db, #doc{body=SecProps}=SecDoc0, Options) ->
     case cassim_metadata_cache:metadata_db_exists() of
         true ->
             DbName = mem3:dbname(DbName0),
-            MetaId = security_meta_id(DbName),
+            MetaId = cassim_metadata_cache:security_meta_id(DbName),
             SecDoc = SecDoc0#doc{id=MetaId},
             UserCtx = couch_util:get_value(user_ctx, Options, #user_ctx{}),
             MetaDbName = cassim_metadata_cache:metadata_db(),
@@ -95,6 +89,7 @@ set_security(#db{name=DbName0}=Db, #doc{body=SecProps}=SecDoc0, Options) ->
             {Status, Etag, {Body0}} =
                 chttpd_db:update_doc(MetaDb, MetaId, SecDoc, Options),
             Body = {proplists:delete(<<"_id">>, Body0)},
+            ok = cassim_metadata_cache:cleanup_old_docs(MetaId),
             {Status, Etag, Body};
         false ->
             fabric:set_security(Db, SecProps, Options)
@@ -103,7 +98,7 @@ set_security(#db{name=DbName0}=Db, #doc{body=SecProps}=SecDoc0, Options) ->
 
 migrate_security_props(DbName0, {SecProps}) ->
     DbName = mem3:dbname(DbName0),
-    MetaId = security_meta_id(DbName),
+    MetaId = cassim_metadata_cache:security_meta_id(DbName),
     SecDoc = #doc{id=MetaId, body={SecProps}},
     MetaDbName = cassim_metadata_cache:metadata_db(),
     MetaDb = #db{name=MetaDbName, user_ctx=?ADMIN_USER},


[3/9] git commit: Add metadata cache

Posted by rn...@apache.org.
Add metadata cache

BugzId: 29571


Project: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/commit/a6b65452
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/tree/a6b65452
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/diff/a6b65452

Branch: refs/heads/windsor-merge
Commit: a6b65452c081917be1556e9c7ff63cb085d9b643
Parents: 63f6e9a
Author: Russell Branca <ch...@gmail.com>
Authored: Wed Apr 30 14:11:48 2014 -0700
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 18:15:47 2014 +0100

----------------------------------------------------------------------
 src/cassim.app.src            |   3 +-
 src/cassim_metadata_cache.erl | 214 +++++++++++++++++++++++++++++++++++++
 2 files changed, 216 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/a6b65452/src/cassim.app.src
----------------------------------------------------------------------
diff --git a/src/cassim.app.src b/src/cassim.app.src
index ad1121d..f1b52ab 100644
--- a/src/cassim.app.src
+++ b/src/cassim.app.src
@@ -21,7 +21,8 @@
         stdlib,
         config,
         couch,
-        mem3
+        mem3,
+        couch_log
     ]},
     {mod, {cassim_app, []}},
     {env, []}

http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/a6b65452/src/cassim_metadata_cache.erl
----------------------------------------------------------------------
diff --git a/src/cassim_metadata_cache.erl b/src/cassim_metadata_cache.erl
new file mode 100644
index 0000000..b0246d8
--- /dev/null
+++ b/src/cassim_metadata_cache.erl
@@ -0,0 +1,214 @@
+% Copyright 2014 Cloudant
+%
+% 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(cassim_metadata_cache).
+-behaviour(gen_server).
+
+
+-export([
+    start_link/0
+]).
+
+-export([
+    init/1,
+    handle_call/3,
+    handle_cast/2,
+    handle_info/2,
+    terminate/2,
+    code_change/3
+]).
+
+-export([
+    load_meta/1,
+    load_meta/2,
+    load_meta/3,
+    metadata_db/0,
+    metadata_db_exists/0
+]).
+
+
+-record(st, {
+    changes_pid,
+    last_seq="0",
+    global_db
+}).
+
+
+-include_lib("couch/include/couch_db.hrl").
+
+
+-define(META_TABLE, metadata_cache).
+-define(TABLE_OPTS, [set, protected, named_table]).
+
+
+metadata_db() ->
+    config:get("couchdb", "metadata_db", "cassim").
+
+
+metadata_db_exists() ->
+    try mem3:shards(metadata_db()) of
+        _Shards ->
+            true
+    catch error:database_does_not_exist ->
+        false
+    end.
+
+
+start_link() ->
+    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+
+
+init([]) ->
+    ets:new(?META_TABLE, ?TABLE_OPTS),
+    GlobalDb = metadata_db(),
+    {Pid, _} = spawn_monitor(fun() -> listen_for_changes("0") end),
+    {ok, #st{changes_pid = Pid, global_db=GlobalDb}}.
+
+
+handle_call(get_seq, _From, State) ->
+    {reply, State#st.last_seq, State};
+handle_call({fetch_meta, MetaId}, _From, State) ->
+    {reply, load_meta_from_db(State#st.global_db, MetaId), State};
+handle_call({fetch_meta, Db, MetaId}, _From, State) ->
+    {reply, load_meta_from_db(Db, MetaId), State};
+handle_call(Call, _From, State) ->
+    couch_log:error("Unknown cassim_metadata_cache call: ~p~n", [Call]),
+    {noreply, State}.
+
+
+handle_cast({insert_cached_meta, {MetaId, Props}}, State) ->
+    ets:insert(?META_TABLE, {MetaId, Props}),
+    {noreply, State};
+handle_cast({delete_meta, MetaId}, State) ->
+    ets:delete(?META_TABLE, MetaId),
+    {noreply, State};
+handle_cast(_Msg, State) ->
+    {noreply, State}.
+
+
+handle_info({'DOWN', _, _, Pid, Reason}, #st{changes_pid=Pid} = State) ->
+    {Delay, Seq} = case Reason of
+        {seq, EndSeq} ->
+            {5 * 1000, EndSeq};
+        {error, database_does_not_exist} ->
+            couch_log:error("Metadata db ~p does not exist", [metadata_db()]),
+            {5 * 60 * 1000, State#st.last_seq};
+        _ ->
+            couch_log:notice("~p changes listener died ~p", [?MODULE, Reason]),
+            {5 * 1000, State#st.last_seq}
+    end,
+    timer:send_after(Delay, {start_listener, Seq}),
+    {noreply, State#st{last_seq=Seq, changes_pid=undefined}};
+handle_info({start_listener, Seq}, #st{changes_pid=undefined} = State) ->
+    {NewPid, _} = spawn_monitor(fun() -> listen_for_changes(Seq) end),
+    {noreply, State#st{changes_pid=NewPid}};
+handle_info(_Msg, State) ->
+    {noreply, State}.
+
+
+terminate(_Reason, #st{changes_pid = Pid}) ->
+    exit(Pid, kill),
+    ok.
+
+
+code_change(_OldVsn, #st{}=State, _Extra) ->
+    {ok, State}.
+
+
+%% internal functions
+
+
+listen_for_changes(Since) ->
+    DbName = metadata_db(),
+    Args = #changes_args{
+        feed = "continuous",
+        since = Since,
+        heartbeat = true,
+        include_docs = true
+    },
+    fabric:changes(DbName, fun changes_callback/2, Since, Args).
+
+
+changes_callback(start, Since) ->
+    {ok, Since};
+changes_callback({stop, EndSeq}, _) ->
+    exit({seq, EndSeq});
+changes_callback({change, {Change}}, _) ->
+    Id = couch_util:get_value(id, Change),
+    case couch_util:get_value(deleted, Change, false) of
+        true ->
+            gen_server:cast(?MODULE, {delete_meta, Id});
+        false ->
+            case couch_util:get_value(doc, Change) of
+                {error, Reason} ->
+                    couch_log:warn(
+                        "could not retrieve metadata doc ~s: ~p", [Id, Reason]);
+                Props ->
+                    gen_server:cast(?MODULE, {insert_cached_meta, {Id, Props}})
+            end
+    end,
+    {ok, couch_util:get_value(seq, Change)};
+changes_callback(timeout, EndSeq) ->
+    exit({seq, EndSeq});
+changes_callback({error, database_does_not_exist}, _EndSeq) ->
+    exit({error, database_does_not_exist});
+changes_callback({error, _}, EndSeq) ->
+    exit({seq, EndSeq}).
+
+
+%% internal metadata functions
+
+
+load_meta_from_db(DbName, MetaId) ->
+    try fabric:open_doc(DbName, MetaId, []) of
+        {ok, Doc} ->
+            couch_doc:to_json_obj(Doc, []);
+        _Else ->
+            couch_log:warn("no record of meta ~s", [MetaId]),
+            undefined
+    catch error:database_does_not_exist ->
+        undefined
+    end.
+
+
+load_meta(MetaId) ->
+    load_meta(MetaId, true).
+
+
+load_meta(MetaId, _UseCache=true) ->
+    case fetch_cached_meta(MetaId) of
+        undefined ->
+            load_meta(MetaId, false);
+        Props ->
+            Props
+    end;
+load_meta(MetaId, _UseCache=false) ->
+    gen_server:call(?MODULE, {fetch_meta, MetaId}).
+
+
+load_meta(MetaId, _UseCache=false, Db) ->
+    gen_server:call(?MODULE, {fetch_meta, Db, MetaId}).
+
+
+fetch_cached_meta(MetaId) ->
+    try ets:lookup(?META_TABLE, MetaId) of
+        [{MetaId, Props}] ->
+            Props;
+        [] ->
+            couch_log:notice("cache miss on metadata ~s", [MetaId]),
+            undefined
+        catch error:badarg ->
+            couch_log:notice("cache miss on metadata ~s", [MetaId]),
+            undefined
+    end.


[2/9] git commit: Initial app structure

Posted by rn...@apache.org.
Initial app structure

BugzId: 29571


Project: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/commit/63f6e9ae
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/tree/63f6e9ae
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/diff/63f6e9ae

Branch: refs/heads/windsor-merge
Commit: 63f6e9aefe9bf281e7ad0afe436c67e173ec7665
Parents: c65e074
Author: Russell Branca <ch...@gmail.com>
Authored: Wed Apr 30 14:11:28 2014 -0700
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 18:13:18 2014 +0100

----------------------------------------------------------------------
 .gitignore         |  1 +
 src/cassim.app.src | 28 ++++++++++++++++++++++++++++
 src/cassim_app.erl | 30 ++++++++++++++++++++++++++++++
 src/cassim_sup.erl | 41 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 100 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/63f6e9ae/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 0c20ff0..321d5bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 .eunit
 deps
+ebin
 *.o
 *.beam
 *.plt

http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/63f6e9ae/src/cassim.app.src
----------------------------------------------------------------------
diff --git a/src/cassim.app.src b/src/cassim.app.src
new file mode 100644
index 0000000..ad1121d
--- /dev/null
+++ b/src/cassim.app.src
@@ -0,0 +1,28 @@
+% Copyright 2014 Cloudant
+%
+% 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.
+
+{application, cassim, [
+    {description, "Application for metadata db and auth related functions"},
+    {vsn, git},
+    {registered, []},
+    {applications, [
+        kernel,
+        stdlib,
+        config,
+        couch,
+        mem3
+    ]},
+    {mod, {cassim_app, []}},
+    {env, []}
+]}.

http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/63f6e9ae/src/cassim_app.erl
----------------------------------------------------------------------
diff --git a/src/cassim_app.erl b/src/cassim_app.erl
new file mode 100644
index 0000000..13a4d83
--- /dev/null
+++ b/src/cassim_app.erl
@@ -0,0 +1,30 @@
+% Copyright 2014 Cloudant
+%
+% 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(cassim_app).
+
+
+-behaviour(application).
+
+
+%% Application callbacks
+-export([start/2, stop/1]).
+
+
+start(_StartType, _StartArgs) ->
+    cassim_sup:start_link().
+
+
+stop(_State) ->
+    ok.

http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/63f6e9ae/src/cassim_sup.erl
----------------------------------------------------------------------
diff --git a/src/cassim_sup.erl b/src/cassim_sup.erl
new file mode 100644
index 0000000..a34fa70
--- /dev/null
+++ b/src/cassim_sup.erl
@@ -0,0 +1,41 @@
+% Copyright 2014 Cloudant
+%
+% 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(cassim_sup).
+
+
+-behaviour(supervisor).
+
+
+-export([start_link/0]).
+
+-export([init/1]).
+
+
+start_link() ->
+    supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+
+init([]) ->
+    MetadataCache = {
+        cassim_metadata_cache,
+        {cassim_metadata_cache, start_link, []},
+        permanent,
+        100,
+        worker,
+        [cassim_metadata_cache]
+    },
+    {ok, {{one_for_one, 5, 10}, [MetadataCache]}}.
+


[4/9] git commit: Add top level API and security logic

Posted by rn...@apache.org.
Add top level API and security logic

BugzId: 29571


Project: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/commit/c1bb498b
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/tree/c1bb498b
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/diff/c1bb498b

Branch: refs/heads/windsor-merge
Commit: c1bb498b37d9055822fcd10d66adc6e305502ff7
Parents: a6b6545
Author: Russell Branca <ch...@gmail.com>
Authored: Wed Apr 30 14:12:03 2014 -0700
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 18:16:17 2014 +0100

----------------------------------------------------------------------
 src/cassim.erl          |  81 +++++++++++++++++
 src/cassim_security.erl | 204 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 285 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/c1bb498b/src/cassim.erl
----------------------------------------------------------------------
diff --git a/src/cassim.erl b/src/cassim.erl
new file mode 100644
index 0000000..b3debea
--- /dev/null
+++ b/src/cassim.erl
@@ -0,0 +1,81 @@
+% Copyright 2014 Cloudant
+%
+% 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(cassim).
+
+
+-export([
+    is_server_admin/1,
+    verify_is_admin/1,
+    verify_is_server_admin/1
+]).
+
+-export([
+    has_admin_role/1,
+    verify_admin_role/1
+]).
+
+-export([
+    get_security/1,
+    get_security/2,
+    set_security/2,
+    set_security/3
+]).
+
+
+-include_lib("couch/include/couch_db.hrl").
+
+
+verify_is_admin(#httpd{}=Req) ->
+    chttpd:verify_is_server_admin(Req).
+
+
+is_server_admin(#httpd{user_ctx=#user_ctx{roles=Roles}}) ->
+    lists:member(server_admin, Roles).
+
+
+verify_is_server_admin(#httpd{}=Req) ->
+    case is_server_admin(Req) of
+        true -> ok;
+        false -> throw({unauthorized, <<"You are not a server admin.">>})
+    end.
+
+
+has_admin_role(#user_ctx{roles=Roles}) ->
+    has_admin_role(Roles);
+has_admin_role(Roles) when is_list(Roles) ->
+    lists:member(<<"_admin">>, Roles) orelse lists:member(server_admin, Roles).
+
+
+verify_admin_role(Obj) ->
+    case has_admin_role(Obj) of
+        true -> ok;
+        false -> throw({unauthorized, <<"You are not a db or server admin.">>})
+    end.
+
+
+get_security(DbName) ->
+    cassim_security:get_security(DbName).
+
+
+get_security(DbName, Options) ->
+    cassim_security:get_security(DbName, Options).
+
+
+set_security(DbName, SecObj) ->
+    cassim_security:set_security(DbName, SecObj).
+
+
+set_security(DbName, SecObj, Options) ->
+    cassim_security:set_security(DbName, SecObj, Options).

http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/c1bb498b/src/cassim_security.erl
----------------------------------------------------------------------
diff --git a/src/cassim_security.erl b/src/cassim_security.erl
new file mode 100644
index 0000000..52fa56a
--- /dev/null
+++ b/src/cassim_security.erl
@@ -0,0 +1,204 @@
+% Copyright 2014 Cloudant
+%
+% 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(cassim_security).
+
+
+-export([
+    get_security/1,
+    get_security/2,
+    get_security_doc/1
+]).
+
+-export([
+    set_security/2,
+    set_security/3
+]).
+
+-export([
+    security_meta_id/1,
+    validate_security_doc/1
+]).
+
+
+-include_lib("couch/include/couch_db.hrl").
+
+
+-define(ADMIN_USER, #user_ctx{roles = [<<"_admin">>]}).
+-define(ADMIN_CTX, {user_ctx, ?ADMIN_USER}).
+
+
+security_meta_id(DbName) ->
+    <<DbName/binary, "/_security">>.
+
+
+get_security(DbName) ->
+    get_security(DbName, [?ADMIN_CTX]).
+
+
+get_security(#db{name=DbName}, Options) ->
+    get_security(DbName, Options);
+get_security(DbName, Options) ->
+    case cassim_metadata_cache:metadata_db_exists() of
+        true ->
+            UserCtx = couch_util:get_value(user_ctx, Options, #user_ctx{}),
+            Doc = get_security_doc(DbName),
+            {SecProps} = couch_doc:to_json_obj(Doc, []),
+            check_is_member(UserCtx, SecProps),
+            {proplists:delete(<<"_id">>, SecProps)};
+        false ->
+            fabric:get_security(DbName, Options)
+    end.
+
+
+get_security_doc(DbName0) when is_binary(DbName0) ->
+    DbName = mem3:dbname(DbName0),
+    MetaId = security_meta_id(DbName),
+    case cassim_metadata_cache:load_meta(MetaId) of
+        undefined ->
+            SecProps = fabric:get_security(DbName),
+            {ok, SecDoc} = migrate_security_props(DbName, SecProps),
+            SecDoc;
+        SecProps ->
+            couch_doc:from_json_obj(SecProps)
+    end.
+
+
+set_security(DbName, SecProps) ->
+    set_security(DbName, SecProps, [?ADMIN_CTX]).
+
+
+set_security(#db{name=DbName0}=Db, #doc{body=SecProps}=SecDoc0, Options) ->
+    case cassim_metadata_cache:metadata_db_exists() of
+        true ->
+            DbName = mem3:dbname(DbName0),
+            MetaId = security_meta_id(DbName),
+            SecDoc = SecDoc0#doc{id=MetaId},
+            UserCtx = couch_util:get_value(user_ctx, Options, #user_ctx{}),
+            MetaDbName = cassim_metadata_cache:metadata_db(),
+            MetaDb = #db{name=MetaDbName, user_ctx=?ADMIN_USER},
+            cassim:verify_admin_role(UserCtx),
+            ok = validate_security_doc(SecDoc),
+            {Status, Etag, {Body0}} =
+                chttpd_db:update_doc(MetaDb, MetaId, SecDoc, Options),
+            Body = {proplists:delete(<<"_id">>, Body0)},
+            {Status, Etag, Body};
+        false ->
+            fabric:set_security(Db, SecProps, Options)
+    end.
+
+
+migrate_security_props(DbName0, {SecProps}) ->
+    DbName = mem3:dbname(DbName0),
+    MetaId = security_meta_id(DbName),
+    SecDoc = #doc{id=MetaId, body={SecProps}},
+    MetaDbName = cassim_metadata_cache:metadata_db(),
+    MetaDb = #db{name=MetaDbName, user_ctx=?ADMIN_USER},
+    %% Better way to construct a new #doc{} with the rev?
+    {_, _, {Body}} = chttpd_db:update_doc(MetaDb, MetaId, SecDoc, [?ADMIN_CTX]),
+    Rev = proplists:get_value(rev, Body),
+    SecProps1 = lists:keystore(<<"_rev">>, 1, SecProps, {<<"_rev">>, Rev}),
+    SecDoc1 = couch_doc:from_json_obj({SecProps1}),
+    {ok, SecDoc1}.
+
+
+validate_security_doc(#doc{body={SecProps}}) ->
+    Admins = couch_util:get_value(<<"admins">>, SecProps, {[]}),
+    % we fallback to readers here for backwards compatibility
+    Members = couch_util:get_value(<<"members">>, SecProps,
+        couch_util:get_value(<<"readers">>, SecProps, {[]})),
+    ok = validate_names_and_roles(Admins),
+    ok = validate_names_and_roles(Members),
+    Users = couch_util:get_value(<<"cloudant">>, SecProps, {[]}),
+    ok = validate_cloudant_roles(Users),
+    ok.
+
+
+validate_names_and_roles({Props}) when is_list(Props) ->
+    lists:foreach(
+        fun(Name) ->
+            validate_roles_list(Name, couch_util:get_value(Name, Props, []))
+        end,
+        [<<"names">>, <<"roles">>]
+    ).
+
+
+validate_cloudant_roles({Props}) when is_list(Props) ->
+    lists:foreach(fun({U, R}) -> validate_roles_list(U, R) end, Props);
+validate_cloudant_roles(_) ->
+    throw("Cloudant field must be a set of name roles list pairs").
+
+
+validate_roles_list(Field, Roles) when is_list(Roles) ->
+    case lists:all(fun(X) -> is_binary(X) end, Roles) of
+        true -> ok;
+        false -> throw(binary_to_list(Field) ++ " must be a JSON list of strings")
+    end;
+validate_roles_list(Field, _Roles) ->
+    throw(binary_to_list(Field) ++ " must be a JSON list of strings").
+
+
+check_is_admin(#user_ctx{name=Name,roles=Roles}, SecProps) ->
+    {Admins} = get_admins(SecProps),
+    AdminRoles = [<<"_admin">> | couch_util:get_value(<<"roles">>, Admins, [])],
+    AdminNames = couch_util:get_value(<<"names">>, Admins,[]),
+    case AdminRoles -- Roles of
+    AdminRoles -> % same list, not an admin role
+        case AdminNames -- [Name] of
+        AdminNames -> % same names, not an admin
+            throw({unauthorized, <<"You are not a db or server admin.">>});
+        _ ->
+            ok
+        end;
+    _ ->
+        ok
+    end.
+
+
+check_is_member(#user_ctx{name=Name,roles=Roles}=UserCtx, SecProps) ->
+    case (catch check_is_admin(UserCtx, SecProps)) of
+    ok -> ok;
+    _ ->
+        {Members} = get_members(SecProps),
+        ReaderRoles = couch_util:get_value(<<"roles">>, Members,[]),
+        WithAdminRoles = [<<"_admin">> | ReaderRoles],
+        ReaderNames = couch_util:get_value(<<"names">>, Members,[]),
+        case ReaderRoles ++ ReaderNames of
+        [] -> ok; % no readers == public access
+        _Else ->
+            case WithAdminRoles -- Roles of
+            WithAdminRoles -> % same list, not an reader role
+                case ReaderNames -- [Name] of
+                ReaderNames -> % same names, not a reader
+                    ?LOG_DEBUG("Not a reader: UserCtx ~p vs Names ~p Roles ~p",[UserCtx, ReaderNames, WithAdminRoles]),
+                    throw({unauthorized, <<"You are not authorized to access this db.">>});
+                _ ->
+                    ok
+                end;
+            _ ->
+                ok
+            end
+        end
+    end.
+
+
+get_admins(SecProps) ->
+    couch_util:get_value(<<"admins">>, SecProps, {[]}).
+
+
+get_members(SecProps) ->
+    % we fallback to readers here for backwards compatibility
+    couch_util:get_value(<<"members">>, SecProps,
+        couch_util:get_value(<<"readers">>, SecProps, {[]})).


[5/9] git commit: Use shard suffix in the security metadata id

Posted by rn...@apache.org.
Use shard suffix in the security metadata id

The primary purpose here is to be able to distinguish between
different version of the same database name. We shouldn't have
security properties be inherited when a database is recreated. Adding
the suffix to the metadata id allows us to make this distinction, but
it also allows us to lazily deal with clearing out security docs for
old deleted database.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/commit/02a5c7ce
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/tree/02a5c7ce
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/diff/02a5c7ce

Branch: refs/heads/windsor-merge
Commit: 02a5c7ceae7da2e4f6bfb22e781f59c1d4e921bc
Parents: c1bb498
Author: Russell Branca <ch...@gmail.com>
Authored: Wed Apr 30 14:28:36 2014 -0700
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 18:16:34 2014 +0100

----------------------------------------------------------------------
 src/cassim_security.erl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/02a5c7ce/src/cassim_security.erl
----------------------------------------------------------------------
diff --git a/src/cassim_security.erl b/src/cassim_security.erl
index 52fa56a..6cf4c68 100644
--- a/src/cassim_security.erl
+++ b/src/cassim_security.erl
@@ -41,7 +41,8 @@
 
 
 security_meta_id(DbName) ->
-    <<DbName/binary, "/_security">>.
+    Suffix = list_to_binary(mem3:shard_suffix(DbName)),
+    <<DbName/binary, Suffix/binary, "/_security">>.
 
 
 get_security(DbName) ->


[9/9] git commit: Remove Cloudant copyright as prereq to ASF donation

Posted by rn...@apache.org.
Remove Cloudant copyright as prereq to ASF donation


Project: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/commit/cef09097
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/tree/cef09097
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/diff/cef09097

Branch: refs/heads/windsor-merge
Commit: cef09097a2520a3a18a8c36e309f6a0fc2739f42
Parents: 8f1812d
Author: Robert Newson <rn...@apache.org>
Authored: Wed Jul 16 12:58:55 2014 +0100
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 18:18:43 2014 +0100

----------------------------------------------------------------------
 src/cassim.app.src            | 2 --
 src/cassim.erl                | 2 --
 src/cassim_app.erl            | 2 --
 src/cassim_metadata_cache.erl | 2 --
 src/cassim_security.erl       | 2 --
 src/cassim_sup.erl            | 2 --
 6 files changed, 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/cef09097/src/cassim.app.src
----------------------------------------------------------------------
diff --git a/src/cassim.app.src b/src/cassim.app.src
index f1b52ab..4acc809 100644
--- a/src/cassim.app.src
+++ b/src/cassim.app.src
@@ -1,5 +1,3 @@
-% Copyright 2014 Cloudant
-%
 % 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://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/cef09097/src/cassim.erl
----------------------------------------------------------------------
diff --git a/src/cassim.erl b/src/cassim.erl
index 15b8570..e838c53 100644
--- a/src/cassim.erl
+++ b/src/cassim.erl
@@ -1,5 +1,3 @@
-% Copyright 2014 Cloudant
-%
 % 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://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/cef09097/src/cassim_app.erl
----------------------------------------------------------------------
diff --git a/src/cassim_app.erl b/src/cassim_app.erl
index 13a4d83..c6c313b 100644
--- a/src/cassim_app.erl
+++ b/src/cassim_app.erl
@@ -1,5 +1,3 @@
-% Copyright 2014 Cloudant
-%
 % 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://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/cef09097/src/cassim_metadata_cache.erl
----------------------------------------------------------------------
diff --git a/src/cassim_metadata_cache.erl b/src/cassim_metadata_cache.erl
index ea8d25c..1eb0fc9 100644
--- a/src/cassim_metadata_cache.erl
+++ b/src/cassim_metadata_cache.erl
@@ -1,5 +1,3 @@
-% Copyright 2014 Cloudant
-%
 % 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://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/cef09097/src/cassim_security.erl
----------------------------------------------------------------------
diff --git a/src/cassim_security.erl b/src/cassim_security.erl
index 0622b8c..b4033c5 100644
--- a/src/cassim_security.erl
+++ b/src/cassim_security.erl
@@ -1,5 +1,3 @@
-% Copyright 2014 Cloudant
-%
 % 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://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/cef09097/src/cassim_sup.erl
----------------------------------------------------------------------
diff --git a/src/cassim_sup.erl b/src/cassim_sup.erl
index a34fa70..a60e18b 100644
--- a/src/cassim_sup.erl
+++ b/src/cassim_sup.erl
@@ -1,5 +1,3 @@
-% Copyright 2014 Cloudant
-%
 % 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


[8/9] git commit: Don't fallback to using fabric:set_security

Posted by rn...@apache.org.
Don't fallback to using fabric:set_security

The return values from cassim:set_security are different than those in
fabric:set_security. This removes the fallback clause to simplify the
logic and moves the is_enabled check out into chttpd.

BugzId: 32070


Project: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/commit/8f1812d2
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/tree/8f1812d2
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/diff/8f1812d2

Branch: refs/heads/windsor-merge
Commit: 8f1812d20da351fc6f7abe58b5a6726db0c2e679
Parents: 80a17b0
Author: Russell Branca <ch...@apache.org>
Authored: Thu Jul 3 13:16:03 2014 -0700
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 18:18:33 2014 +0100

----------------------------------------------------------------------
 src/cassim_security.erl | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/8f1812d2/src/cassim_security.erl
----------------------------------------------------------------------
diff --git a/src/cassim_security.erl b/src/cassim_security.erl
index 250ce9d..0622b8c 100644
--- a/src/cassim_security.erl
+++ b/src/cassim_security.erl
@@ -75,25 +75,20 @@ set_security(DbName, SecProps) ->
     set_security(DbName, SecProps, [?ADMIN_CTX]).
 
 
-set_security(#db{name=DbName0}=Db, #doc{body=SecProps}=SecDoc0, Options) ->
-    case cassim_metadata_cache:metadata_db_exists() of
-        true ->
-            DbName = mem3:dbname(DbName0),
-            MetaId = cassim_metadata_cache:security_meta_id(DbName),
-            SecDoc = SecDoc0#doc{id=MetaId},
-            UserCtx = couch_util:get_value(user_ctx, Options, #user_ctx{}),
-            MetaDbName = cassim_metadata_cache:metadata_db(),
-            MetaDb = #db{name=MetaDbName, user_ctx=?ADMIN_USER},
-            cassim:verify_admin_role(UserCtx),
-            ok = validate_security_doc(SecDoc),
-            {Status, Etag, {Body0}} =
-                chttpd_db:update_doc(MetaDb, MetaId, SecDoc, Options),
-            Body = {proplists:delete(<<"_id">>, Body0)},
-            ok = cassim_metadata_cache:cleanup_old_docs(MetaId),
-            {Status, Etag, Body};
-        false ->
-            fabric:set_security(Db, SecProps, Options)
-    end.
+set_security(#db{name=DbName0}, #doc{}=SecDoc0, Options) ->
+    DbName = mem3:dbname(DbName0),
+    MetaId = cassim_metadata_cache:security_meta_id(DbName),
+    SecDoc = SecDoc0#doc{id=MetaId},
+    UserCtx = couch_util:get_value(user_ctx, Options, #user_ctx{}),
+    MetaDbName = cassim_metadata_cache:metadata_db(),
+    MetaDb = #db{name=MetaDbName, user_ctx=?ADMIN_USER},
+    cassim:verify_admin_role(UserCtx),
+    ok = validate_security_doc(SecDoc),
+    {Status, Etag, {Body0}} =
+        chttpd_db:update_doc(MetaDb, MetaId, SecDoc, Options),
+    Body = {proplists:delete(<<"_id">>, Body0)},
+    ok = cassim_metadata_cache:cleanup_old_docs(MetaId),
+    {Status, Etag, Body}.
 
 
 migrate_security_props(DbName0, {SecProps}) ->


[7/9] git commit: Add cassim:is_enabled

Posted by rn...@apache.org.
Add cassim:is_enabled

BugzId: 32070


Project: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/commit/80a17b00
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/tree/80a17b00
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-cassim/diff/80a17b00

Branch: refs/heads/windsor-merge
Commit: 80a17b0020b58a926713077cd26964a2375d59da
Parents: 1fe5777
Author: Russell Branca <ch...@apache.org>
Authored: Thu Jul 3 13:14:21 2014 -0700
Committer: Robert Newson <rn...@apache.org>
Committed: Wed Jul 30 18:18:25 2014 +0100

----------------------------------------------------------------------
 src/cassim.erl          | 8 ++++++++
 src/cassim_security.erl | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/80a17b00/src/cassim.erl
----------------------------------------------------------------------
diff --git a/src/cassim.erl b/src/cassim.erl
index b3debea..15b8570 100644
--- a/src/cassim.erl
+++ b/src/cassim.erl
@@ -16,6 +16,10 @@
 
 
 -export([
+    is_enabled/0
+]).
+
+-export([
     is_server_admin/1,
     verify_is_admin/1,
     verify_is_server_admin/1
@@ -37,6 +41,10 @@
 -include_lib("couch/include/couch_db.hrl").
 
 
+is_enabled() ->
+    cassim_metadata_cache:metadata_db_exists().
+
+
 verify_is_admin(#httpd{}=Req) ->
     chttpd:verify_is_server_admin(Req).
 

http://git-wip-us.apache.org/repos/asf/couchdb-cassim/blob/80a17b00/src/cassim_security.erl
----------------------------------------------------------------------
diff --git a/src/cassim_security.erl b/src/cassim_security.erl
index daa9cfb..250ce9d 100644
--- a/src/cassim_security.erl
+++ b/src/cassim_security.erl
@@ -46,7 +46,7 @@ get_security(DbName) ->
 get_security(#db{name=DbName}, Options) ->
     get_security(DbName, Options);
 get_security(DbName, Options) ->
-    case cassim_metadata_cache:metadata_db_exists() of
+    case cassim:is_enabled() of
         true ->
             UserCtx = couch_util:get_value(user_ctx, Options, #user_ctx{}),
             Doc = get_security_doc(DbName),