From 7bae429fcaa16e0235dce03e74e1aacfdb662e53 Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Wed, 14 Jul 2021 00:14:15 +0200
Subject: [PATCH] =?UTF-8?q?DB:=20Tabulka=20registra=C4=8Dn=C3=ADch=20token?=
 =?UTF-8?q?=C5=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Chceme umět limitovat četnost registrací a invalidovat už použité
tokeny, takže si všechny dosud neexpirované registrace pamatujeme v DB.
---
 db/db.ddl               | 21 +++++++++++++++++++++
 db/upgrade-20210712.sql | 19 +++++++++++++++++++
 mo/db.py                | 23 +++++++++++++++++++++++
 3 files changed, 63 insertions(+)

diff --git a/db/db.ddl b/db/db.ddl
index b0808cd7..0800fb38 100644
--- a/db/db.ddl
+++ b/db/db.ddl
@@ -322,3 +322,24 @@ CREATE TABLE messages (
 	markdown	text		NOT NULL,
 	html		text		NOT NULL
 );
+
+-- Požadavky na registraci a změny vlastností účtu
+
+CREATE TYPE reg_req_type AS ENUM (
+	'register',
+	'change',
+	'reset'
+);
+
+CREATE TABLE reg_requests (
+	reg_id		serial		PRIMARY KEY,
+	type		reg_req_type	NOT NULL,
+	created_at	timestamp with time zone NOT NULL,
+	expires_at	timestamp with time zone NOT NULL,
+	used_at		timestamp with time zone DEFAULT NULL,
+	email		varchar(255)	DEFAULT NULL,			-- adresa, kterou potvrzujeme
+	captcha_token	varchar(255)	DEFAULT NULL,			-- token pro fázi 1 registrace
+	email_token	varchar(255)	UNIQUE NOT NULL,		-- token pro fázi 2 registrace
+	user_id		int		DEFAULT NULL REFERENCES users(user_id) ON DELETE CASCADE,
+	client		varchar(255)	NOT NULL			-- kdo si registraci vyžádal
+);
diff --git a/db/upgrade-20210712.sql b/db/upgrade-20210712.sql
index 737c4b66..ec6ad79b 100644
--- a/db/upgrade-20210712.sql
+++ b/db/upgrade-20210712.sql
@@ -14,3 +14,22 @@ ALTER TYPE part_state ADD VALUE 'active' AFTER 'invited';
 ALTER TABLE participants ADD COLUMN registered_on timestamp with time zone DEFAULT NULL;
 
 UPDATE participations SET state='active' WHERE state IN ('registered', 'invited');
+
+CREATE TYPE reg_req_type AS ENUM (
+	'register',
+	'change',
+	'reset'
+);
+
+CREATE TABLE reg_requests (
+	reg_id		serial		PRIMARY KEY,
+	type		reg_req_type	NOT NULL,
+	created_at	timestamp with time zone NOT NULL,
+	expires_at	timestamp with time zone NOT NULL,
+	used_at		timestamp with time zone DEFAULT NULL,
+	email		varchar(255)	DEFAULT NULL,
+	captcha_token	varchar(255)	DEFAULT NULL,
+	email_token	varchar(255)	UNIQUE NOT NULL,
+	user_id		int		DEFAULT NULL REFERENCES users(user_id) ON DELETE CASCADE,
+	client		varchar(255)	NOT NULL
+);
diff --git a/mo/db.py b/mo/db.py
index 7ef56460..6fbf140d 100644
--- a/mo/db.py
+++ b/mo/db.py
@@ -661,6 +661,29 @@ class Message(Base):
     created_by_user = relationship('User')
 
 
+class RegReqType(MOEnum):
+    register = auto()
+    change = auto()
+    reset = auto()
+
+
+class RegRequest(Base):
+    __tablename__ = 'reg_requests'
+
+    reg_id = Column(Integer, primary_key=True, server_default=text("nextval('reg_requests_reg_id_seq'::regclass)"))
+    type = Column(Enum(RegReqType, name='reg_req_type'), nullable=False)
+    created_at = Column(DateTime(True), nullable=False)
+    expires_at = Column(DateTime(True), nullable=False)
+    used_at = Column(DateTime(True))
+    captcha_token = Column(Text)
+    email = Column(Text)
+    email_token = Column(Text, nullable=False, unique=True)
+    user_id = Column(Integer, ForeignKey('users.user_id'))
+    client = Column(Text, nullable=False)
+
+    user = relationship('User')
+
+
 _engine: Optional[Engine] = None
 _session: Optional[Session] = None
 flask_db: Any = None
-- 
GitLab