Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SUSTAIN-632] Do not update the users table to contain the public key.
Browse files Browse the repository at this point in the history
The keys table should be the only source of truth
New insert/updates to the users table will insert a sentinel value in the public_key column.
The old values are left as is.
Triggers will act only on the values in the users.public_key that are not the sentinel value.

Signed-off-by: Prajakta Purohit <[email protected]>
PrajaktaPurohit committed Aug 31, 2017

Verified

This commit was signed with the committer’s verified signature.
macmv Neil Macneale V
1 parent 3c916eb commit 36ed4d0
Showing 15 changed files with 278 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
define_upgrade do

if Partybus.config.bootstrap_server
must_be_data_master

# schema update no longer insert public_key in users table.
# the keys table is the only source of truth
run_sqitch('@sentinel_public_key_for_users', 'oc_erchef')
end
end
16 changes: 8 additions & 8 deletions src/oc_erchef/apps/chef_db/itest/chef_sql_users.erl
Original file line number Diff line number Diff line change
@@ -80,21 +80,21 @@ chef_user_record(AzId, _Admin) ->

insert_user_data() ->
Users = [make_user(<<"user01">>), make_user(<<"user02">>)],
Expected = lists:duplicate(length(Users), {ok, 1}),
Expected = lists:duplicate(length(Users), {ok,[[{<<"add_user">>,<<>>}]]}),
Results = [itest_util:create_record(User) || User <- Users],
?assertEqual(Expected, Results).

fetch_user_data() ->
Expected = make_user(<<"user03">>),
Username = Expected#chef_user.username,
%% Make sure client create succeeds
?assertEqual({ok, 1}, itest_util:create_record(Expected)),
?assertEqual({ok,[[{<<"add_user">>,<<>>}]]}, itest_util:create_record(Expected)),
Result = chef_db:fetch(#chef_user{username = Username}, chef_db:make_context(?API_MIN_VER, <<"ABCD">>)),
?assertEqual(Expected, Result).

fetch_user_list() ->
Users = [make_user(<<"user04">>), make_user(<<"user05">>)],
CreatedResults = lists:duplicate(length(Users), {ok, 1}),
CreatedResults = lists:duplicate(length(Users), {ok,[[{<<"add_user">>,<<>>}]]}),
Created = [itest_util:create_record(User) || User <- Users ],
?assertEqual(CreatedResults, Created),

@@ -104,7 +104,7 @@ fetch_user_list() ->

delete_user_data() ->
User = make_user(<<"user06">>),
?assertEqual({ok, 1}, itest_util:create_record(User)),
?assertEqual({ok,[[{<<"add_user">>,<<>>}]]}, itest_util:create_record(User)),
Result = itest_util:delete_record(User),
?assertEqual({ok, 1}, Result),
Username = User#chef_user.username,
@@ -113,7 +113,7 @@ delete_user_data() ->

update_user_data() ->
User = make_user(<<"user07">>),
?assertEqual({ok, 1}, itest_util:create_record(User)),
?assertEqual({ok,[[{<<"add_user">>,<<>>}]]}, itest_util:create_record(User)),

%% Check that public key we inserted is correct
Username = User#chef_user.username,
@@ -123,7 +123,7 @@ update_user_data() ->
%% Update public key
UpdatedUserData = User#chef_user{ public_key = ?OTHER_PUBLIC_KEY },
Result = itest_util:update_record(UpdatedUserData),
?assertEqual({ok, 1}, Result),
?assertEqual(ok, Result),

%% Did the public key really update?
PersistedUser = chef_db:fetch(#chef_user{username = Username}, chef_db:make_context(?API_MIN_VER, <<"ABCD">>)),
@@ -134,6 +134,6 @@ update_user_data() ->

count_admin_users() ->
User = make_admin_user(<<"user08">>),
?assertEqual({ok, 1}, itest_util:create_record(User)),
?assertEqual({ok,[[{<<"add_user">>,<<>>}]]}, itest_util:create_record(User)),
User2 = make_admin_user(<<"user09">>),
?assertEqual({ok, 1}, itest_util:create_record(User2)).
?assertEqual({ok,[[{<<"add_user">>,<<>>}]]}, itest_util:create_record(User2)).
44 changes: 4 additions & 40 deletions src/oc_erchef/apps/chef_db/priv/pgsql_statements.config
Original file line number Diff line number Diff line change
@@ -484,17 +484,10 @@
%% User-related
%%
{insert_user,
<<"INSERT INTO users (id, authz_id, username, email, hashed_password, salt,
hash_type, last_updated_by, created_at, updated_at, external_authentication_uid,
recovery_authentication_enabled, serialized_object, admin, pubkey_version) VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, false, 0)">>}.
<<"SELECT add_user($1, $2, $3, $4, 'thisisnotakey', 0, $5, $6, $7, $8, $9, $10, $11, $12, $13, false)">>}.

