Om Greg
Greg er et kildesystem for registrering av gjester som trenger brukerkonto eller andre digitale identiteter og tilganger. For oppretting av brukerkonto og it-tilganger i Cerebrum, må det settes opp en integrasjon.
Oversikt
For å sette opp en integrasjon med Cerebrum, må man i korte steg:
- Sørge for at Cerebrum er satt opp med støtte for oppgavekøer (Cerebrum.modules.tasks)
- Legge til støtte for Greg i Cerebrum, og implementere forretningsregler for integrasjonen.
- Sette opp og konfigurere integrasjon
Cerebrum.modules.tasks
Integrasjonen trenger støtte for oppgave-kø. Alt som trengs her, er i utgangspunktet databasemodulen mod_tasks.sql dersom denne mangler:
python makedb.py design/mod_tasks.sql
Cerebrum.modules.greg
Integrasjonen trenger egne moduler for lokale tilpasninger i Greg-importen.
Forretningsregler
Cerebrum har en generell, abstrakt Greg-integrasjon. Denne alene er ikke nyttig uten lokale regler for bl.a. oversetting av Greg-rolle til Cerebrum-tilknytning.
Man lager typisk en Cerebrum.modules.no.example.greg_import:
""" Local Greg import logic. """
from __future__ import (
absolute_import,
division,
print_function,
unicode_literals,
)
# from Cerebrum.group import template as _group_template
from Cerebrum.modules.greg import importer as _base_import
from Cerebrum.modules.greg import mapper as _base_mapper
# Consent group(s), if they are needed. See _GregConsents and the
# importer class.
#
# GREG_CONSENT_GROUP = _group_template.GroupTemplate(
# group_name='greg-aktivt-samtykke',
# group_description='Guests who consents to electronic publication',
# group_type='internal-group',
# group_visibility='A',
# )
class _GregOrgunitIds(_base_mapper.GregOrgunitIds):
""" Orgunit-mapper for Greg roles. """
# TODO: Figure out which greg-identifiers to use when mapping org units.
# This depends on which identifies are available from Greg, vs.
# which identifiers we have in Cerebrum
type_map = {
# ('orgreg', 'orgreg_id'): 'ORGREG_OU_ID',
# ('sap', 'legacy_stedkode'): 'NO_SKO',
}
class _GregRoles(_base_mapper.GregRoles):
""" Roles-mapper for Greg. """
# TODO: The institution needs to decide which roles to use in Greg, and
# which affs to give these guests in Cerebrum.
type_map = {
# 'external-consultant': 'TILKNYTTET/ekstern',
# 'external-partner': 'TILKNYTTET/ekstern',
}
# mapper for finding a matching org unit
get_orgunit_ids = _GregOrgunitIds()
class _GregConsents(_base_mapper.GregConsents):
""" Consent-mapper for Greg. """
# TODO: The institution needs to decide which consents to use in Greg,
# and whether or not these consents needs to be represented in
# Cerebrum.
#
# Note: Nothing happens to roles by default, unless there is a
# CONSENT_GROUPS mapping with the target/translated role in the
# importer.
type_map = {
# 'publish': 'greg-publish',
}
class _GregContactInfo(_base_mapper.GregContactInfo):
""" Contact info mapper for Greg. """
# TODO: Does the institution need any custom contact info mappings?
# This module can be omitted if they only need the defaults:
type_map = {
'private_email': 'EMAIL',
'private_mobile': 'PRIVATEMOBILE',
}
class _GregPersonIds(_base_mapper.GregPersonIds):
# TODO: Does the institution need any custom extenal id mappings?
# This module can be omitted if they only need the defaults.
#
# If guests are migrated from another system, we probably want
# some sort of migration id - e.g. employee id of guests that are
# moved from the HR system.
type_map = {
# Example: UiT system-x migration id
# ('system-x', 'migration_id'): 'SYS_X_ID',
# Default mappings:
'norwegian_national_id_number': 'NO_BIRTHNO',
'passport_number': 'PASSNR',
}
class _GregMapper(_base_mapper.GregMapper):
# Assemble the custom mapper by overriding default mappers:
get_affiliations = _GregRoles()
get_consents = _GregConsents()
get_contact_info = _GregContactInfo()
get_person_ids = _GregPersonIds()
class CustomGregImporter(_base_import.GregImporter):
# TODO: If any of these ID-types are missing in Greg, we will refuse to
# create a *new* person to represent the guest, as creating a new
# person with none of these ID-types will almost certainly cause
# duplicates later.
# Remove or keep this section commented out to use this default:
#
# REQUIRED_PERSON_ID = (
# 'NO_BIRTHNO',
# 'PASSNR',
# )
# TODO: If there are duplicates in Cerebrum, we'll try to update the
# person with a matching ID of type MATCH_ID_TYPES. Set
# `MATCH_ID_TYPES = ()` to avoid updating any person when there
# are duplicates.
# Remove or keep this section commented out to use this default:
#
# MATCH_ID_TYPES = (
# 'GREG_PID',
# )
# TODO: If the institution need consents represented as groups, we can
# set that up here.
#
# The key is the normalized/mapped value from _GregConsents,
# while the value is a template for the group to use for that
# consent.
#
# CONSENT_GROUPS = {
# # 'greg-publish': GREG_CONSENT_GROUP,
# }
# Override the default mapper with the custom mapper from this module
mapper = _GregMapper()
Legge til Greg-støtte i cereconf
- Legg til "Cerebrum.modules.greg.constants/GregConstants" i cereconf.CLASS_CONSTANTS
- Legg til "system_greg" et passende sted i prioritetslisten cereconf.SYSTEM_LOOKUP_ORDER. Dette er valgfritt, men uten dette vil ikke forretningslogikk og eksporter ta hensyn til data fra Greg.
- Konfigurerer cereconf.GREG_IMPORT til å peke på institusjonen sin import med lokale forretningsregler (f.eks. GREG_IMPORT = "Cerebrum.modules.no.example.greg_import/CustomGregImporter")
Legge til støtte for Greg-oppgaver i bofhd
Man vil typisk ha kommandoer for innsyn i oppgavekøer, og mulighet for å manuelt legge til oppgaver med bofh.
Dersom institusjonen alt har oppgavekøer, kan det hende at det alt finnes en modul for oppgavekommandoer som kan utvides. Hvis ikke vil man typisk lage en ny, som vil se ut som noe a-la:
# Cerebrum.modules.no.example.bofhd_task_cmds
"""
This module contains task-related commands.
"""
from __future__ import (
absolute_import,
division,
print_function,
unicode_literals,
)
import logging
from Cerebrum.modules.bofhd.help import merge_help_strings
from Cerebrum.modules.greg import bofhd_greg_cmds
from Cerebrum.modules.no.example.bofhd_auth import ExampleAuth
from Cerebrum.modules.tasks import bofhd_task_cmds
logger = logging.getLogger(__name__)
class _CustomTaskAuth(ExampleAuth,
bofhd_greg_cmds.BofhdGregAuth,
bofhd_task_cmds.BofhdTaskAuth):
"""
Modified task auth class.
No changes from the parent classes - this is mainly done to mix in any
auth method overrides from the local institution (ExampleAuth).
"""
class CustomTaskCommands(bofhd_greg_cmds.BofhdGregCommands,
bofhd_task_cmds.BofhdTaskCommands):
"""
Modified task command class.
This also allows for certain overrides, like omitting certain commands
(typically `task_add`), or adding new or modified commands.
The most important thing here, however, is to use the correct authz
class (_CustomTaskAuth).
"""
# All command implementations needs an `all_commands`
all_commands = {}
# Important: This selects the correct authz for commands
authz = _CustomTaskAuth
# We generally want commands from parent classes (task + greg commands)
parent_commands = True
# However, we don't want these specific commands:
omit_parent_commands = (
# Disallow `task_add`, to prevent adding tasks without payload.
# Adding tasks is implemented through queue-specific commands,
# such as `greg import`
'task_add',
)
# If we implement extra commands here, we'd typically need to update the
# help strings:
#
# @classmethod
# def get_help_strings(cls):
# return merge_help_strings(
# super(BofhdTaskCommands, cls).get_help_strings(),
# ({}, {}, {}),
# )
Kommando-modulen må legges inn i bofhd-config for å ta effekt (etc/cerebrum/config.dat).
Konfigurere integrasjon
- Tilgang til Greg-API
- Greg sitt API må eksponeres via en API-gateway.
- Det må opprettes en applikasjon for Cererbum hvis ikke dette alt finnes
- Cerebrum-applikasjonen må få tilgang til API-et.
- API-nøkkel må legges inn i produksjonsmiljøet
- Det må legges inn konfigurasjonsfil for Greg-klienten (se konfigurasjon av greg-klient).
- Tilgang til meldinger
- Greg sitt API må publisere meldinger til en vhost som håndteres av Brom
- Det må opprettes en applikasjon/system i Brom for Cerebrum hvis ikke dette alt finnes (system-production-cerebrum)
- Cerebrum-applikasjonen må abbonnere på meldinger fra Greg (system-production-greg)
- Passord må legges inn i produksjonmiljøet
- Meldingskonsument må konfigureres (se konfigurasjon av consumer)
Konfigurasjon av greg-klient
Greg-klienten må konfigureres for å snakke med riktig API.
Man oppretter typisk en etc/cerebrum/config/greg-client.yml:
url: "https://example.org/greg" auth: "auth-file:greg@example.org"
Konfigurasjon av consumer
Vi trenger en konfigurasjonsfil som kan koble til meldings-broker, konfigurere opp riktig ruting av meldinger, og lytte etter meldinger som skal omgjøres til oppgaver:
Konfigurasjonsfil for consume-tasks.py:
# etc/cerebrum/config/consume-tasks.yml # # Configuration for consumers/consume-tasks.py (crb-consumer.service) # # connection: # host: example.org # port: 5671 # ssl_enable: true # virtual_host: "system-production-cerebrum" # username: system-production-cerebrum # password: "auth-file:system-production-cerebrum@example.org" consumer_tag: crb-consume-tasks # After a connection has been established, our consumer will attempt to set up # any exchanges, queues, or bindings that we configure here: # # exchanges: # # exchange for greg-messages (brom) # - name: "from_system-production-greg" # durable: true # exchange_type: "topic" # queues: # # queue with messages from greg # - name: "greg-import" # durable: true # bindings: # # bind greg queue to all messages from greg # - exchange: "from_system-production-greg" # queue: "greg-import" # routing_keys: # - "#" # Configuration of queue-to-task conversion # # - `source` must be an existing queue, accessable at the given `connnection` # - `get_tasks` must be a function that takes a # `Cerebrum.modules.amqp.handlers:Event` object and converts it to an # iterable of `Cerebrum.modules.tasks.task_model:Task` objects. # # tasks: # - source: "greg-import" # get_tasks: "Cerebrum.modules.greg.tasks:get_tasks"
Merk at Brom setter opp en standardkø, mens eksempelet bruker en egen greg-import-kø. Hvis man følger dette eksempelet, bør man ta bort standardkøen eller bindings til standardkøen slik at denne ikke fylles opp.
Konfigurasjon av systemd
Hvis dette er den første integrasjonen som bruker oppgavekø og meldinger, så må også kjøring av selve consumeren settes opp. En systemd-unit for dette vil typisk se slik ut:
# etc/systemd/crb-consumer.service
[Unit]
Description=Cerebrum MQ task consumer
Wants=network.target network-online.target
After=network.target
[Service]
Type=simple
User=cerebrum
Group=cerebrum
EnvironmentFile=/cerebrum/etc/cerebrum/envvars
PIDFile=/cerebrum/var/run/consumer.pid
ExecStart=/cerebrum/bin/python \
/cerebrum/sbin/consume-tasks.py \
--logger-level=DEBUG \
--dryrun
; Placeholder systemd unit
; TODO: Replace --dryrun with
; --config=/cerebrum/etc/cerebrum/config/consume-tasks.yml \
; --commit
[Install]
WantedBy=multi-user.target
Konfigurasjon av import
Selve importen gjøres ved å regelmessing prosessere oppgavekøen fra Greg regelmessig gjennom job-runner. For dette trenger man en jobb i scheduled_jobs:
class GregImport(Jobs):
""" Class for Greg-related import tasks. """
greg_import_tasks = Action(
call=System(
os.path.join(contrib, "greg/greg-process-tasks.py"),
params=[
"--logger-level", "DEBUG",
"--config", os.path.join(crb_config,
"config/greg-client.yml"),
"--commit",
],
),
health=HealthCheck(
check_overdue=to_seconds(hours=2),
),
when=When(freq=to_seconds(minutes=5)),
max_duration=to_seconds(minutes=30),
)
Konfigurasjon av brukerautomatikk
Hvordan automatikk for oppretting, sperring, og onboarding fungerer, er gjerne ulik fra institusjon til institusjon. Husk å sjekke at hele livsløpet til brukerkontoer fra Greg er ivaretatt!
Det vanligste er:
- Egen jobb for å bygge brukerkonto basert på tilknytning. Hvis Greg-brukere får en ny, tidligere ubrukt tilknytningstype, vil dette typsisk måtte settes opp.
- Egen jobb for sms- og/eller epost-varsling når brukerkonto opprettes. Her finens det som regel en jobb som tar for seg alle brukerkontoer.
- Egen jobb for sperring og/eller avvikling av brukerkonto for personer som mister sine tilknytninger. Her finnes det som regel allerede en jobb som tar for seg alle personer.
Konfigurasjon av tilganger
Enkelte eksporter gjør utplukk basert på tilknytning. Hvis gjester fra Greg gjenbruker eksisterende tilknytningstyper, så trengs det som regel ingen endring (bortett fra SYSTEM_LOOKUP_ORDER nevnt tidligere i dokumentet).
Feide-eksport
LDAP-eksport til Feide har en del regler for utplukk og mapping av tilknytning. Se cereconf.LDAP_PERSON.
Automatiske grupper
For å få bygget automatiske grupper, trenger man:
- Regler for hvilke grupper som kan bygges i cereconf.AUTOMATIC_GROUP_*
- Jobb for bygging av automatiske grupper (populate-automatic-groups.py), med utplukk av hvilke grupperegler som skal bygges.