From 4519ac40237342e0216f5fe7af2029810edc3a6e Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Tue, 3 Jul 2012 11:26:15 +0200 Subject: Lafargue: Migrate to a role-based access control model. --- schema.sql | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 5 deletions(-) (limited to 'schema.sql') diff --git a/schema.sql b/schema.sql index 4170b3b..8934883 100644 --- a/schema.sql +++ b/schema.sql @@ -2,6 +2,11 @@ BEGIN TRANSACTION; +CREATE TABLE roles( + id SERIAL NOT NULL, + PRIMARY KEY(id) +); + CREATE TABLE users( id SERIAL NOT NULL, first_name VARCHAR, @@ -10,8 +15,10 @@ CREATE TABLE users( email VARCHAR, website VARCHAR, status VARCHAR, + "role" INTEGER NOT NULL, PRIMARY KEY(id), - CHECK (status IN ('admin', 'approved', 'visitor', 'disabled')) + CHECK (status IN ('admin', 'approved', 'visitor', 'disabled')), + FOREIGN KEY("role") REFERENCES roles ); CREATE TABLE openids( @@ -66,6 +73,22 @@ CREATE TABLE user_jids( ); CREATE INDEX user_jids_user ON user_jids ("user"); +CREATE TABLE role_subroles( + "superrole" INTEGER NOT NULL, + "subrole" INTEGER NOT NULL, + PRIMARY KEY("superrole", "subrole"), + FOREIGN KEY("superrole") REFERENCES roles, + FOREIGN KEY("subrole") REFERENCES roles +); + +CREATE TABLE user_roles( + "user" INTEGER NOT NULL, + "role" INTEGER NOT NULL, + PRIMARY KEY("user", "role"), + FOREIGN KEY("user") REFERENCES users, + FOREIGN KEY("role") REFERENCES roles +); + CREATE TABLE page_keys( "user" INTEGER NOT NULL, page VARCHAR NOT NULL, @@ -120,12 +143,10 @@ CREATE TABLE lazychat_messages( author INTEGER, date TIMESTAMP WITH TIME ZONE DEFAULT now(), content VARCHAR, - visibility VARCHAR NOT NULL, format VARCHAR NOT NULL, PRIMARY KEY(id), FOREIGN KEY(author) REFERENCES users, - CHECK (format IN ('markdown')), - CHECK (visibility IN ('personal', 'protected', 'public')) + CHECK (format IN ('markdown')) ); CREATE TABLE lazychat_targets( @@ -133,7 +154,7 @@ CREATE TABLE lazychat_targets( target INTEGER NOT NULL, PRIMARY KEY(message, target), FOREIGN KEY(message) REFERENCES lazychat_messages, - FOREIGN KEY(target) REFERENCES users + FOREIGN KEY(target) REFERENCES roles ); CREATE TABLE lazychat_references( @@ -144,5 +165,75 @@ CREATE TABLE lazychat_references( FOREIGN KEY(referee) REFERENCES lazychat_messages ); +CREATE VIEW effective_role_subroles AS + WITH RECURSIVE t(superrole, subrole) AS ( + SELECT id, id + FROM roles + UNION + SELECT t.superrole, rs.subrole + FROM t t + INNER JOIN role_subroles rs + ON (rs.superrole = t.subrole) + ) + SELECT * FROM t; + +CREATE VIEW effective_user_roles AS + (SELECT ur."user", er.subrole AS role + FROM user_roles ur + INNER JOIN effective_role_subroles er + ON (er.superrole = ur.role)) + UNION + (SELECT u.id AS "user", rt.role FROM users u, role_tags rt WHERE rt.tag IN ('everyone', 'world')) + UNION + (SELECT NULL, rt.role FROM role_tags rt WHERE rt.tag = 'world'); + +CREATE FUNCTION new_user_put_in_universal_role() RETURNS TRIGGER AS $$ +DECLARE + universal_role INTEGER; +BEGIN + SELECT "role" FROM role_tags WHERE tag = 'everyone' INTO universal_role; + INSERT INTO user_roles VALUES (NEW.id, universal_role); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER new_user_put_in_universal_role + AFTER INSERT ON users + FOR EACH ROW + EXECUTE PROCEDURE put_new_user_in_universal_role(); + +CREATE FUNCTION new_user_put_user_in_user_role() RETURNS TRIGGER AS $$ +BEGIN + INSERT INTO user_roles VALUES (NEW."role", user_role); +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER new_user_put_user_in_user_role + AFTER INSERT ON users + FOR EACH ROW + EXECUTE PROCEDURE new_user_put_user_in_user_role(); + +CREATE FUNCTION new_user_create_user_role() RETURNS TRIGGER AS $$ +DECLARE + new_role INTEGER; +BEGIN + INSERT INTO roles("name") VALUES (concat(NEW.first_name, ' ', NEW.last_name)) + RETURNING id INTO STRICT new_role; + UPDATE users SET "role" = new_role WHERE id = NEW.id; + NEW.role := new_role; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER new_user_create_user_role + BEFORE INSERT ON users + FOR EACH ROW + EXECUTE PROCEDURE new_user_create_user_role(); + +CREATE VIEW user_visible_lazychat_messages AS + SELECT eur.user, t.message + FROM effective_user_roles eur, lazychat_targets t + WHERE t.target = eur.role; + ROLLBACK; --COMMIT; -- cgit v1.2.3