Skip to content

Commit

Permalink
feat: Handle app Logo in database and auth provider (#510)
Browse files Browse the repository at this point in the history
  • Loading branch information
taorepoara authored Jan 8, 2024
1 parent 177abac commit 2cd4dcc
Show file tree
Hide file tree
Showing 15 changed files with 601 additions and 28 deletions.
7 changes: 6 additions & 1 deletion apps/identity_web/assets/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ header.external-client>p>a::after {
--logo-bg-color: rgba(var(--red-data), var(--disabled-opacity));
}

.logo::before {
.logo[data-letter]::before {
content: attr(data-letter);
display: block;
width: var(--logo-vertical-height);
Expand All @@ -137,6 +137,11 @@ header.external-client>p>a::after {
text-align: center;
}

.logo>img {
width: var(--logo-vertical-height);
height: var(--logo-vertical-height);
}

header.external-client>h1.logo::before {
margin-bottom: 2rem;
}
52 changes: 28 additions & 24 deletions apps/identity_web/lib/identity_web/views/oauth_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ defmodule IdentityWeb.OAuthHelpers do
@moduledoc """
Conveniences for translating OAuth scopes.
"""

use Phoenix.HTML

alias Lenra.Apps

@colors ["blue", "green", "red", "yellow"]
@colors_length length(@colors)

Expand All @@ -22,23 +23,14 @@ defmodule IdentityWeb.OAuthHelpers do
Render the header of the OAuth pages.
"""
def oauth_header("consent", %{"metadata" => %{"environment_id" => env_id}})
when is_binary(env_id) do
when is_integer(env_id) or is_binary(env_id) do
content_tag :header, class: "external-client" do
{:ok, app} = Lenra.Apps.fetch_app_for_env(env_id)

letter =
app.name
|> String.slice(0..0)
|> String.upcase()

[
content_tag :ul do
[
content_tag(:li, app.name,
class: "logo",
"data-letter": letter,
"data-color": get_color(app.service_name)
),
create_logo_tag(app, env_id, :li),
content_tag(:li, "Lenra", class: "lenra")
]
end,
Expand All @@ -51,21 +43,12 @@ defmodule IdentityWeb.OAuthHelpers do
end

def oauth_header(_context, %{"metadata" => %{"environment_id" => env_id}})
when is_binary(env_id) do
when is_integer(env_id) or is_binary(env_id) do
content_tag :header, class: "external-client" do
{:ok, app} = Lenra.Apps.fetch_app_for_env(env_id)

letter =
app.name
|> String.slice(0..0)
|> String.upcase()

[
content_tag(:h1, app.name,
class: "logo",
"data-letter": letter,
"data-color": get_color(app.service_name)
),
create_logo_tag(app, env_id, :h1),
content_tag :p do
[
"Powered by ",
Expand All @@ -76,7 +59,7 @@ defmodule IdentityWeb.OAuthHelpers do
end
end

def oauth_header(_context, _client) do
def oauth_header(_context, client) do
content_tag :header do
content_tag(:h1, "Lenra")
end
Expand All @@ -102,4 +85,25 @@ defmodule IdentityWeb.OAuthHelpers do
def get_translated_scope_description(scope) do
Gettext.dgettext(IdentityWeb.Gettext, "oauth", "scope." <> scope)
end

defp create_logo_tag(app, env_id, tagname) do
case Apps.get_logo(app.id, env_id) do
nil ->
letter =
app.name
|> String.slice(0..0)
|> String.upcase()

content_tag(tagname, app.name,
class: "logo",
"data-letter": letter,
"data-color": get_color(app.service_name)
)

logo ->
content_tag tagname, class: "logo" do
img_tag("#{Application.fetch_env!(:lenra_web, :public_api_url)}/apps/images/#{logo.image_id}", alt: app.name)
end
end
end
end
72 changes: 72 additions & 0 deletions apps/lenra/lib/lenra/apps.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ defmodule Lenra.Apps do
Build,
Deployment,
Environment,
Image,
Logo,
MainEnv,
OAuth2Client,
UserEnvironmentAccess
Expand Down Expand Up @@ -635,4 +637,74 @@ defmodule Lenra.Apps do
{:halt, error_tuple}
end)
end

# Manage Images

def set_logo(user_id, %{"app_id" => app_id} = params) do
Ecto.Multi.new()
# create the image
|> Ecto.Multi.insert(:inserted_image, Image.new(user_id, params))
# check if there already a logo for this app (or env ?)
|> Ecto.Multi.one(
:old_logo,
case params do
%{"env_id" => env_id} ->
from(
l in Logo,
where:
l.application_id == ^app_id and
l.environment_id == ^env_id
)

_params ->
from(
l in Logo,
where:
l.application_id == ^app_id and
is_nil(l.environment_id)
)
end
)
# update the app/env with the image id
|> Ecto.Multi.run(:new_logo, fn repo, state -> upsert_logo(repo, state, params) end)
|> Repo.transaction()
end

defp upsert_logo(transaction, %{inserted_image: image, old_logo: old_logo} = state, %{"app_id" => app_id} = params) do
case old_logo do
nil ->
transaction.insert(Logo.new(app_id, params["env_id"], %{image_id: image.id}))

%Logo{image_id: old_logo_image_id} ->
result = transaction.update(Logo.changeset(old_logo, %{image_id: image.id}))

# delete the previous image if it's not used anymore
if !transaction.exists?(from(l in Logo, where: l.image_id == ^old_logo_image_id)) do
old_image = transaction.get!(Image, old_logo_image_id)
transaction.delete(old_image)
end

result
end
end

def get_logo(app_id, env_id) do
Logger.debug("#{__MODULE__} get logo for app id #{app_id} and env id #{env_id}")

Repo.one(
from(l in Logo,
where: l.application_id == ^app_id and (l.environment_id == ^env_id or is_nil(l.environment_id)),
order_by: is_nil(l.environment_id),
limit: 1
)
)
end

def fetch_image(image_id) do
Repo.fetch(Image, image_id)
end

def get_image(image_id) do
Repo.get(Image, image_id)
end
end
39 changes: 39 additions & 0 deletions apps/lenra/lib/lenra/apps/image.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
defmodule Lenra.Apps.Image do
@moduledoc """
The image schema.
"""

use Lenra.Schema
import Ecto.Changeset
alias Lenra.Accounts.User

@type t :: %__MODULE__{}

@derive {Jason.Encoder,
only: [
:data,
:type,
:creator_id
]}
schema "images" do
field(:data, :binary)
field(:type, :string)
belongs_to(:creator, User)

timestamps()
end

def changeset(image, params \\ %{}) do
image
|> cast(params, [:data, :type])
|> validate_required([:data, :type, :creator_id])
|> foreign_key_constraint(:creator_id)
end

def new(creator_id, params) do
%__MODULE__{
creator_id: creator_id
}
|> __MODULE__.changeset(params)
end
end
44 changes: 44 additions & 0 deletions apps/lenra/lib/lenra/apps/logo.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
defmodule Lenra.Apps.Logo do
@moduledoc """
The logo schema.
"""

use Lenra.Schema
import Ecto.Changeset
alias Lenra.Apps.App
alias Lenra.Apps.Environment
alias Lenra.Apps.Image

@type t :: %__MODULE__{}

@derive {Jason.Encoder,
only: [
:application_id,
:environment_id,
:image_id
]}
schema "logos" do
belongs_to(:application, App)
belongs_to(:environment, Environment)
belongs_to(:image, Image)

timestamps()
end

def changeset(logo, params) do
logo
|> cast(params, [:image_id])
|> validate_required([:application_id, :image_id])
|> foreign_key_constraint(:application_id)
|> foreign_key_constraint(:environment_id)
|> foreign_key_constraint(:image_id)
end

def new(application_id, environment_id, params \\ %{}) do
%__MODULE__{
application_id: application_id,
environment_id: environment_id
}
|> __MODULE__.changeset(params)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule Lenra.Repo.Migrations.ManageAppAndEnvLogo do
use Ecto.Migration

def change do
create table(:images) do
add(:creator_id, references(:users))
add(:data, :binary)
add(:type, :string)
timestamps()
end

create table(:logos) do
add(:application_id, references(:applications))
add(:environment_id, references(:applications), null: true)
add(:image_id, references(:images))
timestamps()
end

create(unique_index(:logos, [:application_id, :environment_id], name: :logos_application_id_environment_id_index))
end
end
2 changes: 1 addition & 1 deletion apps/lenra/test/lenra/apps/environment_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule Lenra.Apps.EnvironmentTest do
@moduledoc """
Test the environment services
"""
use Lenra.RepoCase, async: true
use Lenra.RepoCase, async: false

alias Lenra.Repo

Expand Down
Loading

0 comments on commit 2cd4dcc

Please sign in to comment.