Improve overall configuration and support
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
121
lib/mix/tasks/generate_config.ex
Normal file
121
lib/mix/tasks/generate_config.ex
Normal file
@@ -0,0 +1,121 @@
|
||||
defmodule Mix.Tasks.GenerateConfig do
|
||||
use Mix.Task
|
||||
|
||||
@moduledoc """
|
||||
Generate a new config
|
||||
|
||||
## Usage
|
||||
``mix generate_config``
|
||||
|
||||
This mix task is interactive, and will overwrite the environment file present at ``.env.production``.
|
||||
|
||||
Inspired from Pleroma own generate_config task
|
||||
"""
|
||||
def run(_) do
|
||||
IO.puts("Answer a few questions to generate a new config\n")
|
||||
|
||||
override =
|
||||
if File.exists?(".env.production") do
|
||||
confirm("You already have an .env.production file, do you want to override it?")
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
if override == true do
|
||||
IO.puts("\n--- THIS WILL OVERWRITE YOUR .env.production file! ---\n")
|
||||
end
|
||||
|
||||
if override != false do
|
||||
domain = string_required("What is your domain name? (e.g. framameet.org): ")
|
||||
name = string_required("What is the name of your instance? (e.g. Framameet): ")
|
||||
email = email("What's your admin email address: ")
|
||||
|
||||
if confirm("Is everything okay?") do
|
||||
do_generate(domain, name, email)
|
||||
else
|
||||
IO.puts("\nYou cancelled installation\n")
|
||||
end
|
||||
else
|
||||
IO.puts("\nYou cancelled installation\n")
|
||||
end
|
||||
end
|
||||
|
||||
defp do_generate(domain, name, email) do
|
||||
secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
|
||||
|
||||
# Try to avoid issues with some special caracters using url_encode64()
|
||||
dbpass = :crypto.strong_rand_bytes(64) |> Base.url_encode64() |> binary_part(0, 64)
|
||||
|
||||
resultSql = EEx.eval_file("support/postgresql/setup_db.psql", database_password: dbpass)
|
||||
|
||||
result =
|
||||
EEx.eval_file(
|
||||
".env.production.sample",
|
||||
instance_domain: domain,
|
||||
instance_name: name,
|
||||
instance_email: email,
|
||||
instance_secret: secret,
|
||||
database_password: dbpass
|
||||
)
|
||||
|
||||
IO.puts("\nWriting config to .env.production.\n\nCheck it and configure your database.")
|
||||
|
||||
File.write(".env.production", result)
|
||||
|
||||
IO.puts("""
|
||||
\nWriting setup_db.psql, please run it as postgres superuser, i.e.: sudo su postgres -c 'psql -f setup_db.psql'\n
|
||||
You may delete the setup_db.psql file once it has been executed.
|
||||
""")
|
||||
|
||||
File.write("setup_db.psql", resultSql)
|
||||
end
|
||||
|
||||
# Taken from ex_prompt
|
||||
@spec confirm(String.t()) :: boolean()
|
||||
defp confirm(prompt) do
|
||||
answer =
|
||||
String.trim(prompt)
|
||||
|> Kernel.<>(" [Yn] ")
|
||||
|> string()
|
||||
|> String.downcase()
|
||||
|
||||
cond do
|
||||
answer in ~w(yes y) -> true
|
||||
answer in ~w(no n) -> false
|
||||
true -> confirm(prompt)
|
||||
end
|
||||
end
|
||||
|
||||
# Taken from ex_prompt
|
||||
@spec string(String.t()) :: String.t()
|
||||
defp string(prompt) do
|
||||
case IO.gets(prompt) do
|
||||
:eof -> ""
|
||||
{:error, _reason} -> ""
|
||||
str -> String.trim_trailing(str)
|
||||
end
|
||||
end
|
||||
|
||||
# Taken from ex_prompt
|
||||
@spec string_required(String.t()) :: String.t()
|
||||
defp string_required(prompt) do
|
||||
case string(prompt) do
|
||||
"" -> string_required(prompt)
|
||||
str -> str
|
||||
end
|
||||
end
|
||||
|
||||
@spec email(String.t(), boolean()) :: String.t()
|
||||
defp email(prompt, required \\ true) do
|
||||
email_value =
|
||||
case required do
|
||||
true -> string_required(prompt)
|
||||
_ -> string(prompt)
|
||||
end
|
||||
|
||||
case Mobilizon.Service.EmailChecker.valid?(email_value) do
|
||||
false -> email(prompt, required)
|
||||
_ -> email_value
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,6 +5,7 @@ defmodule Mobilizon.Actors.User do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
alias Mobilizon.Actors.{Actor, User}
|
||||
alias Mobilizon.Service.EmailChecker
|
||||
|
||||
schema "users" do
|
||||
field(:email, :string)
|
||||
|
||||
@@ -27,12 +27,19 @@ defmodule MobilizonWeb.Schema do
|
||||
field(:summary, :string, description: "The actor's summary")
|
||||
field(:preferred_username, :string, description: "The actor's preferred username")
|
||||
field(:keys, :string, description: "The actors RSA Keys")
|
||||
field(:manually_approves_followers, :boolean, description: "Whether the actors manually approves followers")
|
||||
|
||||
field(:manually_approves_followers, :boolean,
|
||||
description: "Whether the actors manually approves followers"
|
||||
)
|
||||
|
||||
field(:suspended, :boolean, description: "If the actor is suspended")
|
||||
field(:avatar_url, :string, description: "The actor's avatar url")
|
||||
field(:banner_url, :string, description: "The actor's banner url")
|
||||
# field(:followers, list_of(:follower))
|
||||
field(:organized_events, list_of(:event), resolve: dataloader(Events), description: "A list of the events this actor has organized")
|
||||
field(:organized_events, list_of(:event),
|
||||
resolve: dataloader(Events),
|
||||
description: "A list of the events this actor has organized"
|
||||
)
|
||||
|
||||
# field(:memberships, list_of(:member))
|
||||
field(:user, :user, description: "The user this actor is associated to")
|
||||
@@ -52,13 +59,29 @@ defmodule MobilizonWeb.Schema do
|
||||
field(:id, non_null(:id), description: "The user's ID")
|
||||
field(:email, non_null(:string), description: "The user's email")
|
||||
# , resolve: dataloader(:actors))
|
||||
field(:actors, non_null(list_of(:actor)), description: "The user's list of actors (identities)")
|
||||
field(:actors, non_null(list_of(:actor)),
|
||||
description: "The user's list of actors (identities)"
|
||||
)
|
||||
|
||||
field(:default_actor_id, non_null(:integer), description: "The user's default actor")
|
||||
field(:confirmed_at, :datetime, description: "The datetime when the user was confirmed/activated")
|
||||
field(:confirmation_sent_at, :datetime, description: "The datetime the last activation/confirmation token was sent")
|
||||
|
||||
field(:confirmed_at, :datetime,
|
||||
description: "The datetime when the user was confirmed/activated"
|
||||
)
|
||||
|
||||
field(:confirmation_sent_at, :datetime,
|
||||
description: "The datetime the last activation/confirmation token was sent"
|
||||
)
|
||||
|
||||
field(:confirmation_token, :string, description: "The account activation/confirmation token")
|
||||
field(:reset_password_sent_at, :datetime, description: "The datetime last reset password email was sent")
|
||||
field(:reset_password_token, :string, description: "The token sent when requesting password token")
|
||||
|
||||
field(:reset_password_sent_at, :datetime,
|
||||
description: "The datetime last reset password email was sent"
|
||||
)
|
||||
|
||||
field(:reset_password_token, :string,
|
||||
description: "The token sent when requesting password token"
|
||||
)
|
||||
end
|
||||
|
||||
@desc "A JWT and the associated user ID"
|
||||
|
||||
15
lib/service/email_checker.ex
Normal file
15
lib/service/email_checker.ex
Normal file
@@ -0,0 +1,15 @@
|
||||
defmodule Mobilizon.Service.EmailChecker do
|
||||
@moduledoc """
|
||||
Provides a function to test emails against a "not so bad" regex
|
||||
"""
|
||||
|
||||
@email_regex ~r/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
|
||||
@doc """
|
||||
Returns whether the email is valid
|
||||
"""
|
||||
@spec valid?(String.t()) :: boolean()
|
||||
def valid?(email) do
|
||||
email =~ @email_regex
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user