-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Seeds Rework #174 #175
Seeds Rework #174 #175
Changes from 6 commits
70ccc1a
c6fe5e7
1b9f7eb
22b9d58
4c32cc5
e0a3d2b
55aff82
1c78cc6
de46c24
134f1a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,19 @@ | ||
export [email protected] | ||
export AUTH_API_KEY=2PzB7PPnpuLsbWmWtXpGyI+kfSQSQ1zUW2Atz/+8PdZuSEJzHgzGnJWV35nTKRwx/dwylauth.herokuapp.com | ||
export EMAIL_APP_URL=https://dwylmail.herokuapp.com | ||
export [email protected] | ||
export AUTH_URL=dwylauth.herokuapp.com | ||
export SECRET_KEY_BASE=2PzB7PPnpuLsbWmWtXpGyI+kfSQSQ1zUW2Atz/+8PdZuSEJzHgzGnJWV35nTKRwx | ||
export ENCRYPTION_KEYS='nMdayQpR0aoasLaq1g94FLba+A+wB44JLko47sVQXMg=,L+ZVX8iheoqgqb22mUpATmMDsvVGtafoAeb0KN5uWf0=' | ||
|
||
# We use these two Oauth2 Providers: | ||
# https://github.com/dwyl/elixir-auth-github | ||
export GITHUB_CLIENT_ID=CreateGitHubApp | ||
export GITHUB_CLIENT_SECRET=SuperSecret | ||
|
||
# https://github.com/dwyl/elixir-auth-google | ||
export GOOGLE_CLIENT_ID=YourAppsClientId.apps.googleusercontent.com | ||
export GOOGLE_CLIENT_SECRET=SuperSecret | ||
export SECRET_KEY_BASE=2PzB7PPnpuLsbWmWtXpGyI+kfSQSQ1zUW2Atz/+8PdZuSEJzHgzGnJWV35nTKRwx | ||
export ENCRYPTION_KEYS='nMdayQpR0aoasLaq1g94FLba+A+wB44JLko47sVQXMg=,L+ZVX8iheoqgqb22mUpATmMDsvVGtafoAeb0KN5uWf0=' | ||
|
||
# Optional for sending emails: | ||
export EMAIL_APP_URL=https://dwylmail.herokuapp.com | ||
|
||
# Export AUTH_API_KEY once you have run Auth.Init.main/0 | ||
export AUTH_API_KEY=2PzB7PPnpuLsbWmWtXpGyI+kfSQSQ1zUW2Atz/+8PdZuSEJzHgzGnJWV35nTKRwx/dwylauth.herokuapp.com |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<div align="center"> | ||
|
||
# Welcome! 👋 | ||
|
||
 | ||
