numerus/deploy/login.sql

66 lines
1.6 KiB
PL/PgSQL

-- Deploy numerus:login to pg
-- requires: roles
-- requires: schema_numerus
-- requires: schema_auth
-- requires: extension_pgcrypto
-- requires: email
-- requires: user
-- requires: login_attempt
-- requires: build_cookie
begin;
set search_path to numerus, auth;
create or replace function login(email email, password text, ip_address inet default null) returns text as
$$
declare
user_cookie text;
begin
if not exists (
select *
from "user"
where "user".email = login.email
and "user".password = crypt(login.password, "user".password)
) then
insert into login_attempt
(user_name, ip_address, success)
values (login.email, login.ip_address, false);
return '';
end if;
select cookie
into user_cookie
from "user"
where "user".email = login.email
and cookie_expires_at > current_timestamp
and length(cookie) > 30;
if user_cookie is null then
select encode(gen_random_bytes(25), 'hex') into user_cookie;
end if;
update "user"
set cookie = user_cookie
, cookie_expires_at = current_timestamp + interval '1 year'
where "user".email = login.email;
insert into login_attempt
(user_name, ip_address, success)
values (login.email, login.ip_address, true);
return build_cookie(email, user_cookie);
end;
$$
language plpgsql
security definer
set search_path = auth, numerus, pg_temp;
comment on function login(email, text, inet) is
'Tries to logs a user in, recording the attempt, and returns the cookie to send back to the user if the authentication was successfull.';
revoke execute on function login(email, text, inet) from public;
grant execute on function login(email, text, inet) to guest;
commit;