Merge pull request #1107 from javajolt/rts-1149-ts-security

RTS-1149: Add security tests for querying data
This commit is contained in:
Brett Hazen 2016-07-28 16:20:02 -06:00 committed by GitHub
commit b9f2173001
3 changed files with 1063 additions and 272 deletions

View File

@ -0,0 +1,301 @@
%% -------------------------------------------------------------------
%%
%% Copyright (c) 2016 Basho Technologies, Inc.
%%
%% This file is provided to you 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.
%%
%% %% Tests for security using the HTTP interface.
%%
%% -------------------------------------------------------------------
-module(ts_simple_http_security_SUITE).
-export([
all/0,
end_per_group/2,
end_per_suite/1,
end_per_testcase/2,
ensure_https_requires_authentication_test/1,
groups/0,
init_per_group/2,
init_per_suite/1,
init_per_testcase/2,
password_user_cannot_connect_with_wrong_password_test/1,
suite/0,
with_security_user_cannot_create_table_without_permissions_test/1,
with_security_user_cannot_put_without_permissions_test/1,
with_security_user_cannot_query_without_permissions_test/1,
with_security_when_user_is_given_permissions_user_can_create_table_test/1,
with_security_when_user_is_given_permissions_user_can_put_data_test/1,
with_security_when_user_is_given_permissions_user_can_query_data_test/1]
).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
%%--------------------------------------------------------------------
%% COMMON TEST CALLBACK FUNCTIONS
%%--------------------------------------------------------------------
suite() ->
[{timetrap,{minutes,10}}].
init_per_suite(Config) -> application:start(crypto),
application:start(asn1),
application:start(public_key),
application:start(ssl),
application:start(ibrowse),
io:format("turning on tracing"),
ibrowse:trace_on(),
CertDir = rt_config:get(rt_scratch_dir) ++ "/http_certs",
%% make a bunch of crypto keys
make_certs:rootCA(CertDir, "rootCA"),
make_certs:endusers(CertDir, "rootCA", ["site3.basho.com", "site4.basho.com"]),
lager:info("Deploy a node"),
ClusterConf = [
{riak_core, [
{default_bucket_props, [{allow_mult, true}, {dvv_enabled, true}]},
{ssl, [
{certfile, filename:join([CertDir, "site3.basho.com/cert.pem"])},
{keyfile, filename:join([CertDir, "site3.basho.com/key.pem"])},
{cacertfile, filename:join([CertDir, "site3.basho.com/cacerts.pem"])}
]}
]},
{riak_search, [ {enabled, false}]}
],
[Node|_] = Nodes = rt:build_cluster(1, ClusterConf),
{HttpIpPort, HttpsIpPort} = enable_ssl(Node),
%% build the test context
Ctx = [
{cluster, Nodes},
{http, HttpIpPort},
{https, HttpsIpPort},
{cert_dir, CertDir} | Config],
%% enable riak security
{ok,_} = riak_admin(Ctx, ["security", "enable"]),
Ctx.
end_per_suite(_Config) ->
ok.
init_per_group(_GroupName, Config) ->
Config.
end_per_group(_GroupName, _Config) ->
ok.
init_per_testcase(_TestCase, Config) ->
Config.
end_per_testcase(_TestCase, _Config) ->
ok.
groups() ->
[].
all() ->
rt:grep_test_functions(?MODULE).
%%--------------------------------------------------------------------
%% UTIL FUNCTIONS
%%--------------------------------------------------------------------
enable_ssl(Node) ->
[{http, {IP, Port}}|_] = rt:connection_info(Node),
HttpPort = Port+1000,
rt:update_app_config(Node, [{riak_api, [{https, [{IP, HttpPort}]}]}]),
rt:wait_until_pingable(Node),
rt:wait_for_service(Node, riak_kv),
{{IP, Port}, {IP, HttpPort}}.
client_conn(Ctx, Username, Password) ->
CertDir = proplists:get_value(cert_dir, Ctx),
{IP, Port} = proplists:get_value(https, Ctx),
rhc:create(IP, Port, "riak", [{is_ssl, true},
{credentials, Username, Password},
{ssl_options, [
{cacertfile, filename:join([CertDir, "rootCA/cert.pem"])},
{verify, verify_peer},
{reuse_sessions, false}
]}
]).
riak_admin(Ctx, Args) ->
[Node|_] = proplists:get_value(cluster, Ctx),
{ok,_Out} = Result = rt:admin(Node, Args),
ct:pal("riak-admin ~s~n~s", [string:join(Args, " "), _Out]),
Result.
create_trusted_user(Ctx, Perms) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", Perms, "127.0.0.1/32", "trust"]),
client_conn(Ctx, User, Password).
create_table_sql(Name) ->
lists:flatten(io_lib:format(
"create table ~p ("
" a varchar not null,"
" b varchar not null,"
" c timestamp not null,"
" d sint64,"
" primary key ((a, b, quantum(c, 1, m)), a, b, c))", [Name])).
%% From riak_core_security.erl
%% Avoid whitespace, control characters, comma, semi-colon,
%% non-standard Windows-only characters, other misc
-define(ILLEGAL, lists:seq(0, 44) ++ lists:seq(58, 63) ++
lists:seq(127, 191)).
user_name() ->
User = string:to_lower(base64:encode_to_string(term_to_binary(make_ref()))),
[C || C <- User, not lists:member(C, ?ILLEGAL)].
execute_query(Ctx, Query) ->
{IP, Port} = proplists:get_value(https, Ctx),
URL = lists:flatten(io_lib:format("http://~s:~B/ts/v1/query",
[IP, Port])),
ibrowse:send_req(URL, [], post, Query).
row(A, B, C, D) ->
io_lib:format("{\"a\": \"~s\", \"b\": \"~s\", \"c\": ~B, \"d\":~B}",
[A, B, C, D]).
post_data(Ctx, Table, Body) ->
{IP, Port} = proplists:get_value(https, Ctx),
URL = lists:flatten(
io_lib:format("http://~s:~B/ts/v1/tables/~s/keys", [IP, Port, Table])),
ibrowse:send_req(URL, [{"Content-Type", "application/json"}], post, lists:flatten(Body)).
%%--------------------------------------------------------------------
%% TESTS
%%--------------------------------------------------------------------
ensure_https_requires_authentication_test(Ctx) ->
{IP, Port} = proplists:get_value(https, Ctx),
lager:info("Checking SSL demands authentication"),
Conn = rhc:create(IP, Port, "riak", [{is_ssl, true}]),
?assertMatch(
{error, {ok, "401", _, _}},
rhc:ping(Conn)
).
password_user_cannot_connect_with_wrong_password_test(Ctx) ->
User = "stranger",
Password = "drongo",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User, "password=donk"]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "password"]),
Conn = client_conn(Ctx, User, Password),
?assertMatch(
{error, {ok, "401", _, _}},
rhc:ping(Conn)
).
with_security_user_cannot_create_table_without_permissions_test(Ctx) ->
create_trusted_user(Ctx, "all"),
Query = create_table_sql("table1"),
%% just assert on the error message this once, to make sure it is getting
%% formatted correctly.
?assertMatch(
{ok, "400", _Headers, _Body},
execute_query(Ctx, Query)
).
with_security_when_user_is_given_permissions_user_can_create_table_test(Ctx) ->
create_trusted_user(Ctx, "riak_ts.query_create_table"),
Query = create_table_sql("table2"),
%% just assert on the error message this once, to make sure it is getting
%% formatted correctly.
?assertMatch(
{ok, "400", _Headers, _Body},
execute_query(Ctx, Query)
).
with_security_user_cannot_put_without_permissions_test(Ctx) ->
create_trusted_user(Ctx, "riak_ts.query_create_table"),
Query = create_table_sql("table3"),
?assertMatch(
{ok, "400", _Headers, _Body},
execute_query(Ctx, Query)
),
RowStr = row("q1", "w1", 11, 110),
?assertMatch(
{ok, "200", _Headers, "{\"success\":true}"},
post_data(Ctx, "table3", RowStr)
).
with_security_when_user_is_given_permissions_user_can_put_data_test(Ctx) ->
create_trusted_user(Ctx, "riak_ts.query_create_table,riak_ts.put"),
Query = create_table_sql("table4"),
?assertMatch(
{ok, "400", _Headers, _Body},
execute_query(Ctx, Query)
),
RowStr = row("q1", "w1", 11, 110),
?assertMatch(
{ok, "200", _Headers, "{\"success\":true}"},
post_data(Ctx, "table4", RowStr)
).
with_security_user_cannot_query_without_permissions_test(Ctx) ->
create_trusted_user(Ctx, "riak_ts.query_create_table,riak_ts.put"),
Query = create_table_sql("table4"),
?assertMatch(
{ok, "400", _Headers, _Body},
execute_query(Ctx, Query)
),
RowStrs = string:join([row("q1", "w2", 20, 150), row("q1", "w1", 20, 119)],
", "),
?assertMatch(
{ok, "200", _Headers, "{\"success\":true}"},
post_data(Ctx, "table4", RowStrs)
),
Select = "SELECT * FROM table4 WHERE a='q1' AND b='w1' AND c>1 AND c<99",
?assertMatch(
{ok, "400", _Headers, _Body},
execute_query(Ctx, Select)
).
with_security_when_user_is_given_permissions_user_can_query_data_test(Ctx) ->
create_trusted_user(Ctx, "riak_ts.query_create_table,riak_ts.put,riak_ts.query_select"),
Query = create_table_sql("table4"),
?assertMatch(
{ok, "400", _Headers, _Body},
execute_query(Ctx, Query)
),
RowStrs = string:join([row("q1", "w2", 20, 150), row("q1", "w1", 20, 119)],
", "),
?assertMatch(
{ok, "200", _Headers, "{\"success\":true}"},
post_data(Ctx, "table4", RowStrs)
),
Select = "SELECT * FROM table4 WHERE a='q1' AND b='w1' AND c>1 AND c<99",
Body = "{\"columns\":[\"a\",\"b\",\"c\",\"d\"],"
"\"rows\":[[\"q1\",\"w1\",11,110],"
"[\"q1\",\"w1\",20,119]]}",
?assertMatch(
{ok,"200", _Headers, Body},
execute_query(Ctx, Select)
).

