66 lines
1.6 KiB
PL/PgSQL
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;
|