feat: usr_session_touch

This commit is contained in:
Orion Kindel 2023-07-16 02:19:11 -04:00
parent 202de79400
commit 5f9c3c7b8e
Signed by untrusted user who does not match committer: orion
GPG Key ID: 6D4165AE4C928719
3 changed files with 55 additions and 9 deletions

View File

@ -14,12 +14,16 @@ begin
, '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 \'', qualified_name, '.', columns[1], E' is immutable\' using errcode = \'restrict_violation\';\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 \'', qualified_name, '.', col, E' is immutable\' using errcode = \'restrict_violation\';\n'
, E' raise exception \'immutable_field\'\n'
, E' using detail = \'', qualified_name, '.', col, E' is immutable\',\n'
, E' errcode = \'restrict_violation\';\n'
);
end loop;

View File

@ -75,7 +75,7 @@ language plpgsql
as $$
begin
if new.tag = usr_tag_of_string('root') then
raise exception 'invalid tag';
raise exception 'tag_invalid';
else
return new;
end if;

View File

@ -21,9 +21,9 @@ create type usr_session_device as enum
create table public.usr_session
( id int not null primary key generated always as identity
, key public.usr_session_key not null unique
, expired boolean not null default false
, expires_at timestamp not null
, usr int not null references public.usr (id)
, remembered boolean not null default false
, location text null
, device usr_session_device null
, ip inet null
@ -41,6 +41,48 @@ select immutable( 'public'
]
);
create function public.usr_session_touch(session public.usr_session_key)
returns public.usr
language plpgsql
volatile
as $$
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;
$$;
create function public.usr_session_login_validate
( tag_or_email public.usr_tag_or_email
, password text
@ -62,19 +104,19 @@ begin
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 for user %', usr_tag_or_email_to_string(tag_or_email);
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 for user %', 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 for user %', usr_tag_or_email_to_string(tag_or_email);
raise exception 'incorrect_password';
end if;
return usr;
@ -107,9 +149,9 @@ begin
end if;
insert into public.usr_session
(key, expires_at, usr, location, device, ip)
(key, expires_at, usr, remembered, location, device, ip)
values
(key, expires_at, usr.id, location, device, ip);
(key, expires_at, usr.id, remember, location, device, ip);
return key;
end;