|
||
</div> | ||
|
||
The purpose of the **`Auth` Application** | ||
is to have a complete separation of concerns between | ||
our | ||
[**App**](https://github.com/dwyl/app) | ||
and any Authentication/Authorization code | ||
in order to: <br /> | ||
|
||
**a)** ***Simplify*** the **code** in the _main_ | ||
[**App**](https://github.com/dwyl/app) | ||
because there is no "User Management" | ||
to think about. | ||
|
||
**b)** ***Maximize privacy/security*** of any/all **personal data** | ||
that people using our App entrust in us | ||
by storing it in a totally separate | ||
fully encrypted database. | ||
|
||
**c)** Minimize the number of environment variables | ||
in the main App so that _anyone_ can run it | ||
from scratch in less than 2 minutes. | ||
|
||
|
||
For better or worse, | ||
minimizing the number of environment variables | ||
in the _main_ | ||
[**App**](https://github.com/dwyl/app) | ||
means they have to go _somewhere_ ... | ||
that somewhere is right _here_! | ||
|
||
## Required Environment Variables for `Auth` App | ||
|
||
In order to initialize the **`Auth` Application** | ||
+ `ADMIN_EMAIL` - the email address of the person who will | ||
administer the **`Auth` App**. | ||
+ `AUTH_URL` - the base URL where the application will be hosted, | ||
e.g: `"auth.dwyl.com"` (exclude the protocol) | ||
+ `SECRET_KEY_BASE` - the secret Phoenix uses to sign and encrypt important information. | ||
see: | ||
https://hexdocs.pm/phoenix/deployment.html#handling-of-your-application-secrets | ||
+ `ENCRYPTION_KEYS` - a list of one or more encryption keys | ||
used to encrypt data in the database. | ||
see: `.env_sample` for example. | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
defmodule Auth.Init do | ||
@moduledoc """ | ||
`Init` as its' name suggests initializes the Auth Application | ||
by creating the necessary records in the various tables. | ||
|
||
This is the sequence of steps that are followed to init the App: | ||
|
||
1. Create the "Super Admin" person who owns the Auth App | ||
based on the `ADMIN_EMAIL` environment/config variable. | ||
|
||
> The person.id (1) for the Super Admin | ||
will own the remaining records so it needs to be created first. | ||
|
||
2. Create default records (Statuses & Roles) | ||
|
||
3. Create the App and `AUTH_API_KEY` for the Auth App. | ||
> Log the `AUTH_API_KEY` so that it can be exported. | ||
""" | ||
|
||
require Logger | ||
import Ecto.Changeset | ||
alias Auth.{Person, Role, Repo, Status} | ||
|
||
def main do | ||
Logger.info("Initialising the Auth Database ...") | ||
# check required environment variables: | ||
Envar.is_set_all?(~w/ADMIN_EMAIL AUTH_URL ENCRYPTION_KEYS SECRET_KEY_BASE/) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could create the list of environment variables as a module variable to make it easier to change later on if required. However I think it does the job at the moment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @SimonLab yeah, that would be a great future enhancement. 👍 |
||
|
||
admin = Auth.Init.create_admin() | ||
|
||
Auth.Init.insert_statuses() | ||
Auth.Init.create_default_roles() | ||
|
||
api_key = Auth.Init.create_apikey_for_admin(admin) | ||
|
||
case Mix.env() do | ||
:test -> | ||
# set the AUTH_API_KEY environment variable during test run: | ||
Envar.set("AUTH_API_KEY", api_key) | ||
# ignore the next lines because we can't test them: | ||
# coveralls-ignore-start | ||
_ -> | ||
# Log the AUTH_API_KEY so it can be exported: | ||
Logger.info("export AUTH_API_KEY=#{api_key}") | ||
# coveralls-ignore-stop | ||
end | ||
|
||
# Update status of Admin to "verified" | ||
Auth.Person.verify_person_by_id(1) | ||
nelsonic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# grant superadmin role to app owner: | ||
Auth.PeopleRoles.upsert(1, 1, 1, 1) | ||
|
||
:ok | ||
end | ||
|
||
# Get AUTH_URL or fallback to localhost: | ||
defp get_auth_url do | ||
# see .env_sample for example | ||
Envar.get("AUTH_URL") || "localhost:4000" | ||
end | ||
|
||
def create_admin do | ||
email = Envar.get("ADMIN_EMAIL") | ||
case Person.get_person_by_email(email) do | ||
# Ignore if the Super Admin already exists: | ||
# coveralls-ignore-start | ||
nil -> | ||
%Person{} | ||
|> Person.changeset(%{email: email}) | ||
|> Repo.insert!() | ||
# coveralls-ignore-stop | ||
|
||
person -> | ||
person | ||
end | ||
end | ||
|
||
def create_apikey_for_admin(person) do | ||
{:ok, app} = | ||
%{ | ||
"name" => "default system app", | ||
"desc" => "Created by lib/auth/init/init.ex during setup.", | ||
"url" => "localhost:4000", | ||
"person_id" => person.id, | ||
"status" => 3 | ||
} | ||
|> Auth.App.create_app() | ||
|
||
# If AUTH_API_KEY environment variable is already set, use it: | ||
update_attrs = %{ | ||
"client_id" => AuthPlug.Token.client_id(), | ||
"client_secret" => AuthPlug.Token.client_secret() | ||
} | ||
|
||
{:ok, key} = | ||
Auth.Apikey.get_apikey_by_app_id(app.id) | ||
|> cast(update_attrs, [:client_id, :client_secret]) | ||
|> Repo.update() | ||
|
||
key.client_id <> "/" <> key.client_secret <> "/" <> get_auth_url() | ||
end | ||
|
||
# scripts for creating default roles and permissions | ||
def get_json(filepath) do | ||
path = File.cwd!() <> filepath | ||
{:ok, data} = File.read(path) | ||
json = Jason.decode!(data) | ||
json | ||
end | ||
|
||
def create_default_roles do | ||
Enum.each(get_json("/lib/auth/init/default_roles.json"), fn role -> | ||
Role.upsert_role(role) | ||
end) | ||
end | ||
|
||
def insert_statuses do | ||
Enum.each(get_json("/lib/auth/init/statuses.json"), fn status -> | ||
Status.upsert_status(status) | ||
end) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to add the
AUTH_URL
environment variable to avoid the circular dependency onauth_plug
noted by @tadasajon in #170