Skip to content
Snippets Groups Projects
Commit e2b2321f authored by Jussi Mäki-Ikola's avatar Jussi Mäki-Ikola
Browse files

added comments

parent eb2e5590
Branches staging
Tags v1.0
No related merge requests found
...@@ -12,3 +12,11 @@ ...@@ -12,3 +12,11 @@
### Running the database ### Running the database
`docker-compose up postgres --build` `docker-compose up postgres --build`
### Browsing the database via psql
```bash
# Accessing the postgres-database inside docker
docker-compose exec postgres psql testdb testuser
# Exit with the command \q
```
\ No newline at end of file
...@@ -34,16 +34,21 @@ CREATE TABLE ${GRAPH_EDITOR_SCHEMA}.person ( ...@@ -34,16 +34,21 @@ CREATE TABLE ${GRAPH_EDITOR_SCHEMA}.person (
created_at timestamp DEFAULT NOW() NOT NULL, created_at timestamp DEFAULT NOW() NOT NULL,
updated_at timestamp DEFAULT NOW() NOT NULL updated_at timestamp DEFAULT NOW() NOT NULL
); );
COMMENT ON TABLE ${GRAPH_EDITOR_SCHEMA}.person IS 'A user of the application';
-- Enable row-level-security and start index from 111, so that we can use test data for ids in range 1-110.
ALTER TABLE ${GRAPH_EDITOR_SCHEMA}.person ENABLE ROW LEVEL SECURITY; ALTER TABLE ${GRAPH_EDITOR_SCHEMA}.person ENABLE ROW LEVEL SECURITY;
ALTER SEQUENCE ${GRAPH_EDITOR_SCHEMA}.person_id_seq RESTART WITH 111; ALTER SEQUENCE ${GRAPH_EDITOR_SCHEMA}.person_id_seq RESTART WITH 111;
CREATE TRIGGER set_timestamp BEFORE UPDATE ON ${GRAPH_EDITOR_SCHEMA}.person CREATE TRIGGER set_timestamp BEFORE UPDATE ON ${GRAPH_EDITOR_SCHEMA}.person
FOR EACH ROW EXECUTE PROCEDURE trigger_set_timestamp(); FOR EACH ROW EXECUTE PROCEDURE trigger_set_timestamp();
-- Grant select and update(email) for person.
-- Note that insert and delete are handled by functions.
GRANT USAGE, SELECT ON SEQUENCE ${GRAPH_EDITOR_SCHEMA}.person_id_seq TO ${GRAPH_EDITOR_SCHEMA}_person; GRANT USAGE, SELECT ON SEQUENCE ${GRAPH_EDITOR_SCHEMA}.person_id_seq TO ${GRAPH_EDITOR_SCHEMA}_person;
GRANT SELECT, UPDATE(email) ON TABLE ${GRAPH_EDITOR_SCHEMA}.person TO ${GRAPH_EDITOR_SCHEMA}_person; GRANT SELECT, UPDATE(email) ON TABLE ${GRAPH_EDITOR_SCHEMA}.person TO ${GRAPH_EDITOR_SCHEMA}_person;
-- Allow ${GRAPH_EDITOR_SCHEMA}_person to only access own data.
CREATE POLICY ${GRAPH_EDITOR_SCHEMA}_person_all_access_to_person CREATE POLICY ${GRAPH_EDITOR_SCHEMA}_person_all_access_to_person
ON ${GRAPH_EDITOR_SCHEMA}.person ON ${GRAPH_EDITOR_SCHEMA}.person
FOR ALL FOR ALL
...@@ -63,12 +68,19 @@ CREATE TABLE ${GRAPH_EDITOR_SCHEMA}.graph ( ...@@ -63,12 +68,19 @@ CREATE TABLE ${GRAPH_EDITOR_SCHEMA}.graph (
created_at timestamp DEFAULT NOW() NOT NULL, created_at timestamp DEFAULT NOW() NOT NULL,
UNIQUE(person_id, name) UNIQUE(person_id, name)
); );
COMMENT ON TABLE ${GRAPH_EDITOR_SCHEMA}.graph IS 'A graph created by a person.';
COMMENT ON COLUMN ${GRAPH_EDITOR_SCHEMA}.graph.name IS 'A readable name for the graph.';
COMMENT ON COLUMN ${GRAPH_EDITOR_SCHEMA}.graph.nodes IS 'A json-array of nodes.';
COMMENT ON COLUMN ${GRAPH_EDITOR_SCHEMA}.graph.edges IS 'A json-array of edges.';
-- Enable row-level-security and start index from 111, so that we can use test data for ids in range 1-110.
ALTER TABLE ${GRAPH_EDITOR_SCHEMA}.graph ENABLE ROW LEVEL SECURITY; ALTER TABLE ${GRAPH_EDITOR_SCHEMA}.graph ENABLE ROW LEVEL SECURITY;
ALTER SEQUENCE ${GRAPH_EDITOR_SCHEMA}.graph_id_seq RESTART WITH 111; ALTER SEQUENCE ${GRAPH_EDITOR_SCHEMA}.graph_id_seq RESTART WITH 111;
CREATE TRIGGER set_timestamp BEFORE UPDATE ON ${GRAPH_EDITOR_SCHEMA}.graph CREATE TRIGGER set_timestamp BEFORE UPDATE ON ${GRAPH_EDITOR_SCHEMA}.graph
FOR EACH ROW EXECUTE PROCEDURE trigger_set_timestamp(); FOR EACH ROW EXECUTE PROCEDURE trigger_set_timestamp();
-- Grant privileges.
GRANT USAGE, SELECT ON SEQUENCE ${GRAPH_EDITOR_SCHEMA}.graph_id_seq TO ${GRAPH_EDITOR_SCHEMA}_person; GRANT USAGE, SELECT ON SEQUENCE ${GRAPH_EDITOR_SCHEMA}.graph_id_seq TO ${GRAPH_EDITOR_SCHEMA}_person;
GRANT GRANT
SELECT, SELECT,
...@@ -76,6 +88,7 @@ GRANT ...@@ -76,6 +88,7 @@ GRANT
UPDATE(name, nodes, edges), UPDATE(name, nodes, edges),
DELETE ON TABLE ${GRAPH_EDITOR_SCHEMA}.graph TO ${GRAPH_EDITOR_SCHEMA}_person; DELETE ON TABLE ${GRAPH_EDITOR_SCHEMA}.graph TO ${GRAPH_EDITOR_SCHEMA}_person;
-- Allow ${GRAPH_EDITOR_SCHEMA}_person to only access graphs that have the same person_id as in the jwt.
CREATE POLICY ${GRAPH_EDITOR_SCHEMA}_person_all_access_to_graph CREATE POLICY ${GRAPH_EDITOR_SCHEMA}_person_all_access_to_graph
ON ${GRAPH_EDITOR_SCHEMA}.graph ON ${GRAPH_EDITOR_SCHEMA}.graph
FOR ALL FOR ALL
...@@ -92,19 +105,32 @@ CREATE TABLE ${GRAPH_EDITOR_SCHEMA}_private.person_account ( ...@@ -92,19 +105,32 @@ CREATE TABLE ${GRAPH_EDITOR_SCHEMA}_private.person_account (
updated_at timestamp DEFAULT NOW() NOT NULL, updated_at timestamp DEFAULT NOW() NOT NULL,
UNIQUE(person_id) UNIQUE(person_id)
); );
COMMENT ON TABLE ${GRAPH_EDITOR_SCHEMA}_private.person_account IS 'Private information about the person.';
COMMENT ON COLUMN ${GRAPH_EDITOR_SCHEMA}_private.person_account.password_hash IS 'A hash of the person''s password.';
-- Enable row-level-security.
ALTER TABLE ${GRAPH_EDITOR_SCHEMA}.person ENABLE ROW LEVEL SECURITY; ALTER TABLE ${GRAPH_EDITOR_SCHEMA}.person ENABLE ROW LEVEL SECURITY;
CREATE TRIGGER set_timestamp BEFORE UPDATE ON ${GRAPH_EDITOR_SCHEMA}_private.person_account CREATE TRIGGER set_timestamp BEFORE UPDATE ON ${GRAPH_EDITOR_SCHEMA}_private.person_account
FOR EACH ROW EXECUTE PROCEDURE trigger_set_timestamp(); FOR EACH ROW EXECUTE PROCEDURE trigger_set_timestamp();
------------------------------------------------
-------------- FUNCTIONS -----------------------
------------------------------------------------
-- The below functions are marked with the keyword 'security definer',
-- which means that the functions are called with the owner's privileges.
-- This means that the statements inside the function bybass the row-level-security.
-- The type that postgraphile uses for creating json-web-tokens.
CREATE TYPE ${GRAPH_EDITOR_SCHEMA}.auth_token as ( CREATE TYPE ${GRAPH_EDITOR_SCHEMA}.auth_token as (
role text, role text,
person_id integer, person_id integer,
exp bigint exp bigint
); );
-- Authentication function. This is called when logging in.
CREATE FUNCTION ${GRAPH_EDITOR_SCHEMA}.authenticate( CREATE FUNCTION ${GRAPH_EDITOR_SCHEMA}.authenticate(
email text, email text,
password text password text
...@@ -131,10 +157,14 @@ BEGIN ...@@ -131,10 +157,14 @@ BEGIN
END IF; END IF;
END; END;
$$ language plpgsql strict security definer; $$ language plpgsql strict security definer;
COMMENT ON FUNCTION ${GRAPH_EDITOR_SCHEMA}.authenticate(text, text) is 'Authenticates a person by email and password. Returns a JWT.';
-- Allow an anonymous user to authenticate.
GRANT EXECUTE ON FUNCTION ${GRAPH_EDITOR_SCHEMA}.authenticate(text, text) TO ${GRAPH_EDITOR_SCHEMA}_anonymous; GRANT EXECUTE ON FUNCTION ${GRAPH_EDITOR_SCHEMA}.authenticate(text, text) TO ${GRAPH_EDITOR_SCHEMA}_anonymous;
-- Person-registration function.
CREATE FUNCTION ${GRAPH_EDITOR_SCHEMA}.register_person( CREATE FUNCTION ${GRAPH_EDITOR_SCHEMA}.register_person(
email text, email text,
password text password text
...@@ -156,10 +186,14 @@ BEGIN ...@@ -156,10 +186,14 @@ BEGIN
)::${GRAPH_EDITOR_SCHEMA}.auth_token; )::${GRAPH_EDITOR_SCHEMA}.auth_token;
END; END;
$$ language plpgsql strict security definer; $$ language plpgsql strict security definer;
COMMENT ON FUNCTION ${GRAPH_EDITOR_SCHEMA}.register_person(text, text) is 'Registers a person by email and password. Returns a JWT.';
-- Allow an anonymous user to register.
GRANT EXECUTE ON FUNCTION ${GRAPH_EDITOR_SCHEMA}.register_person(text, text) TO ${GRAPH_EDITOR_SCHEMA}_anonymous; GRANT EXECUTE ON FUNCTION ${GRAPH_EDITOR_SCHEMA}.register_person(text, text) TO ${GRAPH_EDITOR_SCHEMA}_anonymous;
-- Function that removes a person from the database.
-- Note that this is the only way a person can delete the account.
CREATE FUNCTION ${GRAPH_EDITOR_SCHEMA}.remove_person( CREATE FUNCTION ${GRAPH_EDITOR_SCHEMA}.remove_person(
email text, email text,
password text password text
...@@ -172,6 +206,7 @@ BEGIN ...@@ -172,6 +206,7 @@ BEGIN
FROM ${GRAPH_EDITOR_SCHEMA}_private.person_account a, ${GRAPH_EDITOR_SCHEMA}.person p FROM ${GRAPH_EDITOR_SCHEMA}_private.person_account a, ${GRAPH_EDITOR_SCHEMA}.person p
WHERE p.email = $1 AND p.id = a.person_id; WHERE p.email = $1 AND p.id = a.person_id;
-- Throw error if the person is trying to remove another person's account.
IF (account.person_id != person_id_from_jwt) THEN IF (account.person_id != person_id_from_jwt) THEN
RAISE EXCEPTION 'unauthorized'; RAISE EXCEPTION 'unauthorized';
END IF; END IF;
...@@ -185,7 +220,9 @@ BEGIN ...@@ -185,7 +220,9 @@ BEGIN
RETURN true; RETURN true;
END; END;
$$ language plpgsql strict security definer; $$ language plpgsql strict security definer;
COMMENT ON FUNCTION ${GRAPH_EDITOR_SCHEMA}.remove_person(text, text) is 'Removes an authenticated person by email and password.';
-- Only allow an authenticated user to run this function.
GRANT EXECUTE ON FUNCTION ${GRAPH_EDITOR_SCHEMA}.remove_person(text, text) TO ${GRAPH_EDITOR_SCHEMA}_person; GRANT EXECUTE ON FUNCTION ${GRAPH_EDITOR_SCHEMA}.remove_person(text, text) TO ${GRAPH_EDITOR_SCHEMA}_person;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment