Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create trigger for verifying cloud.gov origin #153

Merged
merged 12 commits into from Jan 6, 2017
65 changes: 63 additions & 2 deletions ci/scripts/create-and-update-db.sh
Expand Up @@ -23,9 +23,70 @@ for db in ${DATABASES}; do

# Special case for uaadb, create totp seed table for use with MFA
# Special case for Shibboleth, create storage records table for use with multi-zone Shibboleth
# Special case for Shibboleth, create function and trigger that verifies origin uaa is set to cloud.gov IdP
# Special case for Shibboelth, create FK between totp_seed and users and CASCADE on delete
if [ "${db}" = "uaadb" ]; then
psql_adm -d "${db}" -c "CREATE TABLE IF NOT EXISTS totp_seed ( username varchar(255) PRIMARY KEY, seed varchar(36), backup_code varchar(36) )"
psql_adm -d "${db}" -c "CREATE TABLE IF NOT EXISTS storagerecords ( context varchar(255) NOT NULL, id varchar(255) NOT NULL, expires bigint DEFAULT NULL, value text NOT NULL, version bigint NOT NULL, PRIMARY KEY (context, id) )"
psql_adm -d "${db}" <<-EOT
BEGIN;
CREATE TABLE IF NOT EXISTS totp_seed
(
username varchar(255) PRIMARY KEY,
seed varchar(36),
backup_code varchar(36)
);
ALTER TABLE IF EXISTS totp_seed
DROP CONSTRAINT username_record_keeper;
ALTER TABLE IF EXISTS totp_seed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for this table not to exist at this point?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more but sure. Also, it's certainly safer to make it all happen within a single transaction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another idempotency question--do we need to drop the constraint if it exists and re-add? I think we do, but haven't verified.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good call.

ADD CONSTRAINT username_record_keeper
FOREIGN KEY (username)
REFERENCES users (username)
ON DELETE CASCADE;
COMMIT;
EOT

psql_adm -d "${db}" <<-EOT
CREATE TABLE IF NOT EXISTS storagerecords
(
context varchar(255) NOT NULL,
id varchar(255) NOT NULL,
expires bigint DEFAULT NULL,
value text NOT NULL,
version bigint NOT NULL,
PRIMARY KEY (context, id)
)
EOT

# Enforce cloud.gov origin for IdP users by validating that their username
# is a valid email address, that their origin is set to `uaa` that they have
# been verified and that their created date does not match their password
# last modified date which only occurs for users who have been invited and
# haven't logged in for the first time and created their password.
psql_adm -d "${db}" <<-EOT
BEGIN;
CREATE OR REPLACE FUNCTION "f_isValidEmail"( text ) RETURNS BOOLEAN AS '
SELECT \$1 ~ ''^[^@\s]+@[^@\s]+(\.[^@\s]+)+$'' AS RESULT
' LANGUAGE sql;
CREATE OR REPLACE FUNCTION "f_enforceCloudGovOrigin"() RETURNS TRIGGER AS \$\$
BEGIN
UPDATE users
SET ( origin, external_id ) = ( 'cloud.gov', username )
WHERE "f_isValidEmail"( username ) AND
origin = 'uaa' AND
verified = true AND
created::date != passwd_lastmodified::date;
END;
\$\$ LANGUAGE plpgsql;
COMMIT;
EOT
psql_adm -d "${db}" <<-EOT
BEGIN;
DROP TRIGGER IF EXISTS enforce_cloud_gov_idp_origin_trigger
ON users;
CREATE TRIGGER enforce_cloud_gov_idp_origin_trigger
AFTER UPDATE ON users
FOR EACH STATEMENT EXECUTE PROCEDURE "f_enforceCloudGovOrigin"();
COMMIT;
EOT
fi

done