./migrations/202de79_to_5f9c3c7.sql
This commit is contained in:
parent
7fde5ae5a3
commit
1a95cd0462
442
202de79_to_5f9c3c7.sql
Normal file
442
202de79_to_5f9c3c7.sql
Normal file
@ -0,0 +1,442 @@
|
||||
alter table "public"."usr_session" drop column "expired";
|
||||
|
||||
alter table "public"."usr_session" add column "remembered" boolean not null default false;
|
||||
|
||||
set check_function_bodies = off;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.usr_session_touch(session usr_session_key)
|
||||
RETURNS usr
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
declare
|
||||
session public.usr_session;
|
||||
session_usr public.usr;
|
||||
new_exp timestamp;
|
||||
begin
|
||||
select s
|
||||
from public.usr_session s
|
||||
where s.key = session
|
||||
into session;
|
||||
|
||||
if session is null then
|
||||
raise exception 'usr_session_invalid';
|
||||
end if;
|
||||
|
||||
if session.expires_at <= now() then
|
||||
raise exception 'usr_session_expired';
|
||||
end if;
|
||||
|
||||
if session.remembered then
|
||||
new_exp := now() + interval '1 week';
|
||||
else
|
||||
new_exp := now() + interval '1 hour';
|
||||
end if;
|
||||
|
||||
update public.usr_session s
|
||||
set s.expires_at = new_exp
|
||||
where s.id = session.id;
|
||||
|
||||
select u.*
|
||||
from public.usr u
|
||||
where u.id = session.usr
|
||||
into session_usr;
|
||||
|
||||
return session_usr;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_check_usr_tag()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
STABLE
|
||||
AS $function$
|
||||
begin
|
||||
if new.tag = usr_tag_of_string('root') then
|
||||
raise exception 'tag_invalid';
|
||||
else
|
||||
return new;
|
||||
end if;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_community_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.community.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.uid <> NEW.uid then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.community.uid is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_grp_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.grp.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.uid <> NEW.uid then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.grp.uid is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.tag <> NEW.tag then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.grp.tag is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_perm_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.perm.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.uid <> NEW.uid then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.perm.uid is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.path <> NEW.path then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.perm.path is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_thread_attachment_emoji_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment_emoji.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.uid <> NEW.uid then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment_emoji.uid is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.thread_attachment <> NEW.thread_attachment then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment_emoji.thread_attachment is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.emoji <> NEW.emoji then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment_emoji.emoji is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_thread_attachment_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.uid <> NEW.uid then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment.uid is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.thread <> NEW.thread then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment.thread is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.kind <> NEW.kind then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment.kind is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_thread_attachment_vote_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment_vote.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.uid <> NEW.uid then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment_vote.uid is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.thread_attachment <> NEW.thread_attachment then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment_vote.thread_attachment is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.direction <> NEW.direction then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_attachment_vote.direction is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_thread_feed_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_feed.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.uid <> NEW.uid then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_feed.uid is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.thread <> NEW.thread then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_feed.thread is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.community <> NEW.community then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread_feed.community is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_thread_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.uid <> NEW.uid then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread.uid is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.kind <> NEW.kind then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.thread.kind is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_usr_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.usr.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.uid <> NEW.uid then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.usr.uid is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.do_usr_session_immutable_columns()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
if OLD.id <> NEW.id then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.usr_session.id is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.key <> NEW.key then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.usr_session.key is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.expires_at <> NEW.expires_at then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.usr_session.expires_at is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.usr <> NEW.usr then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.usr_session.usr is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.location <> NEW.location then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.usr_session.location is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.device <> NEW.device then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.usr_session.device is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
elsif OLD.ip <> NEW.ip then
|
||||
raise exception 'immutable_field'
|
||||
using detail = 'public.usr_session.ip is immutable',
|
||||
errcode = 'restrict_violation';
|
||||
end if;
|
||||
|
||||
return NEW;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.immutable(schema text, table_ text, columns text[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
declare
|
||||
col text;
|
||||
qualified_name text := concat(schema, '.', table_);
|
||||
do_table_immutable_columns text := concat('do_', table_, '_immutable_columns');
|
||||
trigger_table_immutable_columns text := concat('trigger_', table_, '_immutable_columns');
|
||||
create_do_table_immutable_columns text;
|
||||
create_trigger_table_immutable_columns text;
|
||||
begin
|
||||
create_do_table_immutable_columns := concat( create_do_table_immutable_columns
|
||||
, 'create function ', schema, '.', do_table_immutable_columns, E'() returns trigger language plpgsql as \$\$\n'
|
||||
, E'begin\n'
|
||||
, ' if OLD.', columns[1], ' <> NEW.', columns[1], E' then\n'
|
||||
, E' raise exception \'immutable_field\'\n'
|
||||
, E' using detail = \'', qualified_name, '.', columns[1], E' is immutable\',\n'
|
||||
, E' errcode = \'restrict_violation\';\n'
|
||||
);
|
||||
foreach col in array columns[2:] loop
|
||||
create_do_table_immutable_columns := concat( create_do_table_immutable_columns
|
||||
, E' elsif OLD.', col, ' <> NEW.', col, E' then\n'
|
||||
, E' raise exception \'immutable_field\'\n'
|
||||
, E' using detail = \'', qualified_name, '.', col, E' is immutable\',\n'
|
||||
, E' errcode = \'restrict_violation\';\n'
|
||||
);
|
||||
end loop;
|
||||
|
||||
create_do_table_immutable_columns := concat( create_do_table_immutable_columns
|
||||
, E' end if;\n'
|
||||
, E'\n'
|
||||
, E' return NEW;\n'
|
||||
, E'end;\n'
|
||||
, E'\$\$;\n'
|
||||
);
|
||||
|
||||
create_trigger_table_immutable_columns := concat( create_trigger_table_immutable_columns
|
||||
, 'create trigger ', trigger_table_immutable_columns, E'\n'
|
||||
, 'before update on ', qualified_name, E'\n'
|
||||
, 'for each row execute function ', do_table_immutable_columns, '();'
|
||||
);
|
||||
|
||||
execute create_do_table_immutable_columns;
|
||||
execute create_trigger_table_immutable_columns;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.usr_session_login(tag_or_email usr_tag_or_email, password text, remember boolean DEFAULT false, location text DEFAULT NULL::text, device usr_session_device DEFAULT NULL::usr_session_device, ip inet DEFAULT NULL::inet)
|
||||
RETURNS usr_session_key
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
declare
|
||||
usr public.usr;
|
||||
key public.usr_session_key := usr_session_key_gen();
|
||||
expires_at timestamp;
|
||||
begin
|
||||
usr := public.usr_session_login_validate(tag_or_email, password);
|
||||
|
||||
if remember then
|
||||
expires_at := now() + interval '1 week';
|
||||
else
|
||||
expires_at := now() + interval '1 hour';
|
||||
end if;
|
||||
|
||||
insert into public.usr_session
|
||||
(key, expires_at, usr, remembered, location, device, ip)
|
||||
values
|
||||
(key, expires_at, usr.id, remember, location, device, ip);
|
||||
|
||||
return key;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.usr_session_login_validate(tag_or_email usr_tag_or_email, password text)
|
||||
RETURNS usr
|
||||
LANGUAGE plpgsql
|
||||
STABLE
|
||||
AS $function$
|
||||
declare
|
||||
usr_email public.email := public.usr_tag_or_email_to_email(tag_or_email);
|
||||
usr_tag public.usr_tag := public.usr_tag_or_email_to_tag(tag_or_email);
|
||||
usr public.usr;
|
||||
begin
|
||||
select *
|
||||
from public.usr as u
|
||||
where u.email = usr_email
|
||||
or u.tag = usr_tag
|
||||
into usr;
|
||||
|
||||
if usr.id = 1 or usr.tag = usr_tag_of_string('root') then
|
||||
raise notice 'root user may not be logged into';
|
||||
raise exception 'incorrect_password';
|
||||
end if;
|
||||
|
||||
if usr is null then
|
||||
-- prevent email guess bruteforces by raising the same exception
|
||||
-- for invalid password and user not found
|
||||
raise notice 'user % not found', usr_tag_or_email_to_string(tag_or_email);
|
||||
raise exception 'incorrect_password';
|
||||
end if;
|
||||
|
||||
if not hashed_text_matches(password, usr.password) then
|
||||
raise notice 'password does not match for user %', usr_tag_or_email_to_string(tag_or_email);
|
||||
raise exception 'incorrect_password';
|
||||
end if;
|
||||
|
||||
return usr;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user