-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
46a35ec
commit c7b9321
Showing
6 changed files
with
370 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of | ||
# hitobito_sac_cas and licensed under the Affero General Public License version 3 | ||
# or later. See the COPYING file at the top-level directory or at | ||
# https://github.com/hitobito/hitobito_sac_cas | ||
|
||
module SacCas::OidcClaimSetup | ||
|
||
extend ActiveSupport::Concern | ||
|
||
PHONE_NUMBER_LABEL = 'Haupt-Telefonnummer'.freeze | ||
INFERRED_ROLE_LABLES = { | ||
section_functionary: Group::SektionsFunktionaere.roles, | ||
section_president: [Group::SektionsFunktionaere::Praesidium], | ||
SAC_employee: Group::Geschaeftsstelle.roles, | ||
SAC_management: Group::Geschaeftsleitung.roles, | ||
SAC_member: [Group::SektionsMitglieder::Mitglied], | ||
SAC_member_additional: [Group::SektionsMitglieder::MitgliedZusatzsektion], | ||
SAC_central_board_member: Group::Zentralvorstand.roles, | ||
SAC_commission_member: Group::Kommission.roles, | ||
SAC_tourenportal_subscriber: Group::AboTourenPortal.roles, | ||
section_commission_member: Group::SektionsKommission.roles, | ||
huts_functionary: Group::SektionsHuettenkommission.roles, | ||
tourenportal_author: [Group::AboTourenPortal::Autor], | ||
tourenportal_community: [Group::AboTourenPortal::Community], | ||
tourenportal_administrator: [Group::AboTourenPortal::Admin], | ||
magazin_subscriber: Group::AboMagazin.roles, | ||
section_tour_functionary: Group::SektionsTourenkommission.roles, | ||
} | ||
|
||
def run | ||
super | ||
|
||
add_claim(:picture_url, scope: [:name, :with_roles]) do |owner| | ||
owner.decorate.picture_full_url | ||
end | ||
|
||
add_claim(:phone_number, scope: [:name, :with_roles]) do |owner| | ||
phone_number(owner) | ||
end | ||
|
||
add_claim(:membership_years, scope: :with_roles) | ||
add_claim(:user_groups, scope: :with_groups) do |owner| | ||
inferred_role_strings(owner) + formatted_active_roles(owner) | ||
end | ||
end | ||
|
||
private | ||
|
||
def inferred_role_strings(owner) | ||
INFERRED_ROLE_LABLES.select do |_, roles| | ||
(owner.roles.map(&:class) & roles).any? | ||
end.keys.map(&:to_s) | ||
end | ||
|
||
def formatted_active_roles(owner) | ||
owner.roles.map { |r| "#{r.type}##{r.group_id}" } | ||
end | ||
|
||
def phone_number(owner) | ||
owner.phone_numbers.order(:id).find_by(label: PHONE_NUMBER_LABEL)&.number | ||
end | ||
|
||
def membership_years(owner) | ||
Person.with_membership_years.find_by(id: owner.id).membership_years | ||
end | ||
|
||
def section_functionary(owner) | ||
owner.roles.any? | ||
end | ||
|
||
def section_president(owner) | ||
owner.roles.any? { |r| } | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# frozen_string_literal: true | ||
|
||
# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of | ||
# hitobito_sac_cas and licensed under the Affero General Public License version 3 | ||
# or later. See the COPYING file at the top-level directory or at | ||
# https://github.com/hitobito/hitobito_sac_cas | ||
|
||
require 'spec_helper' | ||
|
||
describe OidcClaimSetup do | ||
let(:owner) { people(:admin) } | ||
let(:response) { :user_info } | ||
let(:token) { Doorkeeper::AccessToken.new(resource_owner_id: owner.id, scopes: scope) } | ||
let(:claim_keys) { claims.stringify_keys.keys } | ||
|
||
subject(:claims) { Doorkeeper::OpenidConnect::ClaimsBuilder.generate(token, response) } | ||
|
||
shared_examples 'shared claims' do | ||
describe 'phone_number' do | ||
it 'is blank when no matching number exists' do | ||
expect(claim_keys).to include('phone_number') | ||
end | ||
|
||
it 'returns first number with matching label' do | ||
owner.phone_numbers.create!(label: 'Haupt-Telefonnummer', number: '0791234560') | ||
owner.phone_numbers.create!(label: 'Haupt-Telefonnummer', number: '0791234561') | ||
expect(claims[:phone_number]).to eq '+41 79 123 45 60' | ||
end | ||
end | ||
end | ||
|
||
context 'name' do | ||
let(:scope) { :name } | ||
|
||
it 'picture_url is present' do | ||
expect(claims[:picture_url]).to eq owner.decorate.picture_full_url | ||
end | ||
|
||
it_behaves_like 'shared claims' | ||
end | ||
|
||
context 'with_roles' do | ||
let(:scope) { :with_roles } | ||
|
||
describe 'membership_years'do | ||
it 'is blank when no matching number exists' do | ||
expect(claim_keys).to include('membership_years') | ||
end | ||
|
||
it 'is blank when no matching number exists' do | ||
expect(claims[:membership_years]).to eq 0 | ||
end | ||
end | ||
it_behaves_like 'shared claims' | ||
end | ||
|
||
context 'with_groups' do | ||
let(:role) { roles(:admin) } | ||
let(:scope) { :with_groups } | ||
let(:user_groups) { claims[:user_groups] } | ||
|
||
def create_role(key, role) | ||
group = key.is_a?(Group) ? key : groups(key) | ||
role_type = group.class.const_get(role) | ||
Fabricate(role_type.sti_name, group: group, person: owner) | ||
end | ||
|
||
it 'includes SAC_employee key when matching role exists' do | ||
expect(user_groups).to include 'SAC_employee' | ||
expect(user_groups).to include 'Group::Geschaeftsstelle::Admin#384133472' | ||
end | ||
|
||
it 'includes section_functionary key when matching role exists' do | ||
role = create_role(:bluemlisalp_funktionaere, 'AdministrationReadOnly') | ||
expect(user_groups).to include "section_functionary" | ||
expect(user_groups).to include "Group::Geschaeftsstelle::Admin#384133472" | ||
expect(user_groups).to include format('%s#%d' % [role.type, role.group_id]) | ||
end | ||
|
||
it 'includes section_president key when matching role exists' do | ||
role = create_role(:bluemlisalp_funktionaere, 'Praesidium') | ||
expect(user_groups).to include 'section_president' | ||
end | ||
|
||
it 'includes SAC_management key when matching role exists' do | ||
group = Fabricate(Group::Geschaeftsleitung.sti_name, parent: groups(:root)) | ||
|
||
role = create_role(group, 'Ressortleitung') | ||
expect(user_groups).to include 'SAC_management' | ||
end | ||
|
||
it 'includes SAC_member key when matching role exists' do | ||
role = create_role(:bluemlisalp_mitglieder, 'Mitglied') | ||
expect(user_groups).to include 'SAC_member' | ||
expect(user_groups).not_to include 'SAC_member_additional' | ||
end | ||
|
||
it 'includes SAC_member key when matching role exists' do | ||
create_role(:bluemlisalp_mitglieder, 'Mitglied') | ||
role = create_role(:matterhorn_mitglieder, 'MitgliedZusatzsektion') | ||
expect(user_groups).to include 'SAC_member' | ||
expect(user_groups).to include 'SAC_member_additional' | ||
end | ||
|
||
it 'includes SAC_central_board_member key when matching role exists' do | ||
group = Fabricate(Group::Zentralvorstand.sti_name, parent: groups(:root)) | ||
create_role(group, 'Praesidium') | ||
expect(user_groups).to include 'SAC_central_board_member' | ||
end | ||
|
||
it 'includes SAC_central_board_member key when matching role exists' do | ||
group = Fabricate(Group::Kommission.sti_name, parent: groups(:root)) | ||
create_role(group, 'Praesidium') | ||
expect(user_groups).to include 'SAC_commission_member' | ||
end | ||
|
||
it 'includes SAC_tourenportal_subscriber key when matching role exists' do | ||
group = Fabricate(Group::AboTourenPortal.sti_name, parent: groups(:abonnenten)) | ||
create_role(group, 'Autor') | ||
expect(user_groups).to include 'SAC_tourenportal_subscriber' | ||
end | ||
|
||
it 'includes section_commission_member key when matching role exists' do | ||
group = Fabricate(Group::SektionsKommission.sti_name, parent: groups(:bluemlisalp)) | ||
create_role(group, 'Mitglied') | ||
expect(user_groups).to include 'section_commission_member' | ||
end | ||
|
||
it 'includes huts_functionary key when matching role exists' do | ||
group = Fabricate(Group::SektionsHuettenkommission.sti_name, parent: groups(:bluemlisalp)) | ||
create_role(group, 'Huettenobmann') | ||
expect(user_groups).to include 'huts_functionary' | ||
end | ||
|
||
it 'includes tourenportal_author key when matching role exists' do | ||
group = Fabricate(Group::AboTourenPortal.sti_name, parent: groups(:abonnenten)) | ||
create_role(group, 'Autor') | ||
expect(user_groups).to include 'tourenportal_author' | ||
end | ||
|
||
it 'includes tourenportal_community key when matching role exists' do | ||
group = Fabricate(Group::AboTourenPortal.sti_name, parent: groups(:abonnenten)) | ||
create_role(group, 'Community') | ||
expect(user_groups).to include 'tourenportal_community' | ||
end | ||
|
||
it 'includes tourenportal_community key when matching role exists' do | ||
group = Fabricate(Group::AboTourenPortal.sti_name, parent: groups(:abonnenten)) | ||
create_role(group, 'Community') | ||
expect(user_groups).to include 'tourenportal_community' | ||
end | ||
|
||
it 'includes tourenportal_administrator key when matching role exists' do | ||
group = Fabricate(Group::AboTourenPortal.sti_name, parent: groups(:abonnenten)) | ||
create_role(group, 'Admin') | ||
expect(user_groups).to include 'tourenportal_administrator' | ||
end | ||
|
||
it 'includes magazin_subscriber key when matching role exists' do | ||
group = Fabricate(Group::AboMagazin.sti_name, parent: groups(:abonnenten)) | ||
create_role(group, 'Andere') | ||
expect(user_groups).to include 'magazin_subscriber' | ||
end | ||
|
||
it 'includes section_tour_functionary key when matching role exists' do | ||
create_role(:bluemlisalp_ortsgruppe_ausserberg_tourenkommission, 'JoChef') | ||
expect(user_groups).to include 'section_tour_functionary' | ||
end | ||
end | ||
end |
Oops, something went wrong.