-- 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;