“Merge” find_user_role and login

I honestly do not remember why i thought i needed the find_user
function: it is just a select with a query that i only need in a single
place—when login.

I belive it was a missguided attempt to “write the function safer”, in
hopes that calling a function won’t have the same problems as when
querying a table, but this is fixed with the search_path, that i added.

There is no pgTAP for this, i believe.
This commit is contained in:
jordi fita mas 2023-01-17 13:18:12 +01:00
parent 8fd22672c7
commit 97ac586a3b
6 changed files with 14 additions and 99 deletions

View File

@ -1,26 +0,0 @@
-- Deploy numerus:find_user_role to pg
-- requires: schema_auth
-- requires: user
-- requires: email
begin;
set search_path to auth, numerus, public;
create or replace function find_user_role(email email, password text) returns name
as
$$
select role
from auth."user"
where "user".email = find_user_role.email
and "user".password = crypt(find_user_role.password, "user".password);
$$
language sql
stable;
comment on function find_user_role(email, text) is
'Return the database role assigned to the user with the given email and password';
revoke execute on function find_user_role(email, text) from public;
commit;

View File

@ -1,9 +1,9 @@
-- Deploy numerus:login to pg
-- requires: roles
-- requires: schema_numerus
-- requires: schema_auth
-- requires: email
-- requires: user
-- requires: find_user_role
begin;
@ -12,18 +12,25 @@ set search_path to numerus, auth;
create or replace function login(email email, password text) returns name as
$$
declare
role name;
user_role name;
begin
select auth.find_user_role(email, password) into role;
if role is null then
select role
into user_role
from "user"
where "user".email = login.email
and "user".password = crypt(login.password, "user".password);
if user_role is null then
raise invalid_password using message = 'invalid user or password';
end if;
return role;
return user_role;
end;
$$
language plpgsql
stable
security definer;
security definer
set search_path = auth, numerus, pg_temp;
comment on function login(email, text) is
'Checks that the email and password pair is valid and returns the users databasse role.';

View File

@ -1,7 +0,0 @@
-- Revert numerus:find_user_role from pg
begin;
drop function if exists auth.find_user_role(numerus.email, text);
commit;

View File

@ -12,5 +12,4 @@ user [roles schema_auth email] 2023-01-12T23:44:03Z jordi fita i mas <jfita@info
ensure_role_exists [schema_auth user] 2023-01-12T23:57:59Z jordi fita i mas <jfita@infoblitz.com> # Add trigger to ensure the users role exists
extension_pgcrypto [schema_auth] 2023-01-13T00:11:50Z jordi fita i mas <jfita@infoblitz.com> # Add pgcrypto extension
encrypt_password [schema_auth user extension_pgcrypto] 2023-01-13T00:14:30Z jordi fita i mas <jfita@infoblitz.com> # Add trigger to encrypt users password
find_user_role [schema_auth user email] 2023-01-13T00:22:34Z jordi fita i mas <jfita@infoblitz.com> # Add function to find a users role given its email and password
login [roles schema_numerus email user find_user_role] 2023-01-13T00:32:32Z jordi fita i mas <jfita@infoblitz.com> # Add function to login
login [roles schema_numerus schema_auth email user] 2023-01-13T00:32:32Z jordi fita i mas <jfita@infoblitz.com> # Add function to login

View File

@ -1,51 +0,0 @@
-- Test find_user_role
set client_min_messages to warning;
create extension if not exists pgtap;
reset client_min_messages;
begin;
select plan(12);
set search_path to auth, numerus, public;
select has_function('find_user_role');
select function_lang_is('find_user_role', array ['email', 'text'], 'sql');
select function_returns('find_user_role', array ['email', 'text'], 'name');
select isnt_definer('find_user_role', array ['email', 'text']);
select volatility_is('find_user_role', array ['email', 'text'], 'stable');
select function_privs_are('find_user_role', array ['email', 'text'], 'guest', array []::text[]);
select function_privs_are('find_user_role', array ['email', 'text'], 'invoicer', array []::text[]);
select function_privs_are('find_user_role', array ['email', 'text'], 'admin', array []::text[]);
select function_privs_are('find_user_role', array ['email', 'text'], 'authenticator', array []::text[]);
set client_min_messages to warning;
truncate "user" cascade;
reset client_min_messages;
insert into "user" (email, name, password, role)
values ('info@tandem.blog', 'Perita', 'test', 'guest');
select is(
find_user_role('info@tandem.blog', 'test'),
'guest'::name,
'Should find the role with the correct email and password'
);
select is(
find_user_role('info@tandem.blog', 'mah password'),
NULL::name,
'Should not find any role with an invalid password'
);
select is(
find_user_role('nope@tandem.blog', 'test'),
NULL::name,
'Should not find any role with an invalid email'
);
select *
from finish();
rollback;

View File

@ -1,7 +0,0 @@
-- Verify numerus:find_user_role on pg
begin;
select has_function_privilege('auth.find_user_role(numerus.email, text)', 'execute');
rollback;