]> Untitled Git - lemmy.git/commitdiff
Use enum for registration mode setting (#2604)
authorNutomic <me@nutomic.com>
Thu, 5 Jan 2023 01:42:30 +0000 (01:42 +0000)
committerGitHub <noreply@github.com>
Thu, 5 Jan 2023 01:42:30 +0000 (01:42 +0000)
* Use enum for registration mode setting

* fix tests

17 files changed:
api_tests/package.json
api_tests/src/shared.ts
api_tests/yarn.lock
crates/api/src/local_user/change_password_after_reset.rs
crates/api_common/src/site.rs
crates/api_common/src/utils.rs
crates/api_crud/src/lib.rs
crates/api_crud/src/site/create.rs
crates/api_crud/src/site/mod.rs
crates/api_crud/src/site/update.rs
crates/api_crud/src/user/create.rs
crates/db_schema/src/impls/local_site.rs
crates/db_schema/src/schema.rs
crates/db_schema/src/source/local_site.rs
crates/routes/src/nodeinfo.rs
migrations/2022-12-05-110642_registration_mode/down.sql [new file with mode: 0644]
migrations/2022-12-05-110642_registration_mode/up.sql [new file with mode: 0644]

index f32d87fe4b1c81e2ac88852238976056702ce2a7..4d74cbb2955ce4ea7f039dc60a0511fc2e64e8bb 100644 (file)
@@ -18,7 +18,7 @@
     "eslint": "^8.25.0",
     "eslint-plugin-prettier": "^4.0.0",
     "jest": "^27.0.6",
-    "lemmy-js-client": "0.17.0-rc.60",
+    "lemmy-js-client": "0.17.0-rc.61",
     "node-fetch": "^2.6.1",
     "prettier": "^2.7.1",
     "ts-jest": "^27.0.3",
index 26675c6dec949e9f617f85ce7018f6ea4ed9872a..0805481858d924d9ec5b29de34b4818b94e637e9 100644 (file)
@@ -64,6 +64,7 @@ import {
   GetCommentsResponse,
   FeaturePost,
   PostFeatureType,
+  RegistrationMode,
 } from "lemmy-js-client";
 
 export interface API {
@@ -145,7 +146,7 @@ export async function setupLogins() {
 
   // Registration applications are now enabled by default, need to disable them
   let editSiteForm: EditSite = {
-    require_application: false,
+    registration_mode: RegistrationMode.Open,
     federation_debug: true,
     rate_limit_message: 999,
     rate_limit_post: 999,
index c4c0c37d7cbf38de19001b697a8004ba15479e3f..3701e2f1ade4c82faea2fe546f2fac2dd243b941 100644 (file)
@@ -2363,10 +2363,10 @@ kleur@^3.0.3:
   resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
   integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
 
-lemmy-js-client@0.17.0-rc.60:
-  version "0.17.0-rc.60"
-  resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.0-rc.60.tgz#6cabac42d842eb1f152d230be018090050476614"
-  integrity sha512-Nl+DUBJde0KpKywNkX5wof9PDCmr6RuJlgukVfQRmW5rznYRKYnI1V+awf+9mUx1eNQ8jhnjVO+6XxOzMjloZA==
+lemmy-js-client@0.17.0-rc.61:
+  version "0.17.0-rc.61"
+  resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.17.0-rc.61.tgz#c01e129a3d4c3483ecf337f1e4acf0ad91f9684f"
+  integrity sha512-xauBCD5i4vlUEWqsTMIXLCXeIjAK7ivVIN3C/g+RMAM7mD3CTcRkDZUerwnvLipIfr7V/4iYLWZW0orBaiV1CQ==
   dependencies:
     node-fetch "2.6.6"
 
index c6de10d7ac5569afbc15335123e15ad157eeca48..392fcaa32d14dd9f71b9c4a66f267fa4631bae32 100644 (file)
@@ -6,6 +6,7 @@ use lemmy_api_common::{
   utils::password_length_check,
 };
 use lemmy_db_schema::source::{
+  local_site::RegistrationMode,
   local_user::LocalUser,
   password_reset_request::PasswordResetRequest,
 };
@@ -45,19 +46,20 @@ impl Perform for PasswordChangeAfterReset {
 
     // Return the jwt if login is allowed
     let site_view = SiteView::read_local(context.pool()).await?;
-    let jwt =
-      if site_view.local_site.require_application && !updated_local_user.accepted_application {
-        None
-      } else {
-        Some(
-          Claims::jwt(
-            updated_local_user.id.0,
-            &context.secret().jwt_secret,
-            &context.settings().hostname,
-          )?
-          .into(),
-        )
-      };
+    let jwt = if site_view.local_site.registration_mode == RegistrationMode::RequireApplication
+      && !updated_local_user.accepted_application
+    {
+      None
+    } else {
+      Some(
+        Claims::jwt(
+          updated_local_user.id.0,
+          &context.secret().jwt_secret,
+          &context.settings().hostname,
+        )?
+        .into(),
+      )
+    };
 
     Ok(LoginResponse {
       jwt,
index 9e66013656daff9c4da23832dd2088689ea12b48..30d819f30f6cc3ac537930725d27aa622cb7c3ef 100644 (file)
@@ -1,7 +1,7 @@
 use crate::sensitive::Sensitive;
 use lemmy_db_schema::{
   newtypes::{CommentId, CommunityId, LanguageId, PersonId, PostId},
-  source::{language::Language, tagline::Tagline},
+  source::{language::Language, local_site::RegistrationMode, tagline::Tagline},
   ListingType,
   ModlogActionType,
   SearchType,
@@ -116,11 +116,9 @@ pub struct CreateSite {
   pub icon: Option<String>,
   pub banner: Option<String>,
   pub enable_downvotes: Option<bool>,
-  pub open_registration: Option<bool>,
   pub enable_nsfw: Option<bool>,
   pub community_creation_admin_only: Option<bool>,
   pub require_email_verification: Option<bool>,
-  pub require_application: Option<bool>,
   pub application_question: Option<String>,
   pub private_instance: Option<bool>,
   pub default_theme: Option<String>,
@@ -151,6 +149,7 @@ pub struct CreateSite {
   pub allowed_instances: Option<Vec<String>>,
   pub blocked_instances: Option<Vec<String>>,
   pub taglines: Option<Vec<String>>,
+  pub registration_mode: Option<RegistrationMode>,
   pub auth: Sensitive<String>,
 }
 
@@ -162,11 +161,9 @@ pub struct EditSite {
   pub icon: Option<String>,
   pub banner: Option<String>,
   pub enable_downvotes: Option<bool>,
-  pub open_registration: Option<bool>,
   pub enable_nsfw: Option<bool>,
   pub community_creation_admin_only: Option<bool>,
   pub require_email_verification: Option<bool>,
-  pub require_application: Option<bool>,
   pub application_question: Option<String>,
   pub private_instance: Option<bool>,
   pub default_theme: Option<String>,
@@ -197,6 +194,7 @@ pub struct EditSite {
   pub allowed_instances: Option<Vec<String>>,
   pub blocked_instances: Option<Vec<String>>,
   pub taglines: Option<Vec<String>>,
+  pub registration_mode: Option<RegistrationMode>,
   pub auth: Sensitive<String>,
 }
 
index c85344992075cc5742d2612feea7d29ef2b61042..22d8e611049b52bc94da9b663fdf235c3f651f2d 100644 (file)
@@ -9,7 +9,7 @@ use lemmy_db_schema::{
     community::{Community, CommunityUpdateForm},
     email_verification::{EmailVerification, EmailVerificationForm},
     instance::Instance,
-    local_site::LocalSite,
+    local_site::{LocalSite, RegistrationMode},
     local_site_rate_limit::LocalSiteRateLimit,
     password_reset_request::PasswordResetRequest,
     person::{Person, PersonUpdateForm},
@@ -488,7 +488,7 @@ pub async fn check_registration_application(
   local_site: &LocalSite,
   pool: &DbPool,
 ) -> Result<(), LemmyError> {
-  if local_site.require_application
+  if local_site.registration_mode == RegistrationMode::RequireApplication
     && !local_user_view.local_user.accepted_application
     && !local_user_view.person.admin
   {
index 30c9ebd42d516f386050b4f27b1dfa33f14adea9..d37dfbee243133ec56a8650f5d6487efb62f8e12 100644 (file)
@@ -1,6 +1,5 @@
 use actix_web::web::Data;
 use lemmy_api_common::context::LemmyContext;
-use lemmy_db_schema::source::local_site::LocalSite;
 use lemmy_utils::{error::LemmyError, ConnectionId};
 
 mod comment;
@@ -20,18 +19,3 @@ pub trait PerformCrud {
     websocket_id: Option<ConnectionId>,
   ) -> Result<Self::Response, LemmyError>;
 }
-
-/// Make sure if applications are required, that there is an application questionnaire
-pub fn check_application_question(
-  application_question: &Option<Option<String>>,
-  local_site: &LocalSite,
-  require_application: &Option<bool>,
-) -> Result<(), LemmyError> {
-  if require_application.unwrap_or(false)
-    && (application_question == &Some(None)
-      || (application_question.is_none() && local_site.application_question.is_none()))
-  {
-    return Err(LemmyError::from_message("application_question_required"));
-  }
-  Ok(())
-}
index 370159e432d96494b2b047af50115e7ce4ffb734..8b0b3696f649f69b2807adfc2755edafe1d97fa8 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{check_application_question, PerformCrud};
+use crate::{site::check_application_question, PerformCrud};
 use activitypub_federation::core::signatures::generate_actor_keypair;
 use actix_web::web::Data;
 use lemmy_api_common::{
@@ -71,8 +71,9 @@ impl PerformCrud for CreateSite {
     let application_question = diesel_option_overwrite(&data.application_question);
     check_application_question(
       &application_question,
-      &local_site,
-      &data.require_application,
+      data
+        .registration_mode
+        .unwrap_or(local_site.registration_mode),
     )?;
 
     let actor_id: DbUrl = Url::parse(&context.settings().get_protocol_and_hostname())?.into();
@@ -99,11 +100,10 @@ impl PerformCrud for CreateSite {
       // Set the site setup to true
       .site_setup(Some(true))
       .enable_downvotes(data.enable_downvotes)
-      .open_registration(data.open_registration)
+      .registration_mode(data.registration_mode)
       .enable_nsfw(data.enable_nsfw)
       .community_creation_admin_only(data.community_creation_admin_only)
       .require_email_verification(data.require_email_verification)
-      .require_application(data.require_application)
       .application_question(application_question)
       .private_instance(data.private_instance)
       .default_theme(data.default_theme.clone())
index 845da04914fd7169562142ddce0348fbc8f52b8b..5155e3d0e7b429e3fc7c7e16dbee9bb48fc2e980 100644 (file)
@@ -1,3 +1,19 @@
+use lemmy_db_schema::source::local_site::RegistrationMode;
+use lemmy_utils::error::LemmyError;
+
 mod create;
 mod read;
 mod update;
+
+pub fn check_application_question(
+  application_question: &Option<Option<String>>,
+  registration_mode: RegistrationMode,
+) -> Result<(), LemmyError> {
+  if registration_mode == RegistrationMode::RequireApplication
+    && application_question.as_ref().unwrap_or(&None).is_none()
+  {
+    Err(LemmyError::from_message("application_question_required"))
+  } else {
+    Ok(())
+  }
+}
index 818d38753e8a9205022de71ca84c1cd7cd6b56ac..8cc852bb2fbbd41d9e29c497f4ab93f7ca691093 100644 (file)
@@ -1,4 +1,4 @@
-use crate::{check_application_question, PerformCrud};
+use crate::{site::check_application_question, PerformCrud};
 use actix_web::web::Data;
 use lemmy_api_common::{
   context::LemmyContext,
@@ -17,7 +17,7 @@ use lemmy_db_schema::{
     actor_language::SiteLanguage,
     federation_allowlist::FederationAllowList,
     federation_blocklist::FederationBlockList,
-    local_site::{LocalSite, LocalSiteUpdateForm},
+    local_site::{LocalSite, LocalSiteUpdateForm, RegistrationMode},
     local_site_rate_limit::{LocalSiteRateLimit, LocalSiteRateLimitUpdateForm},
     local_user::LocalUser,
     site::{Site, SiteUpdateForm},
@@ -61,8 +61,9 @@ impl PerformCrud for EditSite {
     let application_question = diesel_option_overwrite(&data.application_question);
     check_application_question(
       &application_question,
-      &local_site,
-      &data.require_application,
+      data
+        .registration_mode
+        .unwrap_or(local_site.registration_mode),
     )?;
 
     if let Some(default_post_listing_type) = &data.default_post_listing_type {
@@ -99,11 +100,10 @@ impl PerformCrud for EditSite {
 
     let local_site_form = LocalSiteUpdateForm::builder()
       .enable_downvotes(data.enable_downvotes)
-      .open_registration(data.open_registration)
+      .registration_mode(data.registration_mode)
       .enable_nsfw(data.enable_nsfw)
       .community_creation_admin_only(data.community_creation_admin_only)
       .require_email_verification(data.require_email_verification)
-      .require_application(data.require_application)
       .application_question(application_question)
       .private_instance(data.private_instance)
       .default_theme(data.default_theme.clone())
@@ -155,11 +155,13 @@ impl PerformCrud for EditSite {
     // will be able to log in. It really only wants this to be a requirement for NEW signups.
     // So if it was set from false, to true, you need to update all current users columns to be verified.
 
+    let old_require_application =
+      local_site.registration_mode == RegistrationMode::RequireApplication;
     let new_require_application = update_local_site
       .as_ref()
-      .map(|ols| ols.require_application)
+      .map(|ols| ols.registration_mode == RegistrationMode::RequireApplication)
       .unwrap_or(false);
-    if !local_site.require_application && new_require_application {
+    if !old_require_application && new_require_application {
       LocalUser::set_all_users_registration_applications_accepted(context.pool())
         .await
         .map_err(|e| LemmyError::from_error_message(e, "couldnt_set_all_registrations_accepted"))?;
index f11c45b31a9957be9a356adb33a310e18cfad7fc..a6979382a1d8aafdd3a89e72a1fb7a617ed140a8 100644 (file)
@@ -19,6 +19,7 @@ use lemmy_api_common::{
 use lemmy_db_schema::{
   aggregates::structs::PersonAggregates,
   source::{
+    local_site::RegistrationMode,
     local_user::{LocalUser, LocalUserInsertForm},
     person::{Person, PersonInsertForm},
     registration_application::{RegistrationApplication, RegistrationApplicationInsertForm},
@@ -47,8 +48,10 @@ impl PerformCrud for Register {
 
     let site_view = SiteView::read_local(context.pool()).await?;
     let local_site = site_view.local_site;
+    let require_registration_application =
+      local_site.registration_mode == RegistrationMode::RequireApplication;
 
-    if !local_site.open_registration {
+    if local_site.registration_mode == RegistrationMode::Closed {
       return Err(LemmyError::from_message("registration_closed"));
     }
 
@@ -59,7 +62,7 @@ impl PerformCrud for Register {
       return Err(LemmyError::from_message("email_required"));
     }
 
-    if local_site.site_setup && local_site.require_application && data.answer.is_none() {
+    if local_site.site_setup && require_registration_application && data.answer.is_none() {
       return Err(LemmyError::from_message(
         "registration_application_answer_required",
       ));
@@ -141,7 +144,7 @@ impl PerformCrud for Register {
       }
     };
 
-    if local_site.site_setup && local_site.require_application {
+    if local_site.site_setup && require_registration_application {
       // Create the registration application
       let form = RegistrationApplicationInsertForm {
         local_user_id: inserted_local_user.id,
@@ -166,7 +169,7 @@ impl PerformCrud for Register {
 
     // Log the user in directly if the site is not setup, or email verification and application aren't required
     if !local_site.site_setup
-      || (!local_site.require_application && !local_site.require_email_verification)
+      || (!require_registration_application && !local_site.require_email_verification)
     {
       login_response.jwt = Some(
         Claims::jwt(
@@ -195,7 +198,7 @@ impl PerformCrud for Register {
         login_response.verify_email_sent = true;
       }
 
-      if local_site.require_application {
+      if require_registration_application {
         login_response.registration_created = true;
       }
     }
index b9e920d15aa140d5095161f0e47e4b18da75e364..dd3d06d626fb37b06f4bceb6697c1cacd55f7f3c 100644 (file)
@@ -1,10 +1,25 @@
 use crate::{
   schema::local_site::dsl::local_site,
-  source::local_site::{LocalSite, LocalSiteInsertForm, LocalSiteUpdateForm},
+  source::local_site::{
+    LocalSite,
+    LocalSiteInsertForm,
+    LocalSiteUpdateForm,
+    RegistrationMode,
+    RegistrationModeType,
+  },
   utils::{get_conn, DbPool},
 };
-use diesel::{dsl::insert_into, result::Error};
+use diesel::{
+  deserialize,
+  deserialize::FromSql,
+  dsl::insert_into,
+  pg::{Pg, PgValue},
+  result::Error,
+  serialize,
+  serialize::{IsNull, Output, ToSql},
+};
 use diesel_async::RunQueryDsl;
+use std::io::Write;
 
 impl LocalSite {
   pub async fn create(pool: &DbPool, form: &LocalSiteInsertForm) -> Result<Self, Error> {
@@ -30,3 +45,25 @@ impl LocalSite {
     diesel::delete(local_site).execute(conn).await
   }
 }
+
+impl ToSql<RegistrationModeType, Pg> for RegistrationMode {
+  fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
+    match *self {
+      RegistrationMode::Closed => out.write_all(b"closed")?,
+      RegistrationMode::RequireApplication => out.write_all(b"require_application")?,
+      RegistrationMode::Open => out.write_all(b"open")?,
+    }
+    Ok(IsNull::No)
+  }
+}
+
+impl FromSql<RegistrationModeType, Pg> for RegistrationMode {
+  fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
+    match bytes.as_bytes() {
+      b"closed" => Ok(RegistrationMode::Closed),
+      b"require_application" => Ok(RegistrationMode::RequireApplication),
+      b"open" => Ok(RegistrationMode::Open),
+      _ => Err("Unrecognized enum variant".into()),
+    }
+  }
+}
index 97def1ffa1ef0ce72c3370d8e849c8710fd83a7f..4dea567c6ee4b9776a7b8cd831d9572b258c526c 100644 (file)
@@ -672,16 +672,17 @@ table! {
 }
 
 table! {
+  use crate::source::local_site::RegistrationModeType;
+  use diesel::sql_types::*;
+
   local_site(id) {
     id -> Int4,
     site_id -> Int4,
     site_setup -> Bool,
     enable_downvotes -> Bool,
-    open_registration -> Bool,
     enable_nsfw -> Bool,
     community_creation_admin_only -> Bool,
     require_email_verification -> Bool,
-    require_application -> Bool,
     application_question -> Nullable<Text>,
     private_instance -> Bool,
     default_theme -> Text,
@@ -696,6 +697,7 @@ table! {
     federation_worker_count -> Int4,
     captcha_enabled -> Bool,
     captcha_difficulty -> Text,
+    registration_mode -> RegistrationModeType,
     published -> Timestamp,
     updated -> Nullable<Timestamp>,
   }
index 4ae68ec1d39477597a78519715299253a24be9c1..40744a534a55b70602f7f5725de6c962daf44f45 100644 (file)
@@ -13,11 +13,9 @@ pub struct LocalSite {
   pub site_id: SiteId,
   pub site_setup: bool,
   pub enable_downvotes: bool,
-  pub open_registration: bool,
   pub enable_nsfw: bool,
   pub community_creation_admin_only: bool,
   pub require_email_verification: bool,
-  pub require_application: bool,
   pub application_question: Option<String>,
   pub private_instance: bool,
   pub default_theme: String,
@@ -32,6 +30,7 @@ pub struct LocalSite {
   pub federation_worker_count: i32,
   pub captcha_enabled: bool,
   pub captcha_difficulty: String,
+  pub registration_mode: RegistrationMode,
   pub published: chrono::NaiveDateTime,
   pub updated: Option<chrono::NaiveDateTime>,
 }
@@ -45,11 +44,9 @@ pub struct LocalSiteInsertForm {
   pub site_id: SiteId,
   pub site_setup: Option<bool>,
   pub enable_downvotes: Option<bool>,
-  pub open_registration: Option<bool>,
   pub enable_nsfw: Option<bool>,
   pub community_creation_admin_only: Option<bool>,
   pub require_email_verification: Option<bool>,
-  pub require_application: Option<bool>,
   pub application_question: Option<String>,
   pub private_instance: Option<bool>,
   pub default_theme: Option<String>,
@@ -64,6 +61,7 @@ pub struct LocalSiteInsertForm {
   pub federation_worker_count: Option<i32>,
   pub captcha_enabled: Option<bool>,
   pub captcha_difficulty: Option<String>,
+  pub registration_mode: Option<RegistrationMode>,
 }
 
 #[derive(Clone, TypedBuilder)]
@@ -73,11 +71,9 @@ pub struct LocalSiteInsertForm {
 pub struct LocalSiteUpdateForm {
   pub site_setup: Option<bool>,
   pub enable_downvotes: Option<bool>,
-  pub open_registration: Option<bool>,
   pub enable_nsfw: Option<bool>,
   pub community_creation_admin_only: Option<bool>,
   pub require_email_verification: Option<bool>,
-  pub require_application: Option<bool>,
   pub application_question: Option<Option<String>>,
   pub private_instance: Option<bool>,
   pub default_theme: Option<String>,
@@ -92,5 +88,21 @@ pub struct LocalSiteUpdateForm {
   pub federation_worker_count: Option<i32>,
   pub captcha_enabled: Option<bool>,
   pub captcha_difficulty: Option<String>,
+  pub registration_mode: Option<RegistrationMode>,
   pub updated: Option<Option<chrono::NaiveDateTime>>,
 }
+
+#[cfg(feature = "full")]
+#[derive(SqlType)]
+#[diesel(postgres_type(name = "registration_mode_enum"))]
+pub struct RegistrationModeType;
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(FromSqlRow, AsExpression))]
+#[cfg_attr(feature = "full", diesel(sql_type = RegistrationModeType))]
+#[serde(rename_all = "lowercase")]
+pub enum RegistrationMode {
+  Closed,
+  RequireApplication,
+  Open,
+}
index 13786e3b691ba0a96c362ef0e768240e3e7f573e..e1c70a8758510c329aacfed234f0cac21ab2bc3b 100644 (file)
@@ -1,6 +1,7 @@
 use actix_web::{error::ErrorBadRequest, web, Error, HttpResponse, Result};
 use anyhow::anyhow;
 use lemmy_api_common::context::LemmyContext;
+use lemmy_db_schema::source::local_site::RegistrationMode;
 use lemmy_db_views::structs::SiteView;
 use lemmy_utils::{error::LemmyError, version};
 use serde::{Deserialize, Serialize};
@@ -37,7 +38,7 @@ async fn node_info(context: web::Data<LemmyContext>) -> Result<HttpResponse, Err
   } else {
     vec![]
   };
-
+  let open_registrations = site_view.local_site.registration_mode == RegistrationMode::Open;
   let json = NodeInfo {
     version: "2.0".to_string(),
     software: NodeInfoSoftware {
@@ -54,7 +55,7 @@ async fn node_info(context: web::Data<LemmyContext>) -> Result<HttpResponse, Err
       local_posts: site_view.counts.posts,
       local_comments: site_view.counts.comments,
     },
-    open_registrations: site_view.local_site.open_registration,
+    open_registrations,
   };
 
   Ok(HttpResponse::Ok().json(json))
diff --git a/migrations/2022-12-05-110642_registration_mode/down.sql b/migrations/2022-12-05-110642_registration_mode/down.sql
new file mode 100644 (file)
index 0000000..25bb36c
--- /dev/null
@@ -0,0 +1,31 @@
+-- add back old registration columns
+alter table local_site add column open_registration boolean not null default true;
+alter table local_site add column require_application boolean not null default true;
+
+-- regenerate their values
+with subquery as (
+    select registration_mode,
+        case
+            when registration_mode='closed' then false
+            else true
+        end
+    from local_site
+)
+update local_site
+set open_registration = subquery.case
+from subquery;
+with subquery as (
+    select registration_mode,
+        case
+            when registration_mode='open' then false
+            else true
+        end
+    from local_site
+)
+update local_site
+set require_application = subquery.case
+from subquery;
+
+-- drop new column and type
+alter table local_site drop column registration_mode;
+drop type registration_mode_enum;
\ No newline at end of file
diff --git a/migrations/2022-12-05-110642_registration_mode/up.sql b/migrations/2022-12-05-110642_registration_mode/up.sql
new file mode 100644 (file)
index 0000000..34515e2
--- /dev/null
@@ -0,0 +1,25 @@
+-- create enum for registration modes
+create type registration_mode_enum as enum
+    ('closed', 'require_application', 'open');
+
+-- use this enum for registration mode setting
+alter table local_site add column
+    registration_mode registration_mode_enum not null default 'require_application';
+
+-- generate registration mode value from previous settings
+with subquery as (
+    select open_registration, require_application,
+        case
+            when open_registration=false then 'closed'::registration_mode_enum
+            when open_registration=true and require_application=true then 'require_application'
+            else 'open'
+        end
+    from local_site
+)
+update local_site
+set registration_mode = subquery.case
+from subquery;
+
+-- drop old registration settings
+alter table local_site drop column open_registration;
+alter table local_site drop column require_application;