Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ For local development dynamically generated, extensive seeds are available for e
[the delayed job documentation](https://github.com/collectiveidea/delayed_job?tab=readme-ov-file#running-jobs)
or just simply run `rails jobs:work` to start working off queued delayed jobs.

## Permission System
In the current permission system, users can only edit their own profiles.
The Role Editor role, as well as Admin and Config Admin, can edit all profiles.
Flash messages will notify you whenever you attempt to edit a profile, indicating whether you have permission.

## PuzzleTime synchronization
If you are using PuzzleSkills as an external company and are not also using the PuzzleTime application, this part of the
application will not bother you.
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/admin/companies_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Admin::CompaniesController < CrudController
self.nesting = :admin
self.permitted_attrs = %i[name reminder_mails_active]
before_action :render_unauthorized_not_conf_admin
before_action :render_unauthorized_not_admin

def list_entries
super.includes(:people)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/admin/departments_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Admin::DepartmentsController < CrudController
self.nesting = :admin
self.permitted_attrs = %i[name]
before_action :render_unauthorized_not_conf_admin
before_action :render_unauthorized_not_admin

def list_entries
super.includes(:people)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/admin/manual_ptime_sync_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Admin::ManualPtimeSyncController < CrudController
self.nesting = :admin
before_action :render_unauthorized_not_conf_admin
before_action :render_unauthorized_not_admin
before_action :redirect_admin, unless: -> { Skills.use_ptime_sync? }

def manual_sync
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/admin/people_management_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Admin::PeopleManagementController < CrudController
self.nesting = :admin
before_action :render_unauthorized_not_conf_admin
before_action :render_unauthorized_not_admin

def self.model_class
Person
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/admin/roles_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Admin::RolesController < CrudController
self.nesting = :admin
self.permitted_attrs = %i[name]
before_action :render_unauthorized_not_conf_admin
before_action :render_unauthorized_not_admin
end
6 changes: 1 addition & 5 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def switch_locale(&)
def authenticate_auth_user!(opts = {})
return super if helpers.devise?

admin = AuthUser.find_by(email: 'conf_admin@skills.ch')
admin = AuthUser.find_by(email: 'editor@skills.ch')
raise 'User not found. This is highly likely due to a non-seeded database.' unless admin

request.env['warden'].set_user(admin, :scope => :auth_user)
Expand All @@ -36,10 +36,6 @@ def render_unauthorized_not_admin
render_unauthorized(helpers.admin?)
end

def render_unauthorized_not_conf_admin
render_unauthorized(helpers.conf_admin?)
end

def render_unauthorized(is_authorized)
return false if is_authorized

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/crud_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def show
#
# Display a form to create a new entry of this model.
def new
raise CanCan::AccessDenied unless can? :create, model_class
raise CanCan::AccessDenied unless can? :create, entry

assign_attributes if params[model_identifier]
end
Expand Down
6 changes: 6 additions & 0 deletions app/domain/ptime/people_employees.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def update_inactive_people(employees)
def update_person_data
update_directly_mappable_attributes
update_indirectly_mappable_attributes
set_auth_user_id_on_person
@person.save!
update_person_roles
end
Expand Down Expand Up @@ -111,5 +112,10 @@ def sanitized_role_name(role_name)
def person_role_level_id_by_role(role)
PersonRoleLevel.find_by(level: role[:role_level])&.id || PersonRoleLevel.first.id
end

def set_auth_user_id_on_person
ldap_username = @ptime_employee_attributes[:ldapname]
@person.auth_user_id = AuthUser.find_by!(ldap_username:)&.id
end
end
end
4 changes: 2 additions & 2 deletions app/helpers/auth_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ def admin?
current_auth_user&.is_admin
end

def conf_admin?
current_auth_user&.is_conf_admin || false
def editor?
current_auth_user&.is_editor
end

def find_person_by_auth_user
Expand Down
10 changes: 10 additions & 0 deletions app/helpers/person_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,14 @@ def people_for_select
def use_ptime_sync?
Skills.use_ptime_sync?
end

def person_alert(person)
if current_auth_user&.person == person
{ message: '.editing_own_profile', alert_class: 'alert-success' }
elsif can?(:update, person)
{ message: '.permission_to_edit_person', alert_class: 'alert-success' }
else
{ message: '.no_permission_to_edit_person', alert_class: 'alert-info' }
end
end
end
5 changes: 3 additions & 2 deletions app/javascript/controllers/people_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["message"]

remove() {
this.messageTarget.remove();
remove(event) {
event.preventDefault();
this.element.remove();
}
}
55 changes: 33 additions & 22 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
@@ -1,47 +1,58 @@
# frozen_string_literal: true

class Ability
include CanCan::Ability

def initialize(user)
initialize_user_rights
if user.is_admin? || user.is_conf_admin?
initialize_admin_rights
end
if user.is_conf_admin?
initialize_conf_admin_rights
initialize_user_rights(user)

role_initializers.each do |predicate, initializer|
send(initializer) if user.public_send(predicate)
end
end

def initialize_user_rights
user_classes.each do |user_classes|
can :manage, user_classes
end
private

def role_initializers
{
is_editor?: :initialize_editor_rights,
is_admin?: :initialize_admin_rights
}
end

def initialize_user_rights(user)
user_classes.each do |user_class|
can :read, user_class
can :manage, user_class do |record|
record.person.auth_user_id == user.id
end
end
can :read, Skill
can :read, Person
can :update, Person, auth_user_id: user.id
can :destroy, Person, auth_user_id: user.id
end

def initialize_admin_rights
admin_classes.each do |admin_class|
can :manage, admin_class
def initialize_editor_rights
editor_classes.each do |editor_class|
can :manage, editor_class
end
end

def initialize_conf_admin_rights
conf_admin_classes.each do |conf_admin_class|
can :manage, conf_admin_class
def initialize_admin_rights
initialize_editor_rights
admin_classes.each do |admin_class|
can :manage, admin_class
end
end

def user_classes
[Activity, AdvancedTraining, Education, Project, Person, PeopleSkill, Contribution]
[Activity, AdvancedTraining, Education, Project, PeopleSkill, Contribution]
end

def conf_admin_classes
[Department, Role, Company]
def editor_classes
[Activity, AdvancedTraining, Education, Person, Project, PeopleSkill, Contribution]
end

def admin_classes
[Certificate, Skill, UnifiedSkill, UnifiedSkillForm]
[Certificate, Skill, UnifiedSkill, UnifiedSkillForm, Department, Role, Company]
end
end
14 changes: 9 additions & 5 deletions app/models/auth_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@ class AuthUser < ApplicationRecord

devise :omniauthable, omniauth_providers: [:keycloak_openid]

has_one :person, dependent: :restrict_with_error

class << self
def from_omniauth(auth)
person = where(uid: auth.uid).first_or_create do |user|
user.name = auth.info.name
user.email = auth.info.email
end
person = where(uid: auth.uid).first_or_create { |user| initialize_user(user, auth) }
person.last_login = Time.zone.now
set_admin(person, auth)
end

private

def initialize_user(user, auth)
user.name = auth.info.name
user.email = auth.info.email
user.ldap_username = auth.extra.raw_info.pitc.uid
end

def set_admin(person, auth)
person.is_admin = role?(auth, AuthConfig.admin_role)
person.is_conf_admin = role?(auth, AuthConfig.conf_admin_role)
person.save
person
end
Expand Down
1 change: 1 addition & 0 deletions app/models/person.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Person < ApplicationRecord

belongs_to :company
belongs_to :department, optional: true
belongs_to :auth_user, optional: true

mount_uploader :picture, PictureUploader
has_many :projects, dependent: :destroy
Expand Down
26 changes: 14 additions & 12 deletions app/views/activities/_activity.html.haml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
- card_content = capture do
%div.d-flex.row.pt-3.pb-5
%span.col-3.ps-5
= date_range_label activity
%span.col.d-flex.flex-column.text-ms
%span.fw-bolder
= activity.role
= activity.description
- unless activity.display_in_cv
%span.col-1.d-flex.justify-content-end.pe-5
%div{ 'data-bs-toggle': 'tooltip', 'data-bs-title': t("people.show.is_not_displayed_in_cv"), 'data-controller': 'tooltip', 'data-action': 'click->tooltip#hide'}
= image_tag('no-file.svg')

%div.border-top
%turbo-frame{id: dom_id(activity)}
= link_to edit_person_activity_path(@person, activity), data:{turbo_prefetch: :false, turbo_frame: dom_id(activity)}, class: "text-decoration-none text-dark bg-hover-gray d-block" do
%div.d-flex.row.pt-3.pb-5
%span.col-3.ps-5
= date_range_label activity
%span.col.d-flex.flex-column.text-ms
%span.fw-bolder
= activity.role
= activity.description
- unless activity.display_in_cv
%span.col-1.d-flex.justify-content-end.pe-5
%div{ 'data-bs-toggle': 'tooltip', 'data-bs-title': t("people.show.is_not_displayed_in_cv"), 'data-controller': 'tooltip', 'data-action': 'click->tooltip#hide'}
= image_tag('no-file.svg')
= link_to_if can?(:update, activity), card_content , edit_person_activity_path(@person, activity), data:{turbo_prefetch: :false, turbo_frame: dom_id(activity)}, class: "text-decoration-none text-dark bg-hover-gray d-block"
26 changes: 15 additions & 11 deletions app/views/advanced_trainings/_advanced_training.html.haml
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
- card_content = capture do
%div.d-flex.row.pt-3.pb-5
%span.col-3.ps-5
= date_range_label advanced_training
%span.col.text-ms
= advanced_training.description
- unless advanced_training.display_in_cv
%span.col-1.d-flex.justify-content-end.pe-5
%div{ 'data-bs-toggle': 'tooltip', 'data-bs-title': t("people.show.is_not_displayed_in_cv"), 'data-controller': 'tooltip', 'data-action': 'click->tooltip#hide'}
= image_tag('no-file.svg')



%div.border-top
%turbo-frame{id: dom_id(advanced_training)}
= link_to edit_person_advanced_training_path(advanced_training.person, advanced_training), data:{turbo_prefetch: :false, turbo_frame: dom_id(advanced_training)}, class: "text-decoration-none text-dark bg-hover-gray d-block" do
%div.d-flex.row.pt-3.pb-5
%span.col-3.ps-5
= date_range_label advanced_training
%span.col.text-ms
= advanced_training.description
- unless advanced_training.display_in_cv
%span.col-1.d-flex.justify-content-end.pe-5
%div{ 'data-bs-toggle': 'tooltip', 'data-bs-title': t("people.show.is_not_displayed_in_cv"), 'data-controller': 'tooltip', 'data-action': 'click->tooltip#hide'}
= image_tag('no-file.svg')
%turbo-frame{id: dom_id(advanced_training)}
= link_to_if can?(:update, advanced_training), card_content, edit_person_advanced_training_path(advanced_training.person, advanced_training), data:{turbo_prefetch: :false, turbo_frame: dom_id(advanced_training)}, class: "text-decoration-none text-dark bg-hover-gray d-block"
32 changes: 17 additions & 15 deletions app/views/contributions/_contribution.html.haml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
- card_content = capture do
%div.d-flex.row.pt-3.pb-5
%span.col-3.ps-5
= date_range_label contribution
%span.col.d-flex.flex-column
%span.fw-bolder
= contribution.title
%span{ data: { contribution_target: "reference" } }
= contribution.reference
- if link_valid(contribution.reference)
%label.btn.btn-outline-primary.w-20.mt-4{ data: { action: "click->contribution#openReference" } }= t("people.contributions.link.open")
- unless contribution.display_in_cv
%span.col-1.d-flex.justify-content-end.pe-5
%div{ 'data-bs-toggle': 'tooltip', 'data-bs-title': t("people.show.is_not_displayed_in_cv"), 'data-controller': 'tooltip', 'data-action': 'click->tooltip#hide'}
= image_tag('no-file.svg')

%div.border-top{ data: { controller: "contribution" } }
%turbo-frame{id: dom_id(contribution)}
= link_to edit_person_contribution_path(contribution.person, contribution), data:{turbo_prefetch: :false, turbo_frame: dom_id(contribution)}, class: "text-decoration-none text-dark bg-hover-gray d-block" do
%div.d-flex.row.pt-3.pb-5
%span.col-3.ps-5
= date_range_label contribution
%span.col.d-flex.flex-column
%span.fw-bolder
= contribution.title
%span{ data: { contribution_target: "reference" } }
= contribution.reference
- if link_valid(contribution.reference)
%label.btn.btn-outline-primary.w-20.mt-4{ data: { action: "click->contribution#openReference" } }= t("people.contributions.link.open")
- unless contribution.display_in_cv
%span.col-1.d-flex.justify-content-end.pe-5
%div{ 'data-bs-toggle': 'tooltip', 'data-bs-title': t("people.show.is_not_displayed_in_cv"), 'data-controller': 'tooltip', 'data-action': 'click->tooltip#hide'}
= image_tag('no-file.svg')
= link_to_if can?(:update, contribution), card_content, edit_person_contribution_path(contribution.person, contribution), data: { turbo_prefetch: :false, turbo_frame: dom_id(contribution) }, class: "text-decoration-none text-dark bg-hover-gray d-block"
26 changes: 14 additions & 12 deletions app/views/educations/_education.html.haml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
- card_content = capture do
%div.d-flex.row.pt-3.pb-5
%span.col-3.ps-5
= date_range_label education
%span.col.d-flex.flex-column.text-ms
%span.fw-bolder
= education.title
= education.location
- unless education.display_in_cv
%span.col-1.d-flex.justify-content-end.pe-5
%div{ 'data-bs-toggle': 'tooltip', 'data-bs-title': t("people.show.is_not_displayed_in_cv"), 'data-controller': 'tooltip', 'data-action': 'click->tooltip#hide'}
= image_tag('no-file.svg')

%div.border-top
%turbo-frame{id: dom_id(education)}
= link_to edit_person_education_path(@person, education), data:{turbo_prefetch: :false, turbo_frame: dom_id(education)}, class: "text-decoration-none text-dark bg-hover-gray d-block" do
%div.d-flex.row.pt-3.pb-5
%span.col-3.ps-5
= date_range_label education
%span.col.d-flex.flex-column.text-ms
%span.fw-bolder
= education.title
= education.location
- unless education.display_in_cv
%span.col-1.d-flex.justify-content-end.pe-5
%div{ 'data-bs-toggle': 'tooltip', 'data-bs-title': t("people.show.is_not_displayed_in_cv"), 'data-controller': 'tooltip', 'data-action': 'click->tooltip#hide'}
= image_tag('no-file.svg')
= link_to_if can?(:manage, education), card_content, edit_person_education_path(@person, education), data: { turbo_prefetch: :false, turbo_frame: dom_id(education) }, class: "text-decoration-none text-dark bg-hover-gray d-block"
2 changes: 1 addition & 1 deletion app/views/layouts/person.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
= export_action_link export_cv_person_path(@person), data: { turbo_frame: "remote_modal" }
%li.text-nowrap{ data: { bs_toggle: 'tooltip' }, title: ti('link.export_redhat_tooltip') }
= export_redhat_action_link export_redhat_cv_person_path(@person)
- unless use_ptime_sync?
- unless use_ptime_sync? || !can?(:destroy, @person)
%li.text-nowrap
= destroy_action_link
%turbo-frame#tab-content.d-flex.gap-3{"data-controller": "scroll"}
Expand Down
Loading
Loading