numerus/deploy/check_cookie.sql
jordi fita mas ea9e830a75 Add user_profile view to update the profile with form
Since users do not have access to the auth scheme, i had to add a view
that selects only the data that they can see of themselves (i.e., no
password or cookie).

I wanted to use the `request.user.id` setting that i set in
check_cookie, but this would be bad because anyone can change that
parameter and, since the view is created by the owner, could see and
*change* the values of everyone just by knowing their id.  Thus, now i
use the cookie instead, because it is way harder to figure out, and if
you already have it you can just set to your browser and the user is
fucked anyway; the database can not help here.

I **am** going to use the user id in row level security policies, but
not the value coming for the setting but instaed the one in the
`user_profile`, since it already is “derived” from the cookie, that’s
why i added that column to the view.

The profile includes the language, that i do not use it yet to switch
the locale, so i had to add a relation of the available languages, for
constraint purposes.  There is no NULL language, and instead i added the
“Undefined” language, with ‘und’ tag’, to represent “do not know/use
content negotiation”.

The languages in that relation are the same i used to have inside
locale.go, because there is no point on having options for languages i
do not have the translation for, so i now configure the list of
available languages user in content negotiation from that relation.

Finally, i have added all font from RemixIcon because that’s what we
used in the design and i am going to use quite a lot of them.

There is duplication in the views; i will address that in a different
commit.
2023-01-22 02:23:09 +01:00

49 lines
1.2 KiB
PL/PgSQL

-- Deploy numerus:check_cookie to pg
-- requires: schema_public
-- requires: user
begin;
set search_path to public, numerus, auth;
create or replace function check_cookie(input_cookie text) returns name as
$$
declare
uid text;
user_email text;
user_role name;
user_cookie text;
begin
select user_id::text, email::text, role, cookie
into uid, user_email, user_role, user_cookie
from "user"
where email = split_part(input_cookie, '/', 2)
and cookie_expires_at > current_timestamp
and length(password) > 0
and cookie = split_part(input_cookie, '/', 1)
;
if user_role is null then
uid := '0';
user_email := '';
user_cookie := '';
user_role := 'guest'::name;
end if;
perform set_config('request.user.id', uid, false);
perform set_config('request.user.email', user_email, false);
perform set_config('request.user.cookie', user_cookie, false);
return user_role;
end;
$$
language plpgsql
security definer
stable
set search_path = auth, numerus, pg_temp;
comment on function check_cookie(text) is
'Checks whether a given cookie is for a valid users, returning its email and role';
revoke execute on function check_cookie(text) from public;
grant execute on function check_cookie(text) to authenticator;
commit;