View File

@ -0,0 +1,762 @@
%% -------------------------------------------------------------------
%%
%% Copyright (c) 2016 Basho Technologies, Inc.
%%
%% This file is provided to you 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.
%%
%% Tests for security using the PBC interface.
%%
%% -------------------------------------------------------------------
-module(ts_simple_pb_security_SUITE).
-compile(export_all).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
%%--------------------------------------------------------------------
%% COMMON TEST CALLBACK FUNCTIONS
%%--------------------------------------------------------------------
suite() ->
[{timetrap,{minutes,10}}].
init_per_suite(Config) ->
application:start(crypto),
application:start(asn1),
application:start(public_key),
application:start(ssl),
application:start(inets),
CertDir = rt_config:get(rt_scratch_dir) ++ "/pb_security_certs",
ok = make_certificates(CertDir),
ok = make_certificates_http_server(CertDir),
lager:info("Deploy some nodes"),
ClusterConf = [
{riak_core, [
{default_bucket_props, [{allow_mult, true}, {dvv_enabled, true}]},
{ssl, [
{certfile, filename:join([CertDir, "site3.basho.com/cert.pem"])},
{keyfile, filename:join([CertDir, "site3.basho.com/key.pem"])},
{cacertfile, filename:join([CertDir, "site3.basho.com/cacerts.pem"])}
]}
]},
{riak_search, [{enabled, false}]}
],
[Node|_] = Nodes = rt:build_cluster(1, ClusterConf),
%% build the test context
[_, {pb, {"127.0.0.1", Port}}] = rt:connection_info(Node),
Ctx = [{cluster,Nodes},{port,Port},{cert_dir,CertDir}|Config],
%% enable riak security
{ok,_} = riak_admin(Ctx, ["security", "enable"]),
Ctx.
end_per_suite(_Config) ->
ok.
init_per_group(_GroupName, Config) ->
Config.
end_per_group(_GroupName, _Config) ->
ok.
init_per_testcase(_TestCase, Config) ->
Config.
end_per_testcase(_TestCase, _Config) ->
ok.
groups() ->
[].
all() ->
rt:grep_test_functions(?MODULE).
%%--------------------------------------------------------------------
%% UTIL FUNCTIONS
%%--------------------------------------------------------------------
%% make a bunch of crypto keys
make_certificates(CertDir) ->
make_certs:rootCA(CertDir, "rootCA"),
make_certs:intermediateCA(CertDir, "intCA", "rootCA"),
make_certs:intermediateCA(CertDir, "revokedCA", "rootCA"),
make_certs:endusers(CertDir, "intCA", ["site1.basho.com", "site2.basho.com"]),
make_certs:endusers(CertDir, "rootCA", ["site3.basho.com", "site4.basho.com", "site5.basho.com"]),
make_certs:enduser(CertDir, "revokedCA", "site6.basho.com"),
make_certs:revoke(CertDir, "rootCA", "site5.basho.com"),
make_certs:revoke(CertDir, "rootCA", "revokedCA"),
%% use a leaf certificate as a CA certificate and make a totally bogus new leaf certificate
make_certs:create_ca_dir(CertDir, "site1.basho.com", make_certs:ca_cnf("site1.basho.com")),
file:copy(filename:join(CertDir, "site1.basho.com/key.pem"), filename:join(CertDir, "site1.basho.com/private/key.pem")),
make_certs:enduser(CertDir, "site1.basho.com", "site7.basho.com"),
file:copy(filename:join([CertDir, "site1.basho.com", "cacerts.pem"]), filename:join(CertDir, "site7.basho.com/cacerts.pem")),
{ok, Bin} = file:read_file(filename:join(CertDir, "site1.basho.com/cert.pem")),
{ok, FD} = file:open(filename:join(CertDir, "site7.basho.com/cacerts.pem"), [append]),
file:write(FD, ["\n", Bin]),
file:close(FD),
make_certs:gencrl(CertDir, "site1.basho.com"),
ok.
%% start a HTTP server to serve the CRLs
%%
%% NB: we use the 'stand_alone' option to link the server to the
%% test process, so it exits when the test process exits.
make_certificates_http_server(CertDir) ->
{ok, _HTTPPid} = inets:start(httpd, [{port, 8000}, {server_name, "localhost"},
{server_root, "/tmp"},
{document_root, CertDir},
{modules, [mod_get]}], stand_alone),
ok.
client_pid(Ctx, User, Password) ->
CertDir = proplists:get_value(cert_dir, Ctx),
Port = proplists:get_value(port, Ctx),
riakc_pb_socket:start(
"127.0.0.1", Port,
[{credentials, iolist_to_binary(User), Password},
{cacertfile, filename:join([CertDir, "rootCA/cert.pem"])}]).
riak_admin(Ctx, Args) ->
[Node|_] = proplists:get_value(cluster, Ctx),
{ok,_Out} = Result = rt:admin(Node, Args),
ct:pal("riak-admin ~s~n~s", [string:join(Args, " "), _Out]),
Result.
%% From riak_core_security.erl
%% Avoid whitespace, control characters, comma, semi-colon,
%% non-standard Windows-only characters, other misc
-define(ILLEGAL, lists:seq(0, 44) ++ lists:seq(58, 63) ++
lists:seq(127, 191)).
user_name() ->
User = string:to_lower(base64:encode_to_string(term_to_binary(make_ref()))),
[C || C <- User, not lists:member(C, ?ILLEGAL)].
receive_keys(Pid, Acc) ->
receive
{ReqId, {keys, Keys}} ->
lager:info("received batch of ~b\n", [length(Keys)]),
receive_keys(ReqId, lists:append(Keys, Acc));
{ReqId, {error, Reason}} ->
lager:info("list_keys(~p) at ~b got an error: ~p\n", [ReqId, length(Acc), Reason]),
{error, Reason};
{ReqId, done} ->
lager:info("done receiving from one quantum (~p) \n", [ReqId]),
receive_keys(Pid, Acc);
Else ->
lager:info("What's that? ~p\n", [Else]),
receive_keys(Pid, Acc)
after 3000 ->
lager:info("Consider streaming done\n", []),
{ok, Acc}
end.
%% If a test creates a table, add it to the ever-growing laundry list
%% of tables so those tests which need to know about all tables will
%% have the complete list
add_table_to_list(Config, Table) ->
{_Saver, ConfigList} = ?config(saved_config, Config),
{save_config, [{Table}|ConfigList]}.
%% Just like add_table_to_list/2, but required to pass the the config
%% state to the next test, even if there is no change
add_no_table_to_list(Config) ->
{_Saver, ConfigList} = ?config(saved_config, Config),
{save_config, ConfigList}.
%%--------------------------------------------------------------------
%% TESTS
%%--------------------------------------------------------------------
trusted_user_does_not_need_a_password_to_connect_test(Ctx) ->
User = user_name(),
NonsensePassword = "nonsense",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok, _} = client_pid(Ctx, User, NonsensePassword),
{save_config,[]}.
password_user_cannot_connect_with_wrong_password_test(Ctx) ->
User = "stranger",
Password = "drongo",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User, "password=donk"]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "password"]),
?assertEqual(
{error,{tcp,<<"Authentication failed">>}},
client_pid(Ctx, User, Password)
),
add_no_table_to_list(Ctx).
with_security_user_cannot_create_table_without_permissions_test(Ctx) ->
User = user_name(),
UserBin = list_to_binary(User),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok, Pid} = client_pid(Ctx, User, Password),
%% just assert on the error message this once, to make sure it is getting
%% formatted correctly.
?assertEqual(
{error,
<<"Permission denied: User '", UserBin/binary, "' does not have ",
"'riak_ts.create_table' on table1">>},
riakc_ts:query(Pid,
"CREATE TABLE table1 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
add_no_table_to_list(Ctx).
with_security_when_user_is_given_permissions_user_can_create_table_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok, {[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table2 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
add_table_to_list(Ctx, <<"table2">>).
with_security_user_cannot_put_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table3 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
riakc_ts:put(Pid, <<"table3">>, [{1,1,1}])
),
add_table_to_list(Ctx, <<"table3">>).
with_security_when_user_is_given_permissions_user_can_put_data_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table4 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertEqual(
ok,
riakc_ts:put(Pid, <<"table4">>, [{1,1,1}])
),
add_table_to_list(Ctx, <<"table4">>).
with_security_user_cannot_query_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table5 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
ok,
riakc_ts:put(Pid, <<"table5">>, [{1,1,1}])
),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
riakc_ts:query(Pid, "SELECT a, b, c FROM table5 WHERE a=1 AND b=1 AND c>0 and c<2")
),
add_table_to_list(Ctx, <<"table5">>).
with_security_when_user_is_given_permissions_user_can_query_data_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put,riak_ts.query_select", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table6 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertEqual(
ok,
riakc_ts:put(Pid, <<"table6">>, [{1,1,1}])
),
?assertEqual(
{ok, {[<<"a">>, <<"b">>, <<"c">>], [{1,1,1}]}},
riakc_ts:query(Pid, "SELECT a, b, c FROM table6 WHERE a=1 AND b=1 AND c>0 and c<2")
),
add_table_to_list(Ctx, <<"table6">>).
with_security_user_cannot_insert_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table7 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
riakc_ts:query(Pid, "INSERT INTO table7 (a, b, c) VALUES (1, 1 ,1)")
),
add_table_to_list(Ctx, <<"table7">>).
with_security_when_user_is_given_permissions_user_can_insert_data_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table8 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
{ok,{[],[]}},
riakc_ts:query(Pid, "INSERT INTO table8 (a, b, c) VALUES (1, 1 ,1)")
),
add_table_to_list(Ctx, <<"table8">>).
with_security_user_cannot_list_keys_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table9 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
ok,
riakc_ts:put(Pid, <<"table9">>, [{1,1,1}])
),
?assertMatch(
ok,
riakc_ts:put(Pid, <<"table9">>, [{2,2,2}])
),
?assertMatch(
ok,
riakc_ts:put(Pid, <<"table9">>, [{3,3,3}])
),
?assertMatch(
{ok, _RefId},
riakc_ts:stream_list_keys(Pid, <<"table9">>, infinity)
),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
receive_keys(Pid, [])
),
add_table_to_list(Ctx, <<"table9">>).
with_security_when_user_is_given_permissions_user_can_list_keys_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put,riak_ts.list_keys", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table10 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
ok,
riakc_ts:put(Pid, <<"table10">>, [{1,1,1}])
),
?assertMatch(
ok,
riakc_ts:put(Pid, <<"table10">>, [{2000,2000,2000}])
),
?assertMatch(
ok,
riakc_ts:put(Pid, <<"table10">>, [{3000,3000,3000}])
),
?assertMatch(
{ok, _RefId},
riakc_ts:stream_list_keys(Pid, <<"table10">>, infinity)
),
?assertMatch(
{ok, _},
receive_keys(Pid, [])
),
add_table_to_list(Ctx, <<"table10">>).
with_security_user_cannot_get_data_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table11 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertEqual(
ok,
riakc_ts:put(Pid, <<"table11">>, [{1,1,1}])
),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
riakc_ts:get(Pid, <<"table11">>, [1,1,1], [])
),
add_table_to_list(Ctx, <<"table11">>).
with_security_when_user_is_given_permissions_user_can_get_data_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put,riak_ts.get", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table12 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertEqual(
ok,
riakc_ts:put(Pid, <<"table12">>, [{1,1,1}])
),
?assertEqual(
{ok,{[<<"a">>,<<"b">>,<<"c">>],[{1,1,1}]}},
riakc_ts:get(Pid, <<"table12">>, [1,1,1], [])
),
add_table_to_list(Ctx, <<"table12">>).
with_security_user_cannot_delete_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table13 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertEqual(
ok,
riakc_ts:put(Pid, <<"table13">>, [{1,1,1}])
),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
riakc_ts:delete(Pid, <<"table13">>, [1,1,1], [])
),
add_table_to_list(Ctx, <<"table13">>).
with_security_when_user_is_given_permissions_user_can_delete_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.put,riak_ts.delete", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table14 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertEqual(
ok,
riakc_ts:put(Pid, <<"table14">>, [{1,1,1}])
),
?assertMatch(
ok,
riakc_ts:delete(Pid, <<"table14">>, [1,1,1], [])
),
add_table_to_list(Ctx, <<"table14">>).
with_security_user_cannot_describe_table_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
%% just assert on the error message this once, to make sure it is getting
%% formatted correctly.
?assertEqual(
{ok, {[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table15 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
riakc_ts:query(Pid, "DESCRIBE table15")
),
add_table_to_list(Ctx, <<"table15">>).
with_security_when_user_is_given_permissions_user_can_describe_table_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.describe_table", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok, {[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table16 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertEqual(
{ok,{[<<"Column">>,<<"Type">>,<<"Is Null">>,
<<"Primary Key">>,<<"Local Key">>,
<<"Interval">>,<<"Unit">>],
[{<<"a">>,<<"sint64">>,false,1,1,[],[]},
{<<"b">>,<<"sint64">>,false,2,2,[],[]},
{<<"c">>,<<"timestamp">>,false,3,3,1,
<<"s">>}]}},
riakc_ts:query(Pid, "DESCRIBE table16")
),
add_table_to_list(Ctx, <<"table16">>).
with_security_user_cannot_get_coverage_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table17 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
riakc_ts:get_coverage(Pid, <<"table17">>, "SELECT a, b, c FROM table17 WHERE a=1 AND b=1 AND c>0 and c<2")
),
add_table_to_list(Ctx, <<"table17">>).
with_security_when_user_is_given_permissions_user_can_get_coverage_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.create_table,riak_ts.coverage", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table18 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
{ok,[{{<<"127.0.0.1">>,_},
<<_/binary>>,
{<<"c">>,{{1,true},{2,false}}},
<<"table18 / c >= 1 and c < 2">>}]},
riakc_ts:get_coverage(Pid, <<"table18">>, "SELECT a, b, c FROM table18 WHERE a=1 AND b=1 AND c>0 and c<2")
),
add_table_to_list(Ctx, <<"table18">>).
with_security_user_cannot_show_tables_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "all", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
riakc_ts:query(Pid, "SHOW TABLES")
),
add_no_table_to_list(Ctx).
with_security_when_user_is_given_permissions_user_can_show_tables_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.show_tables", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
{ok, {Columns, Rows}} = riakc_ts:query(Pid, "SHOW TABLES"),
{_Saver, TableList} = ?config(saved_config, Ctx),
?assertEqual(
[<<"Table">>],
Columns
),
?assertEqual(
lists:sort(Rows),
lists:sort(TableList)
),
add_no_table_to_list(Ctx).

View File

@ -1,272 +0,0 @@
%% -------------------------------------------------------------------
%%
%% Copyright (c) 2015 Basho Technologies, Inc.
%%
%% This file is provided to you 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.
%%
%% Tests for range queries around the boundaries of quanta.
%%
%% -------------------------------------------------------------------
-module(ts_simple_security_SUITE).
-compile(export_all).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
%%--------------------------------------------------------------------
%% COMMON TEST CALLBACK FUNCTIONS
%%--------------------------------------------------------------------
suite() ->
[{timetrap,{minutes,10}}].
init_per_suite(Config) ->
application:start(crypto),
application:start(asn1),
application:start(public_key),
application:start(ssl),
application:start(inets),
CertDir = rt_config:get(rt_scratch_dir) ++ "/pb_security_certs",
ok = make_certificates(CertDir),
ok = make_certificates_http_server(CertDir),
lager:info("Deploy some nodes"),
ClusterConf = [
{riak_core, [
{default_bucket_props, [{allow_mult, true}, {dvv_enabled, true}]},
{ssl, [
{certfile, filename:join([CertDir, "site3.basho.com/cert.pem"])},
{keyfile, filename:join([CertDir, "site3.basho.com/key.pem"])},
{cacertfile, filename:join([CertDir, "site3.basho.com/cacerts.pem"])}
]}
]},
{riak_search, [{enabled, false}]}
],
[Node|_] = Nodes = rt:build_cluster(1, ClusterConf),
%% build the test context
[_, {pb, {"127.0.0.1", Port}}] = rt:connection_info(Node),
Ctx = [{cluster,Nodes},{port,Port},{cert_dir,CertDir}|Config],
%% enable riak security
{ok,_} = riak_admin(Ctx, ["security", "enable"]),
Ctx.
end_per_suite(_Config) ->
ok.
init_per_group(_GroupName, Config) ->
Config.
end_per_group(_GroupName, _Config) ->
ok.
init_per_testcase(_TestCase, Config) ->
Config.
end_per_testcase(_TestCase, _Config) ->
ok.
groups() ->
[].
all() ->
rt:grep_test_functions(?MODULE).
%%--------------------------------------------------------------------
%% UTIL FUNCTIONS
%%--------------------------------------------------------------------
%% make a bunch of crypto keys
make_certificates(CertDir) ->
make_certs:rootCA(CertDir, "rootCA"),
make_certs:intermediateCA(CertDir, "intCA", "rootCA"),
make_certs:intermediateCA(CertDir, "revokedCA", "rootCA"),
make_certs:endusers(CertDir, "intCA", ["site1.basho.com", "site2.basho.com"]),
make_certs:endusers(CertDir, "rootCA", ["site3.basho.com", "site4.basho.com", "site5.basho.com"]),
make_certs:enduser(CertDir, "revokedCA", "site6.basho.com"),
make_certs:revoke(CertDir, "rootCA", "site5.basho.com"),
make_certs:revoke(CertDir, "rootCA", "revokedCA"),
%% use a leaf certificate as a CA certificate and make a totally bogus new leaf certificate
make_certs:create_ca_dir(CertDir, "site1.basho.com", make_certs:ca_cnf("site1.basho.com")),
file:copy(filename:join(CertDir, "site1.basho.com/key.pem"), filename:join(CertDir, "site1.basho.com/private/key.pem")),
make_certs:enduser(CertDir, "site1.basho.com", "site7.basho.com"),
file:copy(filename:join([CertDir, "site1.basho.com", "cacerts.pem"]), filename:join(CertDir, "site7.basho.com/cacerts.pem")),
{ok, Bin} = file:read_file(filename:join(CertDir, "site1.basho.com/cert.pem")),
{ok, FD} = file:open(filename:join(CertDir, "site7.basho.com/cacerts.pem"), [append]),
file:write(FD, ["\n", Bin]),
file:close(FD),
make_certs:gencrl(CertDir, "site1.basho.com"),
ok.
%% start a HTTP server to serve the CRLs
%%
%% NB: we use the 'stand_alone' option to link the server to the
%% test process, so it exits when the test process exits.
make_certificates_http_server(CertDir) ->
{ok, _HTTPPid} = inets:start(httpd, [{port, 8000}, {server_name, "localhost"},
{server_root, "/tmp"},
{document_root, CertDir},
{modules, [mod_get]}], stand_alone),
ok.
client_pid(Ctx, User, Password) ->
CertDir = proplists:get_value(cert_dir, Ctx),
Port = proplists:get_value(port, Ctx),
riakc_pb_socket:start(
"127.0.0.1", Port,
[{credentials, iolist_to_binary(User), Password},
{cacertfile, filename:join([CertDir, "rootCA/cert.pem"])}]).
riak_admin(Ctx, Args) ->
[Node|_] = proplists:get_value(cluster, Ctx),
{ok,_Out} = Result = rt:admin(Node, Args),
ct:pal("riak-admin ~s~n~s", [string:join(Args, " "), _Out]),
Result.
%% From riak_core_security.erl
%% Avoid whitespace, control characters, comma, semi-colon,
%% non-standard Windows-only characters, other misc
-define(ILLEGAL, lists:seq(0, 44) ++ lists:seq(58, 63) ++
lists:seq(127, 191)).
user_name() ->
User = string:to_lower(base64:encode_to_string(term_to_binary(make_ref()))),
[C || C <- User, not lists:member(C, ?ILLEGAL)].
%%--------------------------------------------------------------------
%% TESTS
%%--------------------------------------------------------------------
trusted_user_does_not_need_a_password_to_connect_test(Ctx) ->
User = user_name(),
NonsensePassword = "nonsense",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok, _} = client_pid(Ctx, User, NonsensePassword).
password_user_cannot_connect_with_wrong_password_test(Ctx) ->
User = "stranger",
Password = "drongo",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User, "password=donk"]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "password"]),
?assertEqual(
{error,{tcp,<<"Authentication failed">>}},
client_pid(Ctx, User, Password)
).
with_security_user_cannot_create_table_without_permissions_test(Ctx) ->
User = user_name(),
UserBin = list_to_binary(User),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok, Pid} = client_pid(Ctx, User, Password),
%% just assert on the error message this once, to make sure it is getting
%% formatted correctly.
?assertEqual(
{error,
<<"Permission denied: User '", UserBin/binary, "' does not have ",
"'riak_ts.query_create_table' on table1">>},
riakc_ts:query(Pid,
"CREATE TABLE table1 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
).
with_security_when_user_is_given_permissions_user_can_create_table_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.query_create_table", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok, {[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table2 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
).
with_security_user_cannot_put_without_permissions_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.query_create_table", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table3 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertMatch(
{error, <<"Permission denied", _/binary>>},
riakc_ts:put(Pid, <<"table3">>, [{1,1,1}])
).
with_security_when_user_is_given_permissions_user_can_put_data_test(Ctx) ->
User = user_name(),
Password = "password",
{ok,_} = riak_admin(Ctx,
["security", "add-user", User]),
{ok,_} = riak_admin(Ctx,
["security", "add-source", "all", "127.0.0.1/32", "trust"]),
{ok,_} = riak_admin(Ctx,
["security", "grant", "riak_ts.query_create_table,riak_ts.put", "on", "any", "to", User]),
{ok, Pid} = client_pid(Ctx, User, Password),
?assertEqual(
{ok,{[],[]}},
riakc_ts:query(Pid,
"CREATE TABLE table4 ("
"a SINT64 NOT NULL, "
"b SINT64 NOT NULL, "
"c TIMESTAMP NOT NULL, "
"PRIMARY KEY ((a,b,quantum(c, 1, 's')), a,b,c))")
),
?assertEqual(
ok,
riakc_ts:put(Pid, <<"table4">>, [{1,1,1}])
).