{insert_user_v0,
<<"INSERT INTO users (id, authz_id, username, email, public_key, pubkey_version,
hashed_password, salt, hash_type, last_updated_by, created_at,
updated_at, external_authentication_uid,
recovery_authentication_enabled, serialized_object, admin) VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, false)">>}.
<<"SELECT add_user($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, false)">>}.

{find_user_by_username_v0,
<<"SELECT u.id, authz_id, username, email, k.public_key, k.key_version pubkey_version,
@@ -560,22 +553,7 @@
{list_users_by_ext_auth_uid, <<"SELECT username FROM users WHERE external_authentication_uid = $1">>}.

{update_user_by_id_v0,
<<"UPDATE users
SET pubkey_version = $1,
public_key = $2,
hashed_password = $3,
salt = $4,
hash_type = $5,
serialized_object = $6,
external_authentication_uid = $7,
recovery_authentication_enabled = $8,
email = $9,
username = $10,
last_updated_by = $11,
updated_at = $12,
admin = false
WHERE id = $13">>
}.
<<"SELECT update_user($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, false, $13)">>}.

{list_common_orgs_for_users,
<<"SELECT o.name as name, o.full_name as full_name, o.id as guid"
@@ -587,18 +565,4 @@
}.

{update_user_by_id,
<<"UPDATE users
SET hashed_password = $1,
salt = $2,
hash_type = $3,
serialized_object = $4,
external_authentication_uid = $5,
recovery_authentication_enabled = $6,
email = $7,
username = $8,
last_updated_by = $9,
updated_at = $10,
admin = false,
pubkey_version = 0
WHERE id = $11">>
}.
<<"SELECT update_user(0, 'thisisnotakey', $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, false, $11)">>}.
3 changes: 2 additions & 1 deletion src/oc_erchef/apps/chef_db/src/chef_db.erl
Original file line number Diff line number Diff line change
@@ -155,7 +155,6 @@ make_context(ApiVersion, ReqId) ->
make_context(ApiVersion, ReqId, Darklaunch) ->
#context{server_api_version = ApiVersion, reqid = ReqId, darklaunch = Darklaunch}.


