Move admin flag from person to local_user (fixes #3060) (#3403)

* Move admin flag from person to local_user (fixes #3060)

The person table is for federated data, but admin flag can only
apply to local users. Thats why it really belongs in the local_user
table. This will also prevent the federation code from accidentally
overwriting the admin flag

* fmt

* try to fix api tests

* lint

* fix person view

* ci

* ci

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
This commit is contained in:
Nutomic 2023-08-24 11:40:08 +02:00 committed by GitHub
parent 51ccf318e8
commit 6047257bfc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 140 additions and 81 deletions

View file

@ -27,7 +27,7 @@ pub async fn list_comment_reports(
page,
limit,
}
.list(&mut context.pool(), &local_user_view.person)
.list(&mut context.pool(), &local_user_view)
.await?;
Ok(Json(ListCommentReportsResponse { comment_reports }))

View file

@ -28,7 +28,7 @@ pub async fn add_mod_to_community(
// Verify that only mods or admins can add mod
is_mod_or_admin(&mut context.pool(), local_user_view.person.id, community_id).await?;
let community = Community::read(&mut context.pool(), community_id).await?;
if local_user_view.person.admin && !community.local {
if local_user_view.local_user.admin && !community.local {
return Err(LemmyErrorType::NotAModerator)?;
}

View file

@ -7,8 +7,8 @@ use lemmy_api_common::{
};
use lemmy_db_schema::{
source::{
local_user::{LocalUser, LocalUserUpdateForm},
moderator::{ModAdd, ModAddForm},
person::{Person, PersonUpdateForm},
},
traits::Crud,
};
@ -27,13 +27,11 @@ impl Perform for AddAdmin {
// Make sure user is an admin
is_admin(&local_user_view)?;
let added = data.added;
let added_person_id = data.person_id;
let added_admin = Person::update(
let added_admin = LocalUser::update(
&mut context.pool(),
added_person_id,
&PersonUpdateForm {
admin: Some(added),
data.local_user_id,
&LocalUserUpdateForm {
admin: Some(data.added),
..Default::default()
},
)
@ -43,7 +41,7 @@ impl Perform for AddAdmin {
// Mod tables
let form = ModAddForm {
mod_person_id: local_user_view.person.id,
other_person_id: added_admin.id,
other_person_id: added_admin.person_id,
removed: Some(!data.added),
};

View file

@ -9,6 +9,7 @@ use lemmy_db_schema::{
source::person_block::{PersonBlock, PersonBlockForm},
traits::Blockable,
};
use lemmy_db_views::structs::LocalUserView;
use lemmy_db_views_actor::structs::PersonView;
use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
@ -34,9 +35,8 @@ impl Perform for BlockPerson {
target_id,
};
let target_person_view = PersonView::read(&mut context.pool(), target_id).await?;
if target_person_view.person.admin {
let target_user = LocalUserView::read_person(&mut context.pool(), target_id).await;
if target_user.map(|t| t.local_user.admin) == Ok(true) {
return Err(LemmyErrorType::CantBlockAdmin)?;
}
@ -50,8 +50,9 @@ impl Perform for BlockPerson {
.with_lemmy_type(LemmyErrorType::PersonBlockAlreadyExists)?;
}
let person_view = PersonView::read(&mut context.pool(), target_id).await?;
Ok(BlockPersonResponse {
person_view: target_person_view,
person_view,
blocked: data.block,
})
}

View file

@ -47,7 +47,7 @@ impl Perform for Login {
// Check if the user's email is verified if email verification is turned on
// However, skip checking verification if the user is an admin
if !local_user_view.person.admin
if !local_user_view.local_user.admin
&& site_view.local_site.require_email_verification
&& !local_user_view.local_user.email_verified
{

View file

@ -21,7 +21,7 @@ impl Perform for GetReportCount {
let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
let person_id = local_user_view.person.id;
let admin = local_user_view.person.admin;
let admin = local_user_view.local_user.admin;
let community_id = data.community_id;
let comment_reports =

View file

@ -33,7 +33,7 @@ impl Perform for ListPostReports {
page,
limit,
}
.list(&mut context.pool(), &local_user_view.person)
.list(&mut context.pool(), &local_user_view)
.await?;
Ok(ListPostReportsResponse { post_reports })

View file

@ -9,8 +9,8 @@ use lemmy_db_schema::{
source::{
actor_language::SiteLanguage,
language::Language,
local_user::{LocalUser, LocalUserUpdateForm},
moderator::{ModAdd, ModAddForm},
person::{Person, PersonUpdateForm},
tagline::Tagline,
},
traits::Crud,
@ -39,11 +39,10 @@ impl Perform for LeaveAdmin {
return Err(LemmyErrorType::CannotLeaveAdmin)?;
}
let person_id = local_user_view.person.id;
Person::update(
LocalUser::update(
&mut context.pool(),
person_id,
&PersonUpdateForm {
local_user_view.local_user.id,
&LocalUserUpdateForm {
admin: Some(false),
..Default::default()
},
@ -51,6 +50,7 @@ impl Perform for LeaveAdmin {
.await?;
// Mod tables
let person_id = local_user_view.person.id;
let form = ModAddForm {
mod_person_id: person_id,
other_person_id: person_id,

View file

@ -1,6 +1,6 @@
use crate::sensitive::Sensitive;
use lemmy_db_schema::{
newtypes::{CommentReplyId, CommunityId, LanguageId, PersonId, PersonMentionId},
newtypes::{CommentReplyId, CommunityId, LanguageId, LocalUserId, PersonId, PersonMentionId},
CommentSortType,
ListingType,
SortType,
@ -207,7 +207,7 @@ pub struct MarkAllAsRead {
#[cfg_attr(feature = "full", ts(export))]
/// Adds an admin to a site.
pub struct AddAdmin {
pub person_id: PersonId,
pub local_user_id: LocalUserId,
pub added: bool,
pub auth: Sensitive<String>,
}

View file

@ -78,8 +78,8 @@ pub async fn is_mod_or_admin_opt(
}
pub fn is_admin(local_user_view: &LocalUserView) -> Result<(), LemmyError> {
if !local_user_view.person.admin {
Err(LemmyErrorType::NotAnAdmin)?;
if !local_user_view.local_user.admin {
return Err(LemmyErrorType::NotAnAdmin)?;
}
Ok(())
}
@ -500,7 +500,7 @@ pub async fn check_registration_application(
if (local_site.registration_mode == RegistrationMode::RequireApplication
|| local_site.registration_mode == RegistrationMode::Closed)
&& !local_user_view.local_user.accepted_application
&& !local_user_view.person.admin
&& !local_user_view.local_user.admin
{
// Fetch the registration, see if its denied
let local_user_id = local_user_view.local_user.id;

View file

@ -115,8 +115,6 @@ pub async fn register(
.public_key(actor_keypair.public_key)
.inbox_url(Some(generate_inbox_url(&actor_id)?))
.shared_inbox_url(Some(generate_shared_inbox_url(&actor_id)?))
// If its the initial site setup, they are an admin
.admin(Some(!local_site.site_setup))
.instance_id(site_view.site.instance_id)
.build();
@ -137,6 +135,8 @@ pub async fn register(
.show_nsfw(Some(data.show_nsfw))
.accepted_application(accepted_application)
.default_listing_type(Some(local_site.default_post_listing_type))
// If its the initial site setup, they are an admin
.admin(Some(!local_site.site_setup))
.build();
let inserted_local_user = LocalUser::create(&mut context.pool(), &local_user_form).await?;

View file

@ -163,7 +163,6 @@ impl Object for ApubPerson {
actor_id: Some(person.id.into()),
bio,
local: Some(false),
admin: Some(false),
bot_account: Some(person.kind == UserTypes::Service),
private_key: None,
public_key: person.public_key.public_key_pem,

View file

@ -240,7 +240,6 @@ mod tests {
bio: None,
local: true,
bot_account: false,
admin: false,
private_key: None,
public_key: "nada".to_owned(),
last_refreshed_at: inserted_person.published,

View file

@ -396,9 +396,10 @@ diesel::table! {
totp_2fa_secret -> Nullable<Text>,
totp_2fa_url -> Nullable<Text>,
open_links_in_new_tab -> Bool,
infinite_scroll_enabled -> Bool,
blur_nsfw -> Bool,
auto_expand -> Bool,
infinite_scroll_enabled -> Bool,
admin -> Bool,
}
}
@ -566,7 +567,6 @@ diesel::table! {
#[max_length = 255]
shared_inbox_url -> Nullable<Varchar>,
matrix_user_id -> Nullable<Text>,
admin -> Bool,
bot_account -> Bool,
ban_expires -> Nullable<Timestamp>,
instance_id -> Int4,

View file

@ -57,6 +57,8 @@ pub struct LocalUser {
pub auto_expand: bool,
/// Whether infinite scroll is enabled.
pub infinite_scroll_enabled: bool,
/// Whether the person is an admin.
pub admin: bool,
}
#[derive(Clone, TypedBuilder)]
@ -88,6 +90,7 @@ pub struct LocalUserInsertForm {
pub blur_nsfw: Option<bool>,
pub auto_expand: Option<bool>,
pub infinite_scroll_enabled: Option<bool>,
pub admin: Option<bool>,
}
#[derive(Clone, Default)]
@ -115,4 +118,5 @@ pub struct LocalUserUpdateForm {
pub blur_nsfw: Option<bool>,
pub auto_expand: Option<bool>,
pub infinite_scroll_enabled: Option<bool>,
pub admin: Option<bool>,
}

View file

@ -49,8 +49,6 @@ pub struct Person {
pub shared_inbox_url: Option<DbUrl>,
/// A matrix id, usually given an @person:matrix.org
pub matrix_user_id: Option<String>,
/// Whether the person is an admin.
pub admin: bool,
/// Whether the person is a bot account.
pub bot_account: bool,
/// When their ban, if it exists, expires, if at all.
@ -84,7 +82,6 @@ pub struct PersonInsertForm {
pub inbox_url: Option<DbUrl>,
pub shared_inbox_url: Option<DbUrl>,
pub matrix_user_id: Option<String>,
pub admin: Option<bool>,
pub bot_account: Option<bool>,
pub ban_expires: Option<chrono::NaiveDateTime>,
}
@ -108,7 +105,6 @@ pub struct PersonUpdateForm {
pub inbox_url: Option<DbUrl>,
pub shared_inbox_url: Option<Option<DbUrl>>,
pub matrix_user_id: Option<Option<String>>,
pub admin: Option<bool>,
pub bot_account: Option<bool>,
pub ban_expires: Option<Option<chrono::NaiveDateTime>>,
}

View file

@ -1,4 +1,4 @@
use crate::structs::CommentReportView;
use crate::structs::{CommentReportView, LocalUserView};
use diesel::{
dsl::now,
pg::Pg,
@ -38,7 +38,7 @@ use lemmy_db_schema::{
fn queries<'a>() -> Queries<
impl ReadFn<'a, CommentReportView, (CommentReportId, PersonId)>,
impl ListFn<'a, CommentReportView, (CommentReportQuery, &'a Person)>,
impl ListFn<'a, CommentReportView, (CommentReportQuery, &'a LocalUserView)>,
> {
let all_joins = |query: comment_report::BoxedQuery<'a, Pg>, my_person_id: PersonId| {
query
@ -93,8 +93,9 @@ fn queries<'a>() -> Queries<
.await
};
let list = move |mut conn: DbConn<'a>, (options, my_person): (CommentReportQuery, &'a Person)| async move {
let mut query = all_joins(comment_report::table.into_boxed(), my_person.id)
let list = move |mut conn: DbConn<'a>,
(options, user): (CommentReportQuery, &'a LocalUserView)| async move {
let mut query = all_joins(comment_report::table.into_boxed(), user.person.id)
.left_join(
community_person_ban::table.on(
community::id
@ -125,13 +126,13 @@ fn queries<'a>() -> Queries<
.offset(offset);
// If its not an admin, get only the ones you mod
if !my_person.admin {
if !user.local_user.admin {
query
.inner_join(
community_moderator::table.on(
community_moderator::community_id
.eq(post::community_id)
.and(community_moderator::person_id.eq(my_person.id)),
.and(community_moderator::person_id.eq(user.person.id)),
),
)
.load::<<CommentReportView as JoinView>::JoinTuple>(&mut conn)
@ -213,9 +214,9 @@ impl CommentReportQuery {
pub async fn list(
self,
pool: &mut DbPool<'_>,
my_person: &Person,
user: &LocalUserView,
) -> Result<Vec<CommentReportView>, Error> {
queries().list(pool, (self, my_person)).await
queries().list(pool, (self, user)).await
}
}
@ -254,7 +255,10 @@ mod tests {
#![allow(clippy::unwrap_used)]
#![allow(clippy::indexing_slicing)]
use crate::comment_report_view::{CommentReportQuery, CommentReportView};
use crate::{
comment_report_view::{CommentReportQuery, CommentReportView},
structs::LocalUserView,
};
use lemmy_db_schema::{
aggregates::structs::CommentAggregates,
source::{
@ -262,6 +266,7 @@ mod tests {
comment_report::{CommentReport, CommentReportForm},
community::{Community, CommunityInsertForm, CommunityModerator, CommunityModeratorForm},
instance::Instance,
local_user::{LocalUser, LocalUserInsertForm},
person::{Person, PersonInsertForm},
post::{Post, PostInsertForm},
},
@ -288,6 +293,17 @@ mod tests {
let inserted_timmy = Person::create(pool, &new_person).await.unwrap();
let new_local_user = LocalUserInsertForm::builder()
.person_id(inserted_timmy.id)
.password_encrypted("123".to_string())
.build();
let timmy_local_user = LocalUser::create(pool, &new_local_user).await.unwrap();
let timmy_view = LocalUserView {
local_user: timmy_local_user,
person: inserted_timmy.clone(),
counts: Default::default(),
};
let new_person_2 = PersonInsertForm::builder()
.name("sara_crv".into())
.public_key("pubkey".to_string())
@ -412,7 +428,6 @@ mod tests {
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
@ -436,7 +451,6 @@ mod tests {
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
@ -480,7 +494,6 @@ mod tests {
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
@ -497,7 +510,7 @@ mod tests {
// Do a batch read of timmys reports
let reports = CommentReportQuery::default()
.list(pool, &inserted_timmy)
.list(pool, &timmy_view)
.await
.unwrap();
@ -546,7 +559,6 @@ mod tests {
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
@ -572,7 +584,7 @@ mod tests {
unresolved_only: (true),
..Default::default()
}
.list(pool, &inserted_timmy)
.list(pool, &timmy_view)
.await
.unwrap();
assert_eq!(reports_after_resolve[0], expected_sara_report_view);

View file

@ -205,7 +205,10 @@ fn queries<'a>() -> Queries<
query = query.filter(comment::deleted.eq(false));
}
let is_admin = options.local_user.map(|l| l.person.admin).unwrap_or(false);
let is_admin = options
.local_user
.map(|l| l.local_user.admin)
.unwrap_or(false);
// only show removed comments to admin when viewing user profile
if !(options.is_profile_view && is_admin) {
query = query.filter(comment::removed.eq(false));
@ -847,7 +850,6 @@ mod tests {
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,

View file

@ -62,7 +62,7 @@ fn queries<'a>(
ListMode::AdminsWithEmails => {
local_user::table
.filter(local_user::email.is_not_null())
.filter(person::admin.eq(true))
.filter(local_user::admin.eq(true))
.inner_join(person::table)
.inner_join(person_aggregates::table.on(person::id.eq(person_aggregates::person_id)))
.select(selection)

View file

@ -1,4 +1,4 @@
use crate::structs::PostReportView;
use crate::structs::{LocalUserView, PostReportView};
use diesel::{
pg::Pg,
result::Error,
@ -42,7 +42,7 @@ type PostReportViewTuple = (
fn queries<'a>() -> Queries<
impl ReadFn<'a, PostReportView, (PostReportId, PersonId)>,
impl ListFn<'a, PostReportView, (PostReportQuery, &'a Person)>,
impl ListFn<'a, PostReportView, (PostReportQuery, &'a LocalUserView)>,
> {
let all_joins = |query: post_report::BoxedQuery<'a, Pg>, my_person_id: PersonId| {
query
@ -91,8 +91,8 @@ fn queries<'a>() -> Queries<
.await
};
let list = move |mut conn: DbConn<'a>, (options, my_person): (PostReportQuery, &'a Person)| async move {
let mut query = all_joins(post_report::table.into_boxed(), my_person.id);
let list = move |mut conn: DbConn<'a>, (options, user): (PostReportQuery, &'a LocalUserView)| async move {
let mut query = all_joins(post_report::table.into_boxed(), user.person.id);
if let Some(community_id) = options.community_id {
query = query.filter(post::community_id.eq(community_id));
@ -110,13 +110,13 @@ fn queries<'a>() -> Queries<
.offset(offset);
// If its not an admin, get only the ones you mod
if !my_person.admin {
if !user.local_user.admin {
query
.inner_join(
community_moderator::table.on(
community_moderator::community_id
.eq(post::community_id)
.and(community_moderator::person_id.eq(my_person.id)),
.and(community_moderator::person_id.eq(user.person.id)),
),
)
.load::<PostReportViewTuple>(&mut conn)
@ -193,9 +193,9 @@ impl PostReportQuery {
pub async fn list(
self,
pool: &mut DbPool<'_>,
my_person: &Person,
user: &LocalUserView,
) -> Result<Vec<PostReportView>, Error> {
queries().list(pool, (self, my_person)).await
queries().list(pool, (self, user)).await
}
}
@ -221,12 +221,16 @@ mod tests {
#![allow(clippy::unwrap_used)]
#![allow(clippy::indexing_slicing)]
use crate::post_report_view::{PostReportQuery, PostReportView};
use crate::{
post_report_view::{PostReportQuery, PostReportView},
structs::LocalUserView,
};
use lemmy_db_schema::{
aggregates::structs::PostAggregates,
source::{
community::{Community, CommunityInsertForm, CommunityModerator, CommunityModeratorForm},
instance::Instance,
local_user::{LocalUser, LocalUserInsertForm},
person::{Person, PersonInsertForm},
post::{Post, PostInsertForm},
post_report::{PostReport, PostReportForm},
@ -254,6 +258,17 @@ mod tests {
let inserted_timmy = Person::create(pool, &new_person).await.unwrap();
let new_local_user = LocalUserInsertForm::builder()
.person_id(inserted_timmy.id)
.password_encrypted("123".to_string())
.build();
let timmy_local_user = LocalUser::create(pool, &new_local_user).await.unwrap();
let timmy_view = LocalUserView {
local_user: timmy_local_user,
person: inserted_timmy.clone(),
counts: Default::default(),
};
let new_person_2 = PersonInsertForm::builder()
.name("sara_prv".into())
.public_key("pubkey".to_string())
@ -369,7 +384,6 @@ mod tests {
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
@ -393,7 +407,6 @@ mod tests {
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
@ -445,7 +458,6 @@ mod tests {
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
@ -462,7 +474,7 @@ mod tests {
// Do a batch read of timmys reports
let reports = PostReportQuery::default()
.list(pool, &inserted_timmy)
.list(pool, &timmy_view)
.await
.unwrap();
@ -509,7 +521,6 @@ mod tests {
local: true,
banned: false,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
@ -535,7 +546,7 @@ mod tests {
unresolved_only: (true),
..Default::default()
}
.list(pool, &inserted_timmy)
.list(pool, &timmy_view)
.await
.unwrap();
assert_eq!(reports_after_resolve[0], expected_sara_report_view);

View file

@ -217,7 +217,10 @@ fn queries<'a>() -> Queries<
.filter(post::deleted.eq(false));
}
let is_admin = options.local_user.map(|l| l.person.admin).unwrap_or(false);
let is_admin = options
.local_user
.map(|l| l.local_user.admin)
.unwrap_or(false);
// only show removed posts to admin when viewing user profile
if !(options.is_profile_view && is_admin) {
query = query
@ -945,7 +948,7 @@ mod tests {
assert_eq!(1, post_listings_no_admin.len());
// Removed post is shown to admins on profile page
data.local_user_view.person.admin = true;
data.local_user_view.local_user.admin = true;
let post_listings_is_admin = PostQuery {
sort: Some(SortType::New),
local_user: Some(&data.local_user_view),
@ -1071,7 +1074,6 @@ mod tests {
avatar: None,
actor_id: inserted_person.actor_id.clone(),
local: true,
admin: false,
bot_account: false,
banned: false,
deleted: false,

View file

@ -178,7 +178,6 @@ mod tests {
let timmy_form = PersonInsertForm::builder()
.name("timmy_rav".into())
.admin(Some(true))
.public_key("pubkey".to_string())
.instance_id(instance.id)
.build();

View file

@ -184,7 +184,6 @@ mod tests {
let timmy_person_form = PersonInsertForm::builder()
.name("timmy_rav".into())
.admin(Some(true))
.public_key("pubkey".to_string())
.instance_id(inserted_instance.id)
.build();
@ -194,6 +193,7 @@ mod tests {
let timmy_local_user_form = LocalUserInsertForm::builder()
.person_id(inserted_timmy_person.id)
.password_encrypted("nada".to_string())
.admin(Some(true))
.build();
let _inserted_timmy_local_user = LocalUser::create(pool, &timmy_local_user_form)
@ -289,6 +289,7 @@ mod tests {
password_encrypted: inserted_sara_local_user.password_encrypted,
open_links_in_new_tab: inserted_sara_local_user.open_links_in_new_tab,
infinite_scroll_enabled: inserted_sara_local_user.infinite_scroll_enabled,
admin: false,
},
creator: Person {
id: inserted_sara_person.id,
@ -301,7 +302,6 @@ mod tests {
banned: false,
ban_expires: None,
deleted: false,
admin: false,
bot_account: false,
bio: None,
banner: None,
@ -380,7 +380,6 @@ mod tests {
banned: false,
ban_expires: None,
deleted: false,
admin: true,
bot_account: false,
bio: None,
banner: None,

View file

@ -13,7 +13,7 @@ use lemmy_db_schema::{
aggregates::structs::PersonAggregates,
newtypes::PersonId,
schema,
schema::{person, person_aggregates},
schema::{local_user, person, person_aggregates},
source::person::Person,
traits::JoinView,
utils::{fuzzy_search, get_conn, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn},
@ -33,6 +33,7 @@ fn queries<'a>(
let all_joins = |query: person::BoxedQuery<'a, Pg>| {
query
.inner_join(person_aggregates::table)
.left_join(local_user::table)
.select((person::all_columns, person_aggregates::all_columns))
};
@ -47,7 +48,7 @@ fn queries<'a>(
match mode {
ListMode::Admins => {
query = query
.filter(person::admin.eq(true))
.filter(local_user::admin.eq(true))
.filter(person::deleted.eq(false))
.order_by(person::published);
}
@ -95,9 +96,13 @@ impl PersonView {
}
pub async fn is_admin(pool: &mut DbPool<'_>, person_id: PersonId) -> Result<bool, Error> {
use schema::person::dsl::{admin, id, person};
use schema::{
local_user::dsl::admin,
person::dsl::{id, person},
};
let conn = &mut get_conn(pool).await?;
let is_admin = person
.inner_join(local_user::table)
.filter(id.eq(person_id))
.select(admin)
.first::<bool>(conn)

View file

@ -0,0 +1,16 @@
ALTER TABLE person
ADD COLUMN admin boolean DEFAULT FALSE NOT NULL;
UPDATE
person
SET
admin = TRUE
FROM
local_user
WHERE
local_user.person_id = person.id
AND local_user.admin;
ALTER TABLE local_user
DROP COLUMN admin;

View file

@ -0,0 +1,16 @@
ALTER TABLE local_user
ADD COLUMN admin boolean DEFAULT FALSE NOT NULL;
UPDATE
local_user
SET
admin = TRUE
FROM
person
WHERE
local_user.person_id = person.id
AND person.admin;
ALTER TABLE person
DROP COLUMN admin;

View file

@ -457,7 +457,6 @@ async fn initialize_local_site_2022_10_10(
// Register the user if there's a site setup
let person_form = PersonInsertForm::builder()
.name(setup.admin_username.clone())
.admin(Some(true))
.instance_id(instance.id)
.actor_id(Some(person_actor_id.clone()))
.private_key(Some(person_keypair.private_key))
@ -471,6 +470,7 @@ async fn initialize_local_site_2022_10_10(
.person_id(person_inserted.id)
.password_encrypted(setup.admin_password.clone())
.email(setup.admin_email.clone())
.admin(Some(true))
.build();
LocalUser::create(pool, &local_user_form).await?;
};