couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rnew...@apache.org
Subject [06/13] couch commit: updated refs/heads/master to 311ba94
Date Wed, 12 Aug 2015 15:54:06 GMT
Add couch_db_plugin:validate_dbname/2


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

Branch: refs/heads/master
Commit: 0cf35ce2fa643a814afadfe394d1516d1fe4cd84
Parents: 1c4f6ee
Author: ILYA Khlopotov <iilyak@ca.ibm.com>
Authored: Fri Jun 19 10:32:39 2015 -0700
Committer: ILYA Khlopotov <iilyak@ca.ibm.com>
Committed: Tue Aug 11 12:24:59 2015 -0700

----------------------------------------------------------------------
 src/couch.app.src              |  1 +
 src/couch_db.erl               | 35 ++++++++++++++++++-
 src/couch_db_plugin.erl        | 34 ++++++++++++++++++
 src/couch_server.erl           | 20 ++---------
 test/couch_db_plugin_tests.erl | 70 +++++++++++++++++++++++++++++++++++++
 5 files changed, 142 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/0cf35ce2/src/couch.app.src
----------------------------------------------------------------------
diff --git a/src/couch.app.src b/src/couch.app.src
index dc62c37..2d06932 100644
--- a/src/couch.app.src
+++ b/src/couch.app.src
@@ -42,6 +42,7 @@
         oauth,
 
         % ASF deps
+        couch_epi,
         b64url,
         couch_log,
         couch_event,

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/0cf35ce2/src/couch_db.erl
----------------------------------------------------------------------
diff --git a/src/couch_db.erl b/src/couch_db.erl
index 3c2eb31..81e2df8 100644
--- a/src/couch_db.erl
+++ b/src/couch_db.erl
@@ -34,10 +34,14 @@
 -export([check_md5/2, with_stream/3]).
 -export([monitored_by/1]).
 -export([normalize_dbname/1]).
+-export([validate_dbname/1]).
 
 -include_lib("couch/include/couch_db.hrl").
 
--define(VALID_DB_NAME, "^[a-z][a-z0-9\\_\\$()\\+\\-\\/]*$").
+-define(DBNAME_REGEX,
+    "^[a-z][a-z0-9\\_\\$()\\+\\-\\/]*" % use the stock CouchDB regex
+    "(\\.[0-9]{10,})?$" % but allow an optional shard timestamp at the end
+).
 
 start_link(DbName, Filepath, Options) ->
     case open_db_file(Filepath, Options) of
@@ -1480,3 +1484,32 @@ normalize_dbname(<<"shards/", _/binary>> = Path) ->
     lists:last(binary:split(mem3:dbname(Path), <<"/">>, [global]));
 normalize_dbname(DbName) ->
     DbName.