-spec create(object_rec(), #context{}, object_id()) -> ok | {conflict, term()} | {error, term()}.
create(#chef_cookbook_version{} = Record, DbContext, ActorId) ->
create_object(DbContext, create_cookbook_version, Record, ActorId);
@@ -167,6 +166,7 @@ create(ObjectRec0, #context{server_api_version = ApiVersion, reqid = ReqId}, Act
Fields = chef_object:fields_for_insert(ObjectRec2),
case stats_hero:ctime(ReqId, {chef_sql, create_object},
fun() -> chef_sql:create_object(QueryName, Fields) end) of
{ok,[[{<<"add_user">>,<<>>}]]} -> ok;
{ok, 1} -> ok;
{conflict, Msg}-> {conflict, Msg};
{error, Why} -> {error, Why}
@@ -258,6 +258,7 @@ update(#chef_cookbook_version{org_id =OrgId} = Record, #context{reqid = ReqId} =
update(ObjectRec, #context{reqid = ReqId}, ActorId) ->
case stats_hero:ctime(ReqId, {chef_sql, do_update},
fun() -> chef_sql:update(ObjectRec, ActorId) end) of
[[{<<"update_user">>, <<>>}]] -> ok;
N when is_integer(N), N > 0 -> ok;
not_found -> not_found;
{conflict, Message} -> {conflict, Message};
19 changes: 18 additions & 1 deletion src/oc_erchef/apps/chef_db/src/chef_sql.erl
Original file line number Diff line number Diff line change
@@ -990,7 +990,10 @@ create_object(#chef_sandbox{id=SandboxId,
%% the failure back up
Error
end.
-spec create_object(atom(), tuple() | list()) -> {ok, non_neg_integer()} | {error, term()} | {conflict, term()}.
-spec create_object(atom(), tuple() | list()) -> {ok, non_neg_integer()} |
{ok,[[{binary(),<<>>}]]} |
{error, term()} |
{conflict, term()}.
%% okay, that's pretty ugly, but no more so than all the hacks in here and
%% chef_db for plain old cookbooks, their versions, and their checksums
%% and at least, it's in a transaction
@@ -1003,6 +1006,10 @@ create_object(insert_cookbook_artifact_version = QueryName, Args) when is_list(A
{error, _Why} = Error -> Error;
{conflict, _Why} = Conflict -> Conflict
end;
create_object(QueryName, Args) when QueryName =:= insert_user;
QueryName =:= insert_user_v0,
is_list(Args) ->
sqerl:select(QueryName, Args, count);
create_object(QueryName, Args) when is_atom(QueryName), is_list(Args) ->
sqerl:statement(QueryName, Args, count);
create_object(QueryName, Record) when is_atom(QueryName) ->
@@ -1081,6 +1088,16 @@ delete_object(delete_cookbook_by_orgid_name = Query, OrgId, Name) ->
update(ObjectRec, ActorId) ->
chef_object:update(ObjectRec, ActorId, fun select_rows/1).

do_update(QueryName, UpdateFields) when QueryName =:= update_user_by_id;
QueryName =:= update_user_by_id_v0,
is_list(UpdateFields) ->
case sqerl:select(QueryName, UpdateFields) of
{ok, [[{<<"update_user">>, <<>>}]]} -> ok;
{ok, 1} -> {ok, 1};
{ok, none} -> {ok, not_found};
Error ->
Error
end;
do_update(QueryName, UpdateFields) ->
case sqerl:statement(QueryName, UpdateFields) of
{ok, 1} -> {ok, 1};
2 changes: 1 addition & 1 deletion src/oc_erchef/apps/chef_test/src/chef_test_db_helper.erl
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ start_db(Config, DbName) ->
%% fail
CmdsResult = chef_test_suite_helper:run_cmds(CMDS),
% make sure it's seen in output, don't use lager.
ct:pal("db_start: ~n~p~n", [CmdsResult]),
io:format(user, "db_start: ~n~p~n", [CmdsResult]),

Statements = case ?config(statements, Config) of
undefined ->
90 changes: 90 additions & 0 deletions src/oc_erchef/schema/deploy/create_and_update_users.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
-- Deploy enterprise_chef:create_and_update_users to pg
-- Inserts a sentinel value into the public_key field of a user table.
-- Ensures keys table is the only source of truth for public_key

BEGIN;

DROP FUNCTION If EXISTS add_user(character,character,text,text,text,integer,text,text,password_hash_type,character,timestamp without time zone,timestamp without time zone,text,boolean,text,boolean);

CREATE OR REPLACE FUNCTION add_user(p_id users.id%TYPE,
p_authz_id users.authz_id%TYPE,
p_username users.username%TYPE,
p_email users.email%TYPE,
p_public_key users.public_key%TYPE,
p_pubkey_version users.pubkey_version%TYPE,
p_hashed_password users.hashed_password%TYPE,
p_salt users.salt%TYPE,
p_hash_type users.hash_type%TYPE,
p_last_updated_by users.last_updated_by%TYPE,
p_created_at users.created_at%TYPE,
p_updated_at users.updated_at%TYPE,
p_external_authentication_uid users.external_authentication_uid%TYPE,
p_recovery_authentication_enabled users.recovery_authentication_enabled%TYPE,
p_serialized_object users.serialized_object%TYPE,
p_admin users.admin%TYPE) RETURNS void AS $$
BEGIN
INSERT INTO users
(id, authz_id, username, email, public_key, hashed_password, salt, hash_type,
last_updated_by, created_at, updated_at, external_authentication_uid,
recovery_authentication_enabled, serialized_object, admin,
pubkey_version)
VALUES (p_id, p_authz_id, p_username, p_email, 'thisisnotakey',
p_hashed_password, p_salt, p_hash_type, p_last_updated_by, p_created_at, p_updated_at,
p_external_authentication_uid, p_recovery_authentication_enabled,
p_serialized_object, p_admin, p_pubkey_version);
IF p_public_key != 'thisisnotakey' THEN
INSERT INTO keys
(id, key_name, public_key, key_version, created_at, expires_at)
VALUES
(p_id, 'default', p_public_key, p_pubkey_version, now(), 'infinity'::timestamp);
END IF;
END
$$ LANGUAGE plpgsql;

DROP FUNCTION IF EXISTS update_user(integer,text,text,text,password_hash_type,text,text,boolean,text,text,character,timestamp without time zone,boolean,character);

CREATE OR REPLACE FUNCTION update_user(p_pubkey_version users.pubkey_version%TYPE,
p_public_key users.public_key%TYPE,
p_hashed_password users.hashed_password%TYPE,
p_salt users.salt%TYPE,
p_hash_type users.hash_type%TYPE,
p_serialized_object users.serialized_object%TYPE,
p_external_authentication_uid users.external_authentication_uid%TYPE,
p_recovery_authentication_enabled users.recovery_authentication_enabled%TYPE,
p_email users.email%TYPE,
p_username users.username%TYPE,
p_last_updated_by users.last_updated_by%TYPE,
p_updated_at users.updated_at%TYPE,
p_admin users.admin%TYPE,
p_id character(32)) RETURNS void AS $update_user$
BEGIN
IF p_public_key != 'thisisnotakey' THEN
IF p_public_key IS NOT NULL THEN
UPDATE keys SET public_key = p_public_key,
key_version = p_pubkey_version,
expires_at = 'infinity'::timestamp
WHERE id = p_id AND key_name = 'default';
INSERT INTO keys (id, key_name, public_key, key_version, created_at, expires_at)
SELECT p_id, 'default', p_public_key, p_pubkey_version, now(), 'infinity'::timestamp
WHERE NOT EXISTS (SELECT 1 FROM keys WHERE id = p_id AND key_name = 'default');
ELSE
DELETE FROM keys WHERE id = p_id AND key_name = 'default';
END IF;
END IF;
UPDATE users SET
public_key = 'thisisnotakey',
hashed_password = p_hashed_password,
salt = p_salt,
hash_type = p_hash_type,
last_updated_by = p_last_updated_by,
updated_at = p_updated_at,
external_authentication_uid = p_external_authentication_uid,
recovery_authentication_enabled = p_recovery_authentication_enabled,
serialized_object = p_serialized_object,
admin = p_admin,
pubkey_version = p_pubkey_version
WHERE id = p_id;
END
$update_user$ LANGUAGE plpgsql;

COMMIT;
46 changes: 26 additions & 20 deletions src/oc_erchef/schema/deploy/keys_update_trigger.sql
Original file line number Diff line number Diff line change
@@ -5,29 +5,35 @@
BEGIN;

CREATE OR REPLACE FUNCTION add_key() RETURNS TRIGGER AS $add_key$
BEGIN
IF NEW.public_key IS NOT NULL THEN
INSERT INTO keys
(id, key_name, public_key, key_version, created_at, expires_at) VALUES
(NEW.id, 'default', NEW.public_key, NEW.pubkey_version, now(), 'infinity'::timestamp);
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
BEGIN
IF NEW.public_key != 'thisisnotakey' THEN
IF NEW.public_key IS NOT NULL THEN
INSERT INTO keys
(id, key_name, public_key, key_version, created_at, expires_at) VALUES
(NEW.id, 'default', NEW.public_key, NEW.pubkey_version, now(), 'infinity'::timestamp);
END IF;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$add_key$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION update_key() RETURNS TRIGGER AS $update_key$
BEGIN
IF NEW.public_key IS NOT NULL THEN
UPDATE keys SET public_key = NEW.public_key, key_version = NEW.pubkey_version, expires_at = 'infinity'::timestamp
WHERE id = NEW.id AND key_name = 'default';
INSERT INTO keys (id, key_name, public_key, key_version, created_at, expires_at)
SELECT NEW.id, 'default', NEW.public_key, NEW.pubkey_version, now(), 'infinity'::timestamp
WHERE NOT EXISTS (SELECT 1 FROM keys WHERE id = NEW.id AND key_name = 'default');
ELSE
DELETE FROM keys WHERE id = NEW.id AND key_name = 'default';
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
BEGIN
IF NEW.public_key != 'thisisnotakey' THEN
IF NEW.public_key IS NOT NULL THEN
UPDATE keys SET public_key = NEW.public_key,
key_version = NEW.pubkey_version,
expires_at = 'infinity'::timestamp
WHERE id = NEW.id AND key_name = 'default';
INSERT INTO keys (id, key_name, public_key, key_version, created_at, expires_at)
SELECT NEW.id, 'default', NEW.public_key, NEW.pubkey_version, now(), 'infinity'::timestamp
WHERE NOT EXISTS (SELECT 1 FROM keys WHERE id = NEW.id AND key_name = 'default');
ELSE
DELETE FROM keys WHERE id = NEW.id AND key_name = 'default';
END IF;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$update_key$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS add_key ON clients;
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
-- Deploy keys_update_trigger
--
-- This keeps the keys table consistent when the clients and user tables update their keys
--
BEGIN;

CREATE OR REPLACE FUNCTION add_key() RETURNS TRIGGER AS $add_key$
BEGIN
IF NEW.public_key IS NOT NULL THEN
INSERT INTO keys
(id, key_name, public_key, key_version, created_at, expires_at) VALUES
(NEW.id, 'default', NEW.public_key, NEW.pubkey_version, now(), 'infinity'::timestamp);
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$add_key$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION update_key() RETURNS TRIGGER AS $update_key$
BEGIN
IF NEW.public_key IS NOT NULL THEN
UPDATE keys SET public_key = NEW.public_key, key_version = NEW.pubkey_version, expires_at = 'infinity'::timestamp
WHERE id = NEW.id AND key_name = 'default';
INSERT INTO keys (id, key_name, public_key, key_version, created_at, expires_at)
SELECT NEW.id, 'default', NEW.public_key, NEW.pubkey_version, now(), 'infinity'::timestamp
WHERE NOT EXISTS (SELECT 1 FROM keys WHERE id = NEW.id AND key_name = 'default');
ELSE
DELETE FROM keys WHERE id = NEW.id AND key_name = 'default';
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$update_key$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS add_key ON clients;
DROP TRIGGER IF EXISTS update_key ON clients;

DROP TRIGGER IF EXISTS add_key ON users;
DROP TRIGGER IF EXISTS update_key ON users;

CREATE TRIGGER add_key AFTER INSERT ON clients FOR EACH ROW EXECUTE PROCEDURE add_key();
CREATE TRIGGER update_key AFTER UPDATE ON clients FOR EACH ROW EXECUTE PROCEDURE update_key();

CREATE TRIGGER add_key AFTER INSERT ON users FOR EACH ROW EXECUTE PROCEDURE add_key();
CREATE TRIGGER update_key AFTER UPDATE ON users FOR EACH ROW EXECUTE PROCEDURE update_key();

COMMIT;
8 changes: 8 additions & 0 deletions src/oc_erchef/schema/revert/create_and_update_users.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- Revert enterprise_chef:create_and_update_users from pg

BEGIN;

DROP FUNCTION IF EXISTS add_user();
DROP FUNCTION IF EXISTS update_user();

COMMIT;
37 changes: 34 additions & 3 deletions src/oc_erchef/schema/revert/keys_update_trigger.sql
Original file line number Diff line number Diff line change
@@ -1,14 +1,45 @@
-- Revert keys_update_trigger

--
-- This keeps the keys table consistent when the clients and user tables update their keys
--
BEGIN;

CREATE OR REPLACE FUNCTION add_key() RETURNS TRIGGER AS $add_key$
BEGIN
IF NEW.public_key IS NOT NULL THEN
INSERT INTO keys
(id, key_name, public_key, key_version, created_at, expires_at) VALUES
(NEW.id, 'default', NEW.public_key, NEW.pubkey_version, now(), 'infinity'::timestamp);
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$add_key$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION update_key() RETURNS TRIGGER AS $update_key$
BEGIN
IF NEW.public_key IS NOT NULL THEN
UPDATE keys SET public_key = NEW.public_key, key_version = NEW.pubkey_version, expires_at = 'infinity'::timestamp
WHERE id = NEW.id AND key_name = 'default';
INSERT INTO keys (id, key_name, public_key, key_version, created_at, expires_at)
SELECT NEW.id, 'default', NEW.public_key, NEW.pubkey_version, now(), 'infinity'::timestamp
WHERE NOT EXISTS (SELECT 1 FROM keys WHERE id = NEW.id AND key_name = 'default');
ELSE
DELETE FROM keys WHERE id = NEW.id AND key_name = 'default';
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$update_key$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS add_key ON clients;
DROP TRIGGER IF EXISTS update_key ON clients;

DROP TRIGGER IF EXISTS add_key ON users;
DROP TRIGGER IF EXISTS update_key ON users;

DROP FUNCTION IF EXISTS add_key();
DROP FUNCTION IF EXISTS update_key();
CREATE TRIGGER add_key AFTER INSERT ON clients FOR EACH ROW EXECUTE PROCEDURE add_key();
CREATE TRIGGER update_key AFTER UPDATE ON clients FOR EACH ROW EXECUTE PROCEDURE update_key();

CREATE TRIGGER add_key AFTER INSERT ON users FOR EACH ROW EXECUTE PROCEDURE add_key();
CREATE TRIGGER update_key AFTER UPDATE ON users FOR EACH ROW EXECUTE PROCEDURE update_key();

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Revert keys_update_trigger

BEGIN;

DROP TRIGGER IF EXISTS add_key ON clients;
DROP TRIGGER IF EXISTS update_key ON clients;

DROP TRIGGER IF EXISTS add_key ON users;
DROP TRIGGER IF EXISTS update_key ON users;

DROP FUNCTION IF EXISTS add_key();
DROP FUNCTION IF EXISTS update_key();

COMMIT;
4 changes: 4 additions & 0 deletions src/oc_erchef/schema/sqitch.plan
Original file line number Diff line number Diff line change
@@ -80,3 +80,7 @@ node_policy_name_policy_group 2015-09-04T01:15:03Z Daniel DeLeo <ddeleo@lorentz.

users_email_functional_index [users] 2017-05-30T12:10:32Z Stephan Renatus <srenatus@chef.io> # Add functional index for index-based lower(email) lookups
@users_email_functional_index 2017-05-30T13:27:15Z Stephan Renatus <srenatus@chef.io> # Add functional index for index-based lower(email) lookups

create_and_update_users 2017-08-23T22:53:21Z Prajakta Purohit <prajakta@chef.io> # Adding functions to create and update users by inserting a sentinel value in the public_key_columns
keys_update_trigger [keys_update_trigger@users_email_functional_index] 2017-08-23T23:12:29Z Prajakta Purohit <prajakta@chef.io> # The insert and update triggers ignore rows with sentinel value for public_key.
@sentinel_public_key_for_users 2017-08-24T14:32:04Z Prajakta Purohit <prajakta@chef.io> # public_key only updated in the keys table
7 changes: 7 additions & 0 deletions src/oc_erchef/schema/verify/create_and_update_users.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Verify enterprise_chef:create_and_update_users on pg

BEGIN;

-- XXX Add verifications here.

ROLLBACK;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Verify keys_update_trigger

BEGIN;

-- XXX Add verifications here.

ROLLBACK;

0 comments on commit 36ed4d0

Please sign in to comment.