Dm Unibo Common is a Ruby gem (actually a Rails Engine) with code and configurations common to my ruby projects.
Check to have this gems in Gemfile:
gem 'dm_unibo_user_search', git: 'https://github.com/donapieppo/dm_unibo_user_search.git'
gem 'dm_unibo_common', git: 'https://github.com/donapieppo/dm_unibo_common.git', branch: 'turbo'
gem "cssbundling-rails", "~> 1.1"
gem "sprockets-rails"
gem "jsbundling-rails"
We use asbuild and postcss and so run
./bin/rails css:install:postcss
./bin/rails javascript:install:esbuild
(if you generate a new app use rails new pippo -j esbuild --css postcss
).
Add "dm_unibo_common": "donapieppo/dm_unibo_common.git"
in
package.json.
Create a file
touch ./config/dm_unibo_common.yml
like
production:
omniauth_provider: :google_oauth2
host: example.com
smtp_address: mailhost.example.com
smtp_domain: example.com
support_mail: [email protected]
logout_link: https://idp.example.comt/adfs/ls/?wa=wsignout1.0
login_icon: dm_unibo_common/ssologo18x18.png
logout_icon: dm_unibo_common/ssologo18x18.png
development:
omniauth_provider: :shibboleth
host: tester.example.com
smtp_address: mailhost.example.com
smtp_domain: example.com
support_mail: [email protected]
logout_link: https://idptest.example.com/adfs/ls/?wa=wsignout1.0
login_icon: dm_unibo_common/ssologo18x18.png
logout_icon: dm_unibo_common/ssologo18x18.png
and load in config/application.rb
with
config.dm_unibo_common = ActiveSupport::HashWithIndifferentAccess.new config_for(:dm_unibo_common)
DmUniboCommon implements google_oauth2 and shibboleth authentication.
In your app define User model
class User < ApplicationRecord
include DmUniboCommon::User
Organization model
class Organization < ApplicationRecord
include DmUniboCommon::Organization
has_many :permissions, class_name: "DmUniboCommon::Permission"
class Authorization
include DmUniboCommon::Authorization
_authlevels = {
read: 1,
manage: 2,
pippo: 3
}
configure_authlevels(_authlevels)
DmUniboCommon::OrganizationPolicy.configure_authlevels(_authlevels)
Your ApplicationController has to be a subclass of DmUniboCommon::ApplicationController
class ApplicationController < DmUniboCommon::ApplicationController
Then define routes in base of organization (see below).
Rails.application.routes.draw do
mount DmUniboCommon::Engine => "/dm_unibo_common"
scope ":__org__" do
.......
end
DmUniboCommon provides some helpers (see that comes from
lib/dm_unibo_common/controllers/helpers.rb
).
When you define ApplicationController as subclass of DmUniboCommon::ApplicationController
you get all the new helpers, Pundit authorization system
and a list of the following default before_actions
:
set_current_user
Sets the current_user
. DmUniboCommon
provides also the helper current_user
update_authorization
If there is a current_user it gets the DmUniboCommon::CurrentUser methods
(see app/models/dm_unibo_common/current_user.rb
, used as
current_user.extend(DmUniboCommon::CurrentUser
).
This means that the current_user
(a User
istance usually) gets the
authorization attribute that carries the current authorization of the user in
application (see below)
set_current_organization
Sets the current_organization
.
DmUniboCommon provides also the helper current_organization
.
Applications that uses DmUniboCommon provides usually the same application/user experience to different organziations (or administrative units).
For example in unibo organizations can be the different Departments or different administration units.
Every organization has a code in the database (and a name and description).
From the url
https://example.com/math/posts
params[:org] is 'math' and your controller/action is posts/index.
This is defined in config/routes.rb
as seen before.
current_user
has authorization in the form of an instance of
class DmUniboCommon::Authorization
(under the curtains current_user.authorization = DmUniboCommon::Authorization.new(ip, self))
DmUniboCommon::Authorization provides the next methods:
- has_authorization? -> true/false (has some organziation with some level of access?)
- multi_organizations? -> true/false (has more than one organization with some level of access?)
- organizations -> array of organizations where user has some level of access
- authlevel(org) -> int (level of authorization in organization)
in app/javascript/controllers/index.js
add
import { TurboModalController } from "dm_unibo_common"
application.register("turbo-modal", TurboModalController)
and in app/views/layouts/application.html.erb
<%= turbo_frame_tag "modal" %>
When you want to link to a modal content
<%= link_to article_path(article, modal: 1), data: { turbo_frame: :modal } %>
and in app/views/articles/show.html.erb
<%= render DmUniboCommon::ModalComponent.new(title: @article.name) do %>
...
<% end %>