Skip to content
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

PR: RBAC Role Based Access Control #27 #31 #82 #85

Merged
merged 167 commits into from
Sep 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
167 commits
Select commit Hold shift + click to select a range
0d4dfd5
improve clarity in create_apikey in seeds.exs
nelsonic Jul 17, 2020
a351bfc
remember to export the AUTH_API_KEY in seeds.exs so its present durin…
nelsonic Jul 17, 2020
c2f3d19
if an apikey belongs to SuperAdmin dont check the URL as its the Syst…
nelsonic Jul 17, 2020
090aa66
add notes on RBAC #81
nelsonic Jul 22, 2020
46a2813
add ping to mix.exs see: https://github.com/dwyl/ping
nelsonic Jul 22, 2020
46c45c7
add RBAC schema instructions [WiP] #27 / #31
nelsonic Jul 22, 2020
2f26ed1
add /ping to wake Heroku app see: https://github.com/dwyl/ping
nelsonic Jul 22, 2020
0114fc8
create roles schema and resources #27 / #31
nelsonic Jul 22, 2020
18be2a0
create permissions schema and resources #27 / #31
nelsonic Jul 22, 2020
e961a17
add AuthTest.admin_login/1 helper function to login as admin https://…
nelsonic Jul 23, 2020
a202d73
import AuthTest helper function in conn_case.ex so helper functions a…
nelsonic Jul 23, 2020
39ff5c1
add admin_login/1 to all Role routes for RBAC #27 / #31
nelsonic Jul 23, 2020
f468b4d
add admin_login/1 to all permissions tests #27 / #31
nelsonic Jul 23, 2020
2a3c361
add table listing 7 default roles to rbac doc #82
nelsonic Jul 23, 2020
2b7a66d
mix ecto.gen.migration create_role_permissions #27 /#31
nelsonic Jul 23, 2020
b6e4a5f
mix ecto.gen.migration create_people_roles for rbac #27 / #31
nelsonic Jul 23, 2020
0498e98
add test for get_client_secret/2
nelsonic Jul 24, 2020
9cf0ef5
reduce noise in tests by checking for Mix.env() == :test
nelsonic Jul 18, 2020
eab0291
add "granter" (person who grants a permission/role) to association ta…
nelsonic Jul 24, 2020
f03c050
write AUTH_API_KEY to .env file during setup (seeds.exs) fixes #87
nelsonic Jul 24, 2020
b60522a
add debug IO.inspect in write_env/2 #87 https://travis-ci.org/github/…
nelsonic Jul 24, 2020
1762d43
obviously the .env file doesnt exist on Travis-CI #87 https://travis-…
nelsonic Jul 24, 2020
5ec8568
debugging why tests are failing #87 https://travis-ci.org/github/dwyl…
nelsonic Jul 24, 2020
8f192b1
move Role related helper functions out of Ctx #86
nelsonic Jul 25, 2020
7377027
rename auth/ctx_test.exs to auth/roles_test.exs for #87
nelsonic Jul 25, 2020
ef4261d
remove ctx from project #87
nelsonic Jul 25, 2020
723ae83
create script and default_roles.json (version controllable data file)…
nelsonic Jul 25, 2020
7a8d967
add all default roles to default_roles.json #86
nelsonic Jul 25, 2020
3c1c720
update Role.list_roles() to reflect that we have more roles (default …
nelsonic Jul 25, 2020
510489c
add basic permissions to default_roles.json #86
nelsonic Jul 26, 2020
c1f9d3b
refine basic permissions in default_roles.json #86
nelsonic Jul 27, 2020
b27a21a
fix failing tests by adding ecto associations to Auth.Person function…
nelsonic Aug 14, 2020
259e239
create lib/auth/people_roles.ex Auth.PeopleRoles schema + functions f…
nelsonic Aug 20, 2020
506d365
add grant_role/3 function + test to grant roles to people #90 |> #27 …
nelsonic Aug 20, 2020
1d6a259
create test/auth/people_roles_test.exs to test both happy path and 40…
nelsonic Aug 20, 2020
812e192
run "mix format" to keep SourceLevel happy https://github.com/dwyl/au…
nelsonic Aug 20, 2020
5a0d8bf
add @moduledoc tag comment to all newly created files and some old on…
nelsonic Aug 20, 2020
3ce9bab
create and use Auth.PeopleRoles.list_people_roles/0 function to list …
nelsonic Aug 20, 2020
198b3fb
simplify Auth.PeopleRoles.insert/3 to not use conn as discussed with …
nelsonic Aug 20, 2020
d3fa7de
update @doc comment for PeopleRoles.insert/3 https://github.com/dwyl/…
nelsonic Aug 21, 2020
9dfc9de
use RBAC v0.2.0 to transform roles from List of Maps/Structs to Strin…
nelsonic Aug 21, 2020
aed44b8
mix format
nelsonic Aug 21, 2020
89acf44
apply credo fixes
nelsonic Aug 21, 2020
f0a7782
add :revoked field to people_roles migration and schema for #92
nelsonic Aug 21, 2020
3218d5c
use RBAC v.0.3.0 containing check for :revoked roles #92
nelsonic Aug 22, 2020
361648d
create Auth.PeopleRoles.revoke/3 + tests for #92
nelsonic Aug 22, 2020
d27444b
mix format
nelsonic Aug 22, 2020
b652d34
tidy up revoke/3 function for #92
nelsonic Aug 22, 2020
0f45966
inline function calls to keep @sourcelevel-bot happy https://github.c…
nelsonic Aug 22, 2020
7310d60
create list_people/0 function for #93
nelsonic Aug 22, 2020
ffca1fa
create /people controller, view and templtes for #93
nelsonic Aug 22, 2020
f4aeb67
add status_string to /people table for #93
nelsonic Aug 23, 2020
0b1848d
display roles in /people table #93
nelsonic Aug 23, 2020
7f2286a
remove unused code
nelsonic Aug 23, 2020
d6ccfa5
add tests for /people table #93
nelsonic Aug 23, 2020
b9c2cd8
[WiP] create profile page and revoke functions for people #94
nelsonic Aug 24, 2020
7ac38b3
[WiP] create revoke.html.eex and /roles/revoke/:id + handler for #94
nelsonic Aug 24, 2020
73a6107
add tests for RBAC Admin UI https://github.com/dwyl/auth/issues/94#is…
nelsonic Aug 25, 2020
7335bbd
create Grant Roles Route, Handler and UI for #94 see: https://github.…
nelsonic Aug 25, 2020
a22dd7b
add test for POST /roles/grant for https://github.com/dwyl/auth/issue…
nelsonic Aug 26, 2020
4568c7d
mix format
nelsonic Aug 26, 2020
3df1c93
remove pipeline from simple PeopleView.status_string/2 function https…
nelsonic Aug 26, 2020
2eacfeb
tidy up PeopleController.show/2 handler https://github.com/dwyl/auth/…
nelsonic Aug 26, 2020
46e4a8a
use latest version of elixir-auth-github see: https://github.com/dwyl…
nelsonic Aug 27, 2020
7abbd6f
remove stray IO.inspect https://github.com/dwyl/auth/pull/85#pullrequ…
nelsonic Aug 27, 2020
5389ea4
mix phx.gen.html Ctx App apps #95
nelsonic Aug 30, 2020
f90ef84
remvoe Ctx and fix CreateApps migration #95
nelsonic Aug 30, 2020
01b2b87
add admin_login(conn) to all AppController tests #95
nelsonic Aug 31, 2020
52c0828
rename Ctx to App in app_test.exs #95
nelsonic Aug 31, 2020
3100d28
update html forms / tables to be more visually appealing #95
nelsonic Aug 31, 2020
fdea23d
update copy in test assertion "Listing Apps" > "Apps" #95
nelsonic Sep 1, 2020
45b7dbe
fix failing test (assertion) "Show App" > "App" #95
nelsonic Sep 1, 2020
ecc6043
create apps before apikeys for #97
nelsonic Sep 2, 2020
a4d5e58
fix 1/4 failing auth tests #97
nelsonic Sep 2, 2020
b7188d0
update seeds and tests to create App before API Key #97
nelsonic Sep 2, 2020
87c52d6
fix failing tests for Apps #97
nelsonic Sep 3, 2020
5d52ed3
[WiP:TestsFailing] automatically create API key when new app is inser…
nelsonic Sep 8, 2020
22f5d50
create statuses.json for #101
nelsonic Sep 8, 2020
2aa97f7
create insert_statuses/0 for #101
nelsonic Sep 8, 2020
205c828
rework create_app/1 to use case statement for errors #97
nelsonic Sep 8, 2020
2da212d
mix format
nelsonic Sep 8, 2020
0ae675b
fix failing tests #102
nelsonic Sep 8, 2020
e07952e
mix format
nelsonic Sep 8, 2020
36fd51e
remove IO.inspect() https://github.com/dwyl/auth/pull/85#pullrequestr…
nelsonic Sep 8, 2020
978504f
add Top Nav for /apps /people & /roles https://github.com/dwyl/auth/i…
nelsonic Sep 8, 2020
78cb2d8
make "New App" button more obvious: https://github.com/dwyl/auth/issu…
nelsonic Sep 8, 2020
b3e5576
remove single pipeline operators from tests to keep sourcelevel happy…
nelsonic Sep 9, 2020
8e6c096
remove single pipeline operator from permissions tests to keep @sourc…
nelsonic Sep 9, 2020
dd97914
remove single pipeline from apikey.ex #104
nelsonic Sep 9, 2020
35515a6
tidy up test/auth_web/controllers/apikey_controller_test.exs for #104
nelsonic Sep 9, 2020
c5d7594
tidy up lib/auth/app.ex for #104
nelsonic Sep 9, 2020
341c1e1
tidy up auth/app.ex for #104
nelsonic Sep 9, 2020
05f88d7
set status for app and apikey to 3 ("active") in app_controller.ex > …
nelsonic Sep 9, 2020
88d31c2
derp! remove noisy IO.inspect #104
nelsonic Sep 9, 2020
df79ca2
update copy on "back" button to "< All Apps" for clarity
nelsonic Sep 9, 2020
b1f7c4a
Repo.preload(:statuses) > Repo.preload([:statuses, :roles])
nelsonic Sep 9, 2020
c17bcbb
comment out UI tests in test/auth_web/controllers/apikey_controller_t…
nelsonic Sep 10, 2020
bc136ce
delete lib/auth_web/templates/apikey to avoid warnings #107
nelsonic Sep 10, 2020
13cca0e
remove lib/auth_web/views/apikey_view.ex as no longer needed #107
nelsonic Sep 10, 2020
259149d
all tests passing again after removing API Key UI #107
nelsonic Sep 10, 2020
b0ff09f
🔪 DELETE apikey_controller.ex and apikey_controller_test.exs #107
nelsonic Sep 10, 2020
f59cdf9
all tests passing again after removing API Key UI #107
nelsonic Sep 10, 2020
e6b478a
preload :apikeys in where macro
nelsonic Sep 10, 2020
3859c9f
move environment variable lookup to module attribute in upsert_status…
nelsonic Sep 10, 2020
82f8ff1
Merge branch 'rbac-issue-31' of github.com:dwyl/auth into rbac-issue-31
nelsonic Sep 10, 2020
3c4e5a2
check for API Keys that are "deleted" in get_client_secret/2 #107 + …
nelsonic Sep 10, 2020
3190d72
Restrict access to apps on all CRUD routes #99
nelsonic Sep 10, 2020
f45a850
add test for "deleted" API Key #106
nelsonic Sep 10, 2020
8ec7669
update test methods to put/delete instead of get for #99;
nelsonic Sep 10, 2020
5a21c74
address code issues noted by @sourcelevel-bot in https://github.com/d…
nelsonic Sep 10, 2020
cb45d38
update faulty logic for restricted apps resources #99
nelsonic Sep 10, 2020
bebb939
add :app_id field to :roles schema. tests still pass #108
nelsonic Sep 11, 2020
930ad6e
add app <select> to New Role form (and update tests) https://github.c…
nelsonic Sep 11, 2020
b56b840
add tests for 💯 #108
nelsonic Sep 11, 2020
ec389ab
💄 improve layout of show + edit for roles https://github.com/dwyl/aut…
nelsonic Sep 11, 2020
59560c0
create upsert_role/1 proxy function #95
nelsonic Sep 12, 2020
063e362
use Role.upsert_role/1 in seeds.exs #95
nelsonic Sep 12, 2020
64c88e8
add app.id and app.person_id (both hyperlinked) to apps index templat…
nelsonic Sep 12, 2020
93e7292
refactor apikey to use app_id instead of person_id fixes #111 for #95…
nelsonic Sep 12, 2020
d8b7e0f
mix format
nelsonic Sep 12, 2020
e5d8c5e
require app before displaying /roles/new fixe #112
nelsonic Sep 12, 2020
a199c9e
address sourcelevel issues noted in PR #85 #104
nelsonic Sep 12, 2020
5b8d32e
creating plumbing for /approles/:client_id request https://github.com…
nelsonic Sep 12, 2020
f09a184
[WiP] create GET /approles/:client_id test outline for #110
nelsonic Sep 12, 2020
568c770
create loooong test for checking access to approles is restricted by …
nelsonic Sep 12, 2020
5c12cf6
tidy up approles/2 for #110
nelsonic Sep 12, 2020
607f775
fix @sourceleve-bot issues in #110
nelsonic Sep 12, 2020
f261c85
reduce length of keys in conn.assigns.person #113
nelsonic Sep 12, 2020
fdab8cf
revert data changes #113
nelsonic Sep 12, 2020
e9c63cd
add app_id to people schema #108
nelsonic Sep 13, 2020
943ad03
(maintenance) update fields to 2.7.0 https://github.com/dwyl/fields/i…
nelsonic Sep 13, 2020
2b87797
update elixir+erlang version in .travis.yml #114
nelsonic Sep 13, 2020
1de4a08
check for Mix.env() == :prod in seeds.exs for https://github.com/dwyl…
nelsonic Sep 13, 2020
231d10a
use Elixir 1.10.4 and OTP/Erlang 23.0.4 in elixir_buildpack.config fo…
nelsonic Sep 13, 2020
ef2fa11
downgrade from Erlang 23.0.4 to 23.0.3 see: https://github.com/dwyl/a…
nelsonic Sep 13, 2020
cbd51a5
update dependencies to latest versions
nelsonic Sep 13, 2020
c9de4a5
add RBAC.init_roles_cache https://github.com/dwyl/auth/issues/110
nelsonic Sep 14, 2020
f7cb9a1
avoid overwriting .env file in seeds.exs
nelsonic Sep 14, 2020
6cd4495
add case for where .env file dont exist e.g. heroko
nelsonic Sep 14, 2020
297b93a
catch MatchError in seeds.exs
nelsonic Sep 14, 2020
5ca7ebc
even more error handling for no .env on travis ... 🙄
nelsonic Sep 14, 2020
ca5fcfa
check for TRAVIS env var https://travis-ci.com/github/dwyl/auth/jobs/…
nelsonic Sep 14, 2020
5242c6b
remove excess error checking code as not running env() on travis
nelsonic Sep 14, 2020
7849d5e
fix code error
nelsonic Sep 14, 2020
8395345
hide irrelevant nav links #115
nelsonic Sep 14, 2020
131efde
simplify app/show.html.eex template #115
nelsonic Sep 14, 2020
d57d17a
display "New App" button if the person does not have any apps on /pro…
nelsonic Sep 14, 2020
6c94745
address @sourcelevel-bot issues noted in PR #85
nelsonic Sep 14, 2020
80d3f6e
tidy up app/show template for consistency #115
nelsonic Sep 14, 2020
f27ce54
remove "Phoenix Framework" from page title (noise)
nelsonic Sep 14, 2020
818bba2
insert statuses before creating admin apikey in seeds.exs
nelsonic Sep 16, 2020
333a448
Add test and code for restricting creation of roles to apps the perso…
nelsonic Sep 16, 2020
707f4af
create is_owner function plug (no content yet) https://github.com/dwy…
nelsonic Sep 16, 2020
83ea6cb
update/add tests to reflect restriction of routes for #116
nelsonic Sep 16, 2020
c5f1821
address @sourcelevel-bot comments in #85
nelsonic Sep 16, 2020
035022b
mix format
nelsonic Sep 16, 2020
2aa91e5
Avoid negated conditions in if-else blocks. #85
nelsonic Sep 16, 2020
650635e
add check for ownership of role in update/2 (role controller) + test …
nelsonic Sep 16, 2020
e608d27
restrict who can edit a role (only owner) #116
nelsonic Sep 16, 2020
304a53f
restrict updating role to only alow apps the person owns #116
nelsonic Sep 17, 2020
9fdcf70
add clarifcation for need for map_get/2 function
nelsonic Sep 17, 2020
966f748
map_get/2 > map_get/3 (with default)
nelsonic Sep 17, 2020
71f6d0f
person.id == 1 (superadmin) can *always* see all apps #116
nelsonic Sep 17, 2020
ecae729
clarify reason for `list_apps/1 proxy function #116
nelsonic Sep 17, 2020
8738b44
move list_apps/1 proxy function to apps.ex (duh)
nelsonic Sep 17, 2020
be9b1f9
use list_apps/1 in app_controller
nelsonic Sep 17, 2020
23df807
mix format + address @sourcelevel-bot issue (line-spacing) 🙄
nelsonic Sep 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
language: elixir
elixir:
- 1.10.2
- 1.10.4
otp_release:
- 22.1.8
- 23.0.3
services:
- postgresql
env:
- MIX_ENV=test
before_script:
# create .env file on Travis-CI:
- echo "export MIX_ENV=test" > .env
- mix ecto.setup
script:
- mix do deps.get, coveralls.json
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ you can setup in ***5 minutes***.
<!-- uncomment when service is working ...
[![Inline docs](http://inch-ci.org/github/dwyl/auth.svg?branch=master&style=flat-square)](http://inch-ci.org/github/dwyl/auth)
-->
![wake-sleeping-heroku-app](https://dwylauth.herokuapp.com/ping)

</div>

Expand Down Expand Up @@ -173,7 +174,6 @@ And for sending emails you will need the
`SECRET_KEY_BASE` and `EMAIL_APP_URL` defined.



### 4. Create and migrate your database:

> Ensure that PostgreSQL is running
Expand All @@ -190,7 +190,7 @@ mix ecto.setup
mix phoenix.server
```

> It may take a couple of minutes to compile the app the first time. ⏳
> It may take a minute to compile the app the first time. ⏳

Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.

Expand Down
4 changes: 2 additions & 2 deletions elixir_buildpack.config
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Elixir version
elixir_version=1.10
elixir_version=1.10.4

# Erlang version
# available versions https://github.com/HashNuke/heroku-buildpack-elixir-otp-builds/blob/master/otp-versions
erlang_version=22.2.7
erlang_version=23.0.3

# always_rebuild=true
109 changes: 59 additions & 50 deletions lib/auth/apikey.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
defmodule Auth.Apikey do
@moduledoc """
Defines apikeys schema and CRUD functions
"""
use Ecto.Schema
import Ecto.Query, warn: false
import Ecto.Changeset
Expand All @@ -9,57 +12,79 @@ defmodule Auth.Apikey do
schema "apikeys" do
field :client_secret, :binary
field :client_id, :binary
field :description, :string
field :name, :string
field :url, :binary
field :person_id, :id
field :status, :id
belongs_to :app, Auth.App

timestamps()
end

@doc false
def changeset(apikey, attrs) do
apikey
|> cast(attrs, [:client_id, :client_secret, :name, :description, :url, :person_id])
|> validate_required([:client_secret])
@doc """
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These functions aren't new. I just moved them over from the ApikeysController file which was deleted in this PR. 👍

`encrypt_encode/1` does exactly what it's name suggests,
AES Encrypts a string of plaintext and then Base58 encodes it.
We encode it using Base58 so it's human-friendly (readable).
"""
def encrypt_encode(plaintext) do
plaintext |> Fields.AES.encrypt() |> Base58.encode()
end

def change_apikey(%Apikey{} = apikey) do
Apikey.changeset(apikey, %{})
@doc """
`create_api_key/1` uses the `encrypt_encode/1` to create an API Key
that is just two strings joined with a forwardslash ("/").
This allows us to use a *single* environment variable.
"""
def create_api_key(id) do
encrypt_encode(id) <> "/" <> encrypt_encode(id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this just duplicate the string? - am i missing something?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Close. On first inspection this appears to be the case, but actually these two strings are always different.
Because the initialisation vector changes each time Aes.encrypt is called, the client_id and client_secret will always be different. We sign the JWT with the client_secret and any app using auth_plug sends their client_id when making requests. i.e. the client_secret is never transmitted. It's basic pre-shared key security. 💭

end

def create_apikey(attrs \\ %{}) do
%Apikey{}
|> Apikey.changeset(attrs)
|> Repo.insert()
@doc """
`decode_decrypt/1` accepts a `key` and attempts to Base58.decode
followed by AES.decrypt it. If decode or decrypt fails, return 0 (zero).
"""
def decode_decrypt(key) do
try do
key |> Base58.decode() |> Fields.AES.decrypt() |> String.to_integer()
rescue
ArgumentError ->
0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for returning 0 and not {:error, :reason}?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I honestly don't mind refactoring this. I just thought the 0 failure was OK for MVP.
Again, this is a good area for improvement as is adding Logging for monitoring for the errors. 👍


ArithmeticError ->
0
end
end

def list_apikeys_for_person(person_id) do
query =
from(
a in __MODULE__,
where: a.person_id == ^person_id
)

Repo.all(query)
def decrypt_api_key(key) do
key |> String.split("/") |> List.first() |> decode_decrypt()
end

@doc """
Gets a single apikey.

Raises `Ecto.NoResultsError` if the Apikey does not exist.

## Examples
def changeset(apikey, attrs) do
apikey
|> cast(attrs, [:client_id, :client_secret, :status, :person_id])
|> put_assoc(:app, Map.get(attrs, "app"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might allow anyone to associate an API key with any "app", unless theres validation to check that the user owns the app beforehand.

It might be worth refactoring App and ApiKey out into a common context - e.g. a Project context with App and ApiKey models, as I feel like they are closely related with the possibility of some common functions

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@th0mas I briefly thought of removing apikey as a separate entity and just having app with a client_id and client_secret on the app (i.e. only one Key pair per app). But it was a lot of refactoring so I didn't ...

I'd actually be quite happy to re-build this whole thing from scratch in order to simplify it.
But for now I just want to finish this PR and get something working. 👍

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think this is a potential security risk as anytime any api is key is created or changed, there is the possibility of injecting another app as its owner.

end

iex> get_apikey!(123)
%Apikey{}
def create_apikey(app) do
attrs = %{
"client_secret" => encrypt_encode(app.id),
"client_id" => encrypt_encode(app.id),
"person_id" => app.person_id,
"status" => 3,
"app" => app
}

iex> get_apikey!(456)
** (Ecto.NoResultsError)
%Apikey{}
|> Apikey.changeset(attrs)
|> Repo.insert()
end

"""
def get_apikey!(id), do: Repo.get!(__MODULE__, id)
def get_apikey_by_app_id(app_id) do
from(
a in __MODULE__,
where: a.app_id == ^app_id
)
|> Repo.one()
|> Repo.preload(:app)
nelsonic marked this conversation as resolved.
Show resolved Hide resolved
end

@doc """
Updates a apikey.
Expand All @@ -78,20 +103,4 @@ defmodule Auth.Apikey do
|> changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a apikey.

## Examples

iex> delete_apikey(apikey)
{:ok, %Apikey{}}

iex> delete_apikey(apikey)
{:error, %Ecto.Changeset{}}

"""
def delete_apikey(%Apikey{} = apikey) do
Repo.delete(apikey)
end
end
155 changes: 155 additions & 0 deletions lib/auth/app.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
defmodule Auth.App do
@moduledoc """
Schema and helper functions for creating/managing Apps.
"""
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query, warn: false
alias Auth.Repo
# https://stackoverflow.com/a/47501059/1148249
alias __MODULE__

schema "apps" do
field :desc, :binary
field :end, :naive_datetime
field :name, :binary
field :url, :binary
field :person_id, :id
field :status, :id
has_many :apikeys, Auth.Apikey

timestamps()
end

@doc false
def changeset(app, attrs) do
app
|> cast(attrs, [:name, :desc, :url, :end, :person_id, :status])
|> validate_required([:name, :url])
end

@doc """
Returns the list of apps.

## Examples

iex> list_apps()
[%App{}, ...]

"""
def list_apps do
Repo.all(App)
end

# Returning all apps when person_id == 1 (superadmin) means
#  the superadmin can always see/manage all apps as necessary.
# Later we could refactor this function to use RBAC.has_role_any/2.
def list_apps(conn) when is_map(conn) do
case conn.assigns.person.id == 1 do
true -> Auth.App.list_apps()
false -> Auth.App.list_apps(conn.assigns.person.id)
end
end

def list_apps(person_id) do
App
|> where([a], a.status != 6 and a.person_id == ^person_id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a magic number here is still confusing, these should be refactored into constants

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This can be improved I was just hard-coding it because (at least for now) these are known values.

"text": "deleted",
"id": "6",

|> Repo.all()
end

@doc """
Gets a single app.

Raises `Ecto.NoResultsError` if the App does not exist.

## Examples

iex> get_app!(123)
%App{}

iex> get_app!(456)
** (Ecto.NoResultsError)

"""
def get_app!(id) do
App
|> where([a], a.id == ^id and a.status != 6)
nelsonic marked this conversation as resolved.
Show resolved Hide resolved
|> Repo.one()
|> Repo.preload(:apikeys)
end

@doc """
Creates a app.

## Examples

iex> create_app(%{field: value})
{:ok, %App{}}

iex> create_app(%{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def create_app(attrs \\ %{}) do
case %App{} |> App.changeset(attrs) |> Repo.insert() do
{:ok, app} ->
# Create API Key for App https://github.com/dwyl/auth/issues/97
Auth.Apikey.create_apikey(app)

# return the App with the API Key preloaded:
{:ok, get_app!(app.id)}

{:error, err} ->
{:error, err}
end
end

@doc """
Updates a app.

## Examples

iex> update_app(app, %{field: new_value})
{:ok, %App{}}

iex> update_app(app, %{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def update_app(%App{} = app, attrs) do
app
# |> IO.inspect(label: "update_app/2:109")
|> App.changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a app.

## Examples

iex> delete_app(app)
{:ok, %App{}}

iex> delete_app(app)
{:error, %Ecto.Changeset{}}

"""
def delete_app(%App{} = app) do
# "soft delete" for autiting purposes:
update_app(app, %{status: 6})
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking app changes.

## Examples

iex> change_app(app)
%Ecto.Changeset{data: %App{}}

"""
def change_app(%App{} = app, attrs \\ %{}) do
App.changeset(app, attrs)
end
end
3 changes: 3 additions & 0 deletions lib/auth/login_log.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
defmodule Auth.LoginLog do
@moduledoc """
Defines login_logs schema and CRUD functions
"""
use Ecto.Schema
import Ecto.Changeset
alias Auth.Repo
Expand Down
Loading