Skip to content

Commit

Permalink
chore: add routes to fetch to rotate api keys
Browse files Browse the repository at this point in the history
  • Loading branch information
Clivern committed Sep 20, 2024
1 parent 254e3cc commit 89b7d81
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 3 deletions.
25 changes: 25 additions & 0 deletions lib/lynx/module/user_module.ex
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,31 @@ defmodule Lynx.Module.UserModule do
end
end

@doc """
Rotate User API Key
"""
def rotate_api_key(user_uuid, new_api_key) do
user = UserContext.get_user_by_uuid(user_uuid)

case user do
nil ->
{:not_found, "User with ID #{user_uuid} not found"}

_ ->
case UserContext.update_user(user, %{api_key: new_api_key}) do
{:ok, user} ->
{:ok, user}

{:error, changeset} ->
messages =
changeset.errors()
|> Enum.map(fn {field, {message, _options}} -> "#{field}: #{message}" end)

{:error, Enum.at(messages, 0)}
end
end
end

@doc """
Delete User by UUID
"""
Expand Down
48 changes: 47 additions & 1 deletion lib/lynx_web/controllers/profile_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ defmodule LynxWeb.ProfileController do
@name_min_length 2
@name_max_length 60

alias Lynx.Service.AuthService
alias Lynx.Module.UserModule
alias Lynx.Service.ValidatorService

plug :regular_user when action in [:update]
plug :regular_user when action in [:update, :fetch_api_key, :rotate_api_key]

defp regular_user(conn, _opts) do
Logger.info("Validate user permissions")
Expand Down Expand Up @@ -74,6 +75,51 @@ defmodule LynxWeb.ProfileController do
end
end

@doc """
Fetch API Key Endpoint
"""
def fetch_api_key(conn, _params) do
case UserModule.get_user_by_uuid(conn.assigns[:user_uuid]) do
nil ->
conn
|> put_status(:not_found)
|> render("error.json", %{message: "Profile not found"})

user ->
conn
|> put_status(:ok)
|> render("user.json", %{api_key: user.api_key})
end
end

@doc """
Rotate API Key Endpoint
"""
def rotate_api_key(conn, _params) do
api_key = AuthService.get_uuid()

case UserModule.rotate_api_key(conn.assigns[:user_uuid], AuthService.get_uuid()) do
{:not_found, msg} ->
Logger.info(msg)

conn
|> put_status(:not_found)
|> render("error.json", %{message: "Profile not found"})

{:error, msg} ->
Logger.error(msg)

conn
|> put_status(:bad_request)
|> render("error.json", %{message: "Failed to rotate the API Key"})

{:ok, _} ->
conn
|> put_status(:ok)
|> render("user.json", %{api_key: api_key})
end
end

defp validate_update_request(params, user_uuid) do
errs = %{
name_required: "User name is required",
Expand Down
2 changes: 1 addition & 1 deletion lib/lynx_web/controllers/user_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ defmodule LynxWeb.UserController do
UserModule.create_user(%{
name: params["name"],
email: params["email"],
api_key: AuthService.get_random_salt(),
api_key: AuthService.get_uuid(),
role: params["role"],
password: params["password"]
})
Expand Down
6 changes: 6 additions & 0 deletions lib/lynx_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ defmodule LynxWeb.Router do
# Profile Endpoints
post "/profile", ProfileController, :update

# Fetch API Key Endpoint
post "/api_key/fetch", ProfileController, :fetch_api_key

# Rotate API Key Endpoint
post "/api_key/rotate", ProfileController, :rotate_api_key

# Task Endpoints
get "/task/:uuid", TaskController, :index

Expand Down
8 changes: 7 additions & 1 deletion lib/lynx_web/templates/page/profile.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,14 @@
</div>
<div class="col-12 mt-16">
<div class="mb-24">
<input class="form-control" name="api_key" type="text" value={@data.user_api_key} disabled>
<input class="form-control" name="api_key" type="text" value="**************************" disabled>
</div>
<button id="show_api_key" type="submit" class="btn btn-sm btn-dark">
<%= gettext "Show the Key" %>
</button>
<button id="rotate_api_key" type="submit" class="btn btn-sm btn-dark">
<%= gettext "Rotate the Key" %>
</button>
</div>
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions lib/lynx_web/views/profile_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ defmodule LynxWeb.ProfileView do
def render("error.json", %{message: message}) do
%{errorMessage: message}
end

def render("user.json", %{api_key: api_key}) do
%{apiKey: api_key}
end
end

0 comments on commit 89b7d81

Please sign in to comment.