summaryrefslogtreecommitdiff
path: root/db/rest/user
diff options
context:
space:
mode:
Diffstat (limited to 'db/rest/user')
-rw-r--r--db/rest/user/api_avatar.sql22
-rw-r--r--db/rest/user/api_user.sql23
-rw-r--r--db/rest/user/api_user_delete.sql30
-rw-r--r--db/rest/user/api_user_insert.sql121
-rw-r--r--db/rest/user/api_user_update.sql21
5 files changed, 217 insertions, 0 deletions
diff --git a/db/rest/user/api_avatar.sql b/db/rest/user/api_avatar.sql
new file mode 100644
index 0000000..981409f
--- /dev/null
+++ b/db/rest/user/api_avatar.sql
@@ -0,0 +1,22 @@
+CREATE FUNCTION api.avatar(
+ user_id INTEGER DEFAULT 0
+)
+RETURNS sys."*/*"
+LANGUAGE plpgsql VOLATILE
+AS $BODY$
+DECLARE
+ _mod INTEGER;
+ _name TEXT;
+BEGIN
+ _mod = MOD(user_id, 24);
+ _name = 'default_avatar_' || _mod || '.png';
+ RETURN _api.serve_media(_name);
+END
+$BODY$;
+
+GRANT EXECUTE ON FUNCTION api.avatar(INTEGER)
+ TO rest_anon, rest_user;
+GRANT SELECT ON TABLE admin.user
+ TO rest_anon, rest_user;
+GRANT SELECT ON TABLE admin.media
+ TO rest_anon, rest_user;
diff --git a/db/rest/user/api_user.sql b/db/rest/user/api_user.sql
new file mode 100644
index 0000000..e45768a
--- /dev/null
+++ b/db/rest/user/api_user.sql
@@ -0,0 +1,23 @@
+CREATE VIEW api.user AS
+ SELECT
+ u.id,
+ u.username,
+ NULL AS password,
+ u.role,
+ u.first_name,
+ u.last_name,
+ u.middle_name,
+ u.email,
+ u.gender,
+ u.join_date,
+ u.birth_date,
+ u.profile_avatar,
+ u.profile_banner,
+ u.profile_bio
+ FROM
+ admin.user u;
+
+GRANT SELECT ON TABLE api.user
+ TO rest_anon, rest_user;
+GRANT SELECT ON TABLE admin.user
+ TO rest_anon, rest_user;
diff --git a/db/rest/user/api_user_delete.sql b/db/rest/user/api_user_delete.sql
new file mode 100644
index 0000000..8d7d52f
--- /dev/null
+++ b/db/rest/user/api_user_delete.sql
@@ -0,0 +1,30 @@
+CREATE FUNCTION _api.user_delete()
+RETURNS TRIGGER
+LANGUAGE plpgsql VOLATILE
+AS $BODY$
+DECLARE
+ _user_id INTEGER;
+BEGIN
+ _user_id = _api.get_user_id();
+
+ IF OLD.id <> _user_id THEN
+ PERFORM _api.raise_deny();
+ END IF;
+
+ DELETE FROM admin.user
+ WHERE id = _user_id;
+END
+$BODY$;
+
+GRANT EXECUTE ON FUNCTION _api.user_delete()
+ TO rest_user;
+GRANT DELETE ON TABLE api.user
+ TO rest_user;
+GRANT DELETE ON TABLE admin.user
+ TO rest_user;
+
+CREATE TRIGGER api_user_delete_trgr
+ INSTEAD OF DELETE
+ ON api.user
+ FOR EACH ROW
+ EXECUTE PROCEDURE _api.user_delete();
diff --git a/db/rest/user/api_user_insert.sql b/db/rest/user/api_user_insert.sql
new file mode 100644
index 0000000..da3ae2d
--- /dev/null
+++ b/db/rest/user/api_user_insert.sql
@@ -0,0 +1,121 @@
+CREATE FUNCTION _api.user_insert()
+RETURNS TRIGGER
+LANGUAGE plpgsql VOLATILE
+AS $BODY$
+DECLARE
+ _length INTEGER;
+BEGIN
+ PERFORM _api.validate_text(
+ _text => NEW.username,
+ _column => 'username',
+ _min => 1,
+ _max => 24
+ );
+
+ PERFORM TRUE FROM admin.user
+ WHERE username = NEW.username;
+
+ IF FOUND THEN
+ PERFORM _api.raise_unique('username');
+ END IF;
+
+ PERFORM _api.validate_text(
+ _text => NEW.password,
+ _column => 'password',
+ _max => 256
+ );
+
+ PERFORM _api.validate_text(
+ _text => NEW.first_name,
+ _nullable => TRUE,
+ _column => 'first_name',
+ _max => 256
+ );
+ NEW.first_name = COALESCE(NEW.first_name, ''::text);
+
+ PERFORM _api.validate_text(
+ _text => NEW.last_name,
+ _nullable => TRUE,
+ _column => 'last_name',
+ _max => 256
+ );
+ NEW.last_name = COALESCE(NEW.last_name, ''::text);
+
+ PERFORM _api.validate_text(
+ _text => NEW.middle_name,
+ _nullable => TRUE,
+ _column => 'middle_name',
+ _max => 256
+ );
+ NEW.middle_name = COALESCE(NEW.middle_name, ''::text);
+
+ PERFORM _api.validate_text(
+ _text => NEW.email,
+ _column => 'email',
+ _max => 256
+ );
+
+ PERFORM _api.validate_text(
+ _text => NEW.gender,
+ _column => 'gender',
+ _max => 256
+ );
+
+ IF NEW.birth_date IS NULL THEN
+ PERFORM _api.raise_null('birth_date');
+ END IF;
+
+ PERFORM _api.validate_text(
+ _text => NEW.profile_bio,
+ _nullable => TRUE,
+ _column => 'profile_bio',
+ _max => 2048
+ );
+ NEW.profile_bio = COALESCE(NEW.profile_bio, ''::text);
+
+ INSERT INTO admin.user (
+ username,
+ password,
+ first_name,
+ last_name,
+ middle_name,
+ email,
+ gender,
+ birth_date,
+ profile_avatar,
+ profile_banner,
+ profile_bio
+ ) VALUES (
+ NEW.username,
+ NEW.password,
+ NEW.first_name,
+ NEW.last_name,
+ NEW.middle_name,
+ NEW.email,
+ NEW.gender,
+ NEW.birth_date,
+ NEW.profile_avatar,
+ NEW.profile_banner,
+ NEW.profile_bio
+ );
+
+ NEW.password := NULL;
+
+ RETURN NEW;
+END
+$BODY$;
+
+GRANT EXECUTE ON FUNCTION _api.user_insert()
+ TO rest_anon, rest_user;
+GRANT INSERT ON TABLE api.user
+ TO rest_anon, rest_user;
+GRANT INSERT ON TABLE admin.user
+ TO rest_anon, rest_user;
+GRANT UPDATE ON TABLE sys.user_id_seq
+ TO rest_anon, rest_user;
+
+CREATE TRIGGER api_user_insert_trgr
+ INSTEAD OF INSERT
+ ON api.user
+ FOR EACH ROW
+ EXECUTE PROCEDURE _api.user_insert();
diff --git a/db/rest/user/api_user_update.sql b/db/rest/user/api_user_update.sql
new file mode 100644
index 0000000..c6e7f4f
--- /dev/null
+++ b/db/rest/user/api_user_update.sql
@@ -0,0 +1,21 @@
+CREATE FUNCTION _api.user_update()
+RETURNS TRIGGER
+LANGUAGE plpgsql VOLATILE
+AS $BODY$
+DECLARE
+ _length INTEGER;
+BEGIN
+ RETURN NEW;
+END
+$BODY$;
+
+GRANT EXECUTE ON FUNCTION _api.user_update()
+ TO rest_user;
+GRANT DELETE ON TABLE api.user
+ TO rest_user;
+
+CREATE TRIGGER api_user_update_trgr
+ INSTEAD OF UPDATE
+ ON api.user
+ FOR EACH ROW
+ EXECUTE PROCEDURE _api.user_update();