+
+validate_dbname(DbName) when is_list(DbName) ->
+    validate_dbname(?l2b(DbName));
+validate_dbname(DbName) when is_binary(DbName) ->
+    Normalized = normalize_dbname(DbName),
+    case couch_db_plugin:validate_dbname(DbName, Normalized) of
+        true ->
+            ok;
+        false ->
+            validate_dbname_int(DbName, Normalized)
+    end.
+
+validate_dbname_int(DbName, Normalized) when is_binary(DbName) ->
+    case re:run(DbName, ?DBNAME_REGEX, [{capture,none}, dollar_endonly]) of
+        match ->
+            ok;
+        nomatch ->
+            case is_systemdb(Normalized) of
+                true -> ok;
+                false -> {error, {illegal_database_name, DbName}}
+            end
+    end.
+
+is_systemdb(DbName) when is_list(DbName) ->
+    is_systemdb(?l2b(DbName));
+is_systemdb(<<"shards/", _/binary>> = Path) when is_binary(Path) ->
+    is_systemdb(normalize_dbname(Path));
+is_systemdb(DbName) when is_binary(DbName) ->
+    lists:member(?b2l(DbName), ?SYSTEM_DATABASES).

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/0cf35ce2/src/couch_db_plugin.erl
----------------------------------------------------------------------
diff --git a/src/couch_db_plugin.erl b/src/couch_db_plugin.erl
new file mode 100644
index 0000000..c192abc
--- /dev/null
+++ b/src/couch_db_plugin.erl
@@ -0,0 +1,34 @@
+% 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(couch_db_plugin).
+
+-export([validate_dbname/2]).
+
+-define(SERVICE_ID, couch_db).
+
+-include_lib("couch/include/couch_db.hrl").
+
+%% ------------------------------------------------------------------
+%% API Function Definitions
+%% ------------------------------------------------------------------
+
+validate_dbname(DbName, Normalized) ->
+    Handle = couch_epi:get_handle(?SERVICE_ID),
+    %% callbacks return true only if it specifically allow the given Id
+    couch_epi:any(Handle, ?SERVICE_ID, validate_dbname, [DbName, Normalized],
+        [ignore_providers]).
+
+
+%% ------------------------------------------------------------------
+%% Internal Function Definitions
+%% ------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/0cf35ce2/src/couch_server.erl
----------------------------------------------------------------------
diff --git a/src/couch_server.erl b/src/couch_server.erl
index 01f9a0e..93b6f5f 100644
--- a/src/couch_server.erl
+++ b/src/couch_server.erl
@@ -31,7 +31,6 @@
 
 -record(server,{
     root_dir = [],
-    dbname_regexp,
     max_dbs_open=?MAX_DBS_OPEN,
     dbs_open=0,
     start_time="",
@@ -142,16 +141,8 @@ maybe_add_sys_db_callbacks(DbName, Options) ->
 path_ends_with(Path, Suffix) ->
     Suffix == couch_db:normalize_dbname(Path).
 
-check_dbname(#server{dbname_regexp=RegExp}, DbName) ->
-    case re:run(DbName, RegExp, [{capture, none}]) of
-    nomatch ->
-        case lists:member(DbName, ?SYSTEM_DATABASES) of
-            true -> ok;
-            false -> {error, illegal_database_name, DbName}
-        end;
-    match ->
-        ok
-    end.
+check_dbname(#server{}, DbName) ->
+    couch_db:validate_dbname(DbName).
 
 is_admin(User, ClearPwd) ->
     case config:get("admins", User) of
@@ -192,15 +183,10 @@ init([]) ->
     ok = config:listen_for_changes(?MODULE, nil),
     ok = couch_file:init_delete_dir(RootDir),
     hash_admin_passwords(),
-    {ok, RegExp} = re:compile(
-        "^[a-z][a-z0-9\\_\\$()\\+\\-\\/]*" % use the stock CouchDB regex
-        "(\\.[0-9]{10,})?$" % but allow an optional shard timestamp at the end
-    ),
     ets:new(couch_dbs, [set, protected, named_table, {keypos, #db.name}]),
     ets:new(couch_dbs_pid_to_name, [set, protected, named_table]),
     process_flag(trap_exit, true),
     {ok, #server{root_dir=RootDir,
-                dbname_regexp=RegExp,
                 max_dbs_open=MaxDbsOpen,
                 update_lru_on_read=UpdateLruOnRead,
                 start_time=couch_util:rfc1123_date()}}.
@@ -208,7 +194,7 @@ init([]) ->
 terminate(Reason, Srv) ->
     couch_log:error("couch_server terminating with ~p, state ~2048p",
                     [Reason,
-                     Srv#server{dbname_regexp = redacted, lru = redacted}]),
+                     Srv#server{lru = redacted}]),
     ets:foldl(fun(#db{main_pid=Pid}, _) -> couch_util:shutdown_sync(Pid) end,
         nil, couch_dbs),
     ok.

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/0cf35ce2/test/couch_db_plugin_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_db_plugin_tests.erl b/test/couch_db_plugin_tests.erl
new file mode 100644
index 0000000..980980d
--- /dev/null
+++ b/test/couch_db_plugin_tests.erl
@@ -0,0 +1,70 @@
+% 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(couch_db_plugin_tests).
+
+-export([
+    validate_dbname/2
+]).
+
+-include_lib("couch/include/couch_eunit.hrl").
+-include_lib("couch/include/couch_db.hrl").
+
+-record(ctx, {pid, handle}).
+
+setup() ->
+    error_logger:tty(false),
+    application:start(couch_epi),
+    {ok, FunctionsPid} = couch_epi_functions:start_link(
+        test_app, {epi_key, couch_db}, {modules, [?MODULE]},
+        [{interval, 100}]),
+    ok = couch_epi_functions:wait(FunctionsPid),
+    #ctx{pid = FunctionsPid, handle = couch_epi:get_handle(couch_db)}.
+
+teardown(#ctx{pid = FunctionsPid}) ->
+    erlang:unlink(FunctionsPid),
+    couch_epi_functions:stop(FunctionsPid),
+    application:stop(couch_epi),
+    ok.
+
+validate_dbname({true, _Db}, _) -> true;
+validate_dbname({false, _Db}, _) -> false;
+validate_dbname({fail, _Db}, _) -> throw(validate_dbname).
+
+callback_test_() ->
+    {
+        "callback tests",
+        {
+            foreach, fun setup/0, fun teardown/1,
+            [
+                fun validate_dbname_match/0,
+                fun validate_dbname_no_match/0,
+                fun validate_dbname_throw/0
+            ]
+        }
+    }.
+
+
+validate_dbname_match() ->
+    ?_assertMatch(
+        {true, [validate_dbname, db]},
+        couch_db_plugin:validate_dbname({true, [db]}, db)).
+
+validate_dbname_no_match() ->
+    ?_assertMatch(
+        {false, [db]},
+        couch_db_plugin:validate_dbname({false, [db]}, db)).
+
+validate_dbname_throw() ->
+    ?_assertThrow(
+        validate_dbname,
+        couch_db_plugin:validate_dbname({fail, [db]}, db)).


Mime
View raw message