numerus/deploy/user_profile.sql

72 lines
1.6 KiB
MySQL
Raw Permalink Normal View History

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 01:23:09 +00:00
-- Deploy numerus:user_profile to pg
-- requires: schema_numerus
-- requires: user
-- requires: current_user_cookie
-- requires: current_user_email
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 01:23:09 +00:00
begin;
set search_path to numerus, public;
create or replace view user_profile
with (security_barrier)
as
select user_id
, email
, name
, role
, lang_tag
, left(cookie, 10) as csrf_token
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 01:23:09 +00:00
from auth."user"
where email = current_user_email()
and cookie = current_user_cookie()
and cookie_expires_at > current_timestamp
and length(cookie) > 30
union all
select 0
, null::email
, ''
, 'guest'::name
, 'und'
, ''
where not exists (
select 1
from auth."user"
where email = current_user_email()
and cookie = current_user_cookie()
and cookie_expires_at > current_timestamp
and length(cookie) > 30
);
grant select on table user_profile to guest;
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 01:23:09 +00:00
grant select, update(email, name, lang_tag) on table user_profile to invoicer;
grant select, update(email, name, lang_tag) on table user_profile to admin;
create or replace function update_user_profile() returns trigger as
$$
begin
update auth."user"
set email = new.email
, name = new.name
, lang_tag = new.lang_tag
where email = current_user_email()
and cookie = current_user_cookie()
and cookie_expires_at > current_timestamp
and length(cookie) > 30
;
perform set_config('request.user.email', new.email, false);
return new;
end;
$$
language plpgsql
security definer
set search_path to auth, numerus, pg_temp;
create trigger update_user_profile
instead of update on user_profile
for each row execute procedure update_user_profile();
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 01:23:09 +00:00
commit;