Skip to content

Commit

Permalink
Refactoring and fixes for #871 #941 #939
Browse files Browse the repository at this point in the history
  • Loading branch information
mellelieuwes committed Sep 4, 2024
1 parent 979098b commit 7e13bbe
Show file tree
Hide file tree
Showing 126 changed files with 1,315 additions and 1,150 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- id: setup-elixir
uses: erlef/setup-elixir@v1
with:
otp-version: "25.0.4"
otp-version: "25.3.2.7"
elixir-version: "1.14.0"

- name: Setup the Elixir project
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
erlang 25.0.4
erlang 25.3.2.7
elixir 1.14.0-otp-25
nodejs 18.19.0
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
"elixir": "html",
"phoenix-heex": "html"
},
"editor.tabCompletion": "on"
"editor.tabCompletion": "on",
"elixirLS.mixEnv": "dev"
}
4 changes: 2 additions & 2 deletions core/assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { decode } from "blurhash";
import { urlBase64ToUint8Array } from "./tools";
import { registerAPNSDeviceToken } from "./apns";
import "./100vh-fix";
import { ViewportResize } from "./viewport_resize";
import { Viewport } from "./viewport";
import { SidePanel } from "./side_panel";
import { Toggle } from "./toggle";
import { Cell } from "./cell";
Expand Down Expand Up @@ -108,7 +108,7 @@ let Hooks = {
Tabbar,
TabbarItem,
TabbarFooterItem,
ViewportResize,
Viewport,
Wysiwyg,
AutoSubmit,
Sticky,
Expand Down
15 changes: 10 additions & 5 deletions core/assets/js/viewport_resize.js → core/assets/js/viewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@ import _ from "lodash";

let resizeHandler;

export const ViewportResize = {
export const Viewport = {
mounted() {
// Direct push of current window size to properly update view
this.pushResizeEvent();

window.addEventListener("resize", (event) => {
this.pushResizeEvent();
this.pushChangeEvent();
});
},

pushResizeEvent() {
console.log("pushResizeEvent");
this.pushEvent("viewport_resize", {
updated() {
console.log("[Viewport] updated");
this.pushChangeEvent();
},

pushChangeEvent() {
console.log("[Viewport] push update event");
this.pushEvent("viewport_changed", {
width: window.innerWidth,
height: window.innerHeight,
});
Expand Down
17 changes: 15 additions & 2 deletions core/bundles/next/lib/account/signin_page.ex
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
defmodule Next.Account.SigninPage do
use CoreWeb, :live_view

on_mount({CoreWeb.Live.Hook.Base, __MODULE__})
on_mount({CoreWeb.Live.Hook.User, __MODULE__})
on_mount({CoreWeb.Live.Hook.Uri, __MODULE__})
on_mount({Frameworks.GreenLight.LiveHook, __MODULE__})
on_mount({Frameworks.Fabric.LiveHook, __MODULE__})

import CoreWeb.Layouts.Stripped.Html
import CoreWeb.Layouts.Stripped.Composer
import CoreWeb.Menus

import Frameworks.Pixel.Line

alias Frameworks.Pixel.Tabbar

alias Next.Account.SigninPageBuilder

@impl true
Expand All @@ -29,11 +37,16 @@ defmodule Next.Account.SigninPage do
}
end

defp update_view_model(socket) do
def update_view_model(socket) do
vm = SigninPageBuilder.view_model(nil, socket.assigns)
assign(socket, vm: vm)
end

def update_menus(%{assigns: %{current_user: user, uri: uri}} = socket) do
menus = build_menus(stripped_menus_config(), user, uri)
assign(socket, menus: menus)
end

@impl true
def render(assigns) do
~H"""
Expand Down
14 changes: 14 additions & 0 deletions core/bundles/self/lib/account/signin_page.ex
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
defmodule Self.Account.SigninPage do
use CoreWeb, :live_view

on_mount({CoreWeb.Live.Hook.Base, __MODULE__})
on_mount({CoreWeb.Live.Hook.User, __MODULE__})
on_mount({CoreWeb.Live.Hook.Uri, __MODULE__})
on_mount({Frameworks.GreenLight.LiveHook, __MODULE__})
on_mount({Frameworks.Fabric.LiveHook, __MODULE__})

import CoreWeb.Layouts.Stripped.Html
import CoreWeb.Layouts.Stripped.Composer
import CoreWeb.Menus

alias Systems.Account.User
alias Systems.Account.UserForm

@impl true
def mount(params, _session, socket) do
require_feature(:password_sign_in)

Expand All @@ -18,6 +27,11 @@ defmodule Self.Account.SigninPage do
}
end

def update_menus(%{assigns: %{current_user: user, uri: uri}} = socket) do
menus = build_menus(stripped_menus_config(), user, uri)
assign(socket, menus: menus)
end

defp update_form(%{assigns: %{email: nil}} = socket) do
assign(socket, :form, to_form(%{}))
end
Expand Down
3 changes: 1 addition & 2 deletions core/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,10 @@ config :plug, :statuses, %{
404 => "Page not found"
}

config :core, :branch, factory: Systems.Project.Public

config :core, CoreWeb.FileUploader, max_file_size: 100_000_000

config :core,
greenlight_auth_module: Core.Authorization,
image_catalog: Core.ImageCatalog.Unsplash,
banking_backend: Systems.Banking.Dummy

Expand Down
34 changes: 7 additions & 27 deletions core/frameworks/concept/branch.ex
Original file line number Diff line number Diff line change
@@ -1,31 +1,11 @@
defmodule Frameworks.Concept.Branch do
defmodule Factory do
@type scope :: :self | :parent
@type leaf :: struct()
@callback name(leaf, scope) :: {:ok, binary()} | {:error, atom()}
@callback hierarchy(leaf) :: {:ok, list()} | {:error, atom()}
end
defprotocol Frameworks.Concept.Branch do
# FIXME: add possibility to resolve dependencies to leafs (siblings)

require Logger
@type scope :: :self | :parent

def name(leaf, scope, default) when is_struct(leaf) and is_binary(default) do
case factory().name(leaf, scope) do
{:ok, name} ->
name
@spec name(t, scope) :: binary
def name(_t, _scope)

{:error, error} ->
Logger.warn(
"[Branch] Error while fetching name: #{inspect(error)} for leaf #{inspect(leaf)}"
)

default
end
end

def hierarchy(leaf) when is_struct(leaf) do
factory().hierarchy(leaf)
end

defp factory, do: Access.get(settings(), :factory, nil)
defp settings, do: Application.fetch_env!(:core, :branch)
@spec hierarchy(t) :: list
def hierarchy(_t)
end
28 changes: 28 additions & 0 deletions core/frameworks/concept/live_hook.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
defmodule Frameworks.Concept.LiveHook do
@type live_view_module :: atom()
@type params :: map()
@type session :: map()
@type socket :: Phoenix.LiveView.Socket.t()

@callback on_mount(live_view_module(), params(), session(), socket()) ::
{:cont | :halt, socket()}

defmacro __using__(_opts) do
quote do
@behaviour Frameworks.Concept.LiveHook

import Phoenix.LiveView,
only: [attach_hook: 4, connected?: 1, get_connect_params: 1, redirect: 2]

import Phoenix.Component, only: [assign: 2]

def optional_apply(socket, live_view_module, function) do
Frameworks.Utility.Module.optional_apply(live_view_module, function, [socket], socket)
end

def optional_apply(socket, live_view_module, function, args) when is_list(args) do
Frameworks.Utility.Module.optional_apply(live_view_module, function, args, socket)
end
end
end
end
9 changes: 9 additions & 0 deletions core/frameworks/fabric/live_hook.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Frameworks.Fabric.LiveHook do
import Phoenix.Component, only: [assign: 2]

def on_mount(_live_view_module, _params, _session, socket) do
self = %Fabric.LiveView.RefModel{pid: self()}
fabric = %Fabric.Model{parent: nil, self: self, children: nil}
{:cont, socket |> assign(fabric: fabric)}
end
end
22 changes: 0 additions & 22 deletions core/frameworks/fabric/live_view_mount_plug.ex

This file was deleted.

23 changes: 23 additions & 0 deletions core/frameworks/green_light/_live_feature.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Frameworks.GreenLight.LiveFeature do
@callback get_authorization_context(
Phoenix.LiveView.unsigned_params() | :not_mounted_at_router,
session :: map,
socket :: Phoenix.Socket.t()
) :: integer | struct

@optional_callbacks get_authorization_context: 3

defmacro __using__(_opts) do
quote do
@behaviour Frameworks.GreenLight.LiveFeature

def mount(params, session, %{assigns: %{authorization_failed: true}} = socket) do
{:ok, socket}
end

def render(%{authorization_failed: true}) do
raise Frameworks.GreenLight.AccessDeniedError, "Authorization failed for #{__MODULE__}"
end
end
end
end
40 changes: 40 additions & 0 deletions core/frameworks/green_light/_live_hook.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule Frameworks.GreenLight.LiveHook do
@moduledoc """
Live Hook that enables automatic authorization checks.
"""
use Frameworks.Concept.LiveHook
use CoreWeb, :verified_routes
require Logger

@impl true
def on_mount(live_view_module, params, session, socket) do
if access_allowed?(live_view_module, params, session, socket) do
{:cont, socket}
else
{:halt, redirect(socket, to: ~p"/access_denied")}
end
end

defp access_allowed?(live_view_module, params, session, socket) do
user = Map.get(socket.assigns, :current_user)

if function_exported?(live_view_module, :get_authorization_context, 3) do
can_access? =
auth_module().can_access?(
user,
live_view_module.get_authorization_context(params, session, socket)
|> Core.Authorization.print_roles(),
live_view_module
)

Logger.notice("User #{user.id} can_access? #{live_view_module}: #{can_access?}")
can_access?
else
auth_module().can_access?(user, live_view_module)
end
end

defp auth_module() do
Application.get_env(:core, :greenlight_auth_module)
end
end
61 changes: 0 additions & 61 deletions core/frameworks/green_light/live.ex

This file was deleted.

Loading

0 comments on commit 7e13bbe

Please sign in to comment.