Добавляем в концепцию Сотрудник‑Трудоустройство‑Назначение на должность концепцию Проекты. Допустим что у нас нет источника где написано у кого какой проект, и мы не можем их создать из ресурса и развесить как делали это с трудоустройствами и назначениями. Пусть у нас будет динамическое, даже автономно‑персональное, создание проекта и управления правами и участниками проекта. Проект в философском смысле это всего лишь — управление членами проекта, и правами проекта.

Начальник заходит в свой GUI Midpoint, создает Проект. В Request Access запрашивает на проект роли. Там же на своих подчинённых и себя запрашивает‑выдаёт роль Проект. Может на Проект запрашивать роль которая создает специально под проект роль (создающая AD группу например), которую можно выдать проекту и она будет у всех участников проекта, или выдать только конкретному участнику проекта. Можно убрать роль или сотрудника из проекта, права пришедшие с проектом и специальные роли проекта при этом у сотрудника снимутся.
Простая схема

У сотрудник User есть роль дающая право создавать в GUI проекты Role.
При создание роли проект N001 Role сразу создаётся проект N001 User и назначает себе проект N001 Role.
Сотрудник (начальник) в Request Access cебе, на назначение Position User, или подчиненным на их User Position выдает роль Проект N001 Role.
Сотрудник (начальник) в Request Access запрашивает роли Forward Role(которые передают информацию что должно быть у получателя прав, проект не получатель прав, получателем будет учетка AD на позции User или трудоустройстве User) на проект N001 User.
Там же можно выдать проект N001 User роль которая создаст роль специально для этого проекта, которая создаст системную роль(если её нет).
6. Эту роль можно назначить проекту N001 User или назначению Position User. На роли политика которая не дает назначить роль если у получателя нет роль Проект N001 Role, и снимает её если у носителя пропадает роль Проект N001 Role.
Полнейшая схема

Окончательный код на Github: IDM-Midpoint-POC-Employments-and-Positions
Docker-образ: IDM-Midpoint-POC-Employments-and-Positions/tree/main/Docker
Перед началом
Вынужден прискорбно признать что orgRelation ну никак не работает в Midpoint 4.9.1, или я все таки не угадал как ими можно пользоваться, что тоже может быть конечно. В 3-тей части концепции Сотрудник‑Трудоустройство‑Назначение на должность он хотя бы ошибочно казался работающим, но сейчас вообще никак! А в Midpoint 4.9.2–3 перестали работать фильтры в targetSelection group collection поэтому все еще на 4.9.1.
Так что переделываем авторизацию для роли POCE GUI My Subordinates, фулстори не будет но идея такая в User назначение на должность один департамент один признак — начальник да/нет. В его список с Forward Roles пишем строку DEPARTMENT|EMP001 001|DEP10 101|POS000 101|EMP002 001|600 667|default или manager. Org Роль Departament забирает её и пишет в себя мой босс такой‑то и User назначение забирает это в себя и пишет мой босс такой‑то. Просто и понятно.
Переходим к добавлению концепции Проекты в концепцию Сотрудник-Трудоустройство-Назначение на должность
Добавляем пару атрибутов. Кладем файл project.xsd в /opt/midpoint/var/schema/
с кодом
<xsd:schema elementFormDefault="qualified"
targetNamespace="http://example.com/xml/ns/mySchema"
xmlns:tns="http://example.com/xml/ns/mySchema"
xmlns:a="http://prism.evolveum.com/xml/ns/public/annotation-3"
xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="RoleExtensionType">
<xsd:annotation>
<xsd:appinfo>
<a:extension ref="c:RoleType"/>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="role_active" type="xsd:boolean" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:appinfo>
<a:indexed>true</a:indexed>
<a:displayName>Active</a:displayName>
<a:displayOrder>1</a:displayOrder>
<a:help>ToDo</a:help>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="OrgExtensionType">
<xsd:annotation>
<xsd:appinfo>
<a:extension ref="c:OrgType"/>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="org_boss" type="xsd:string" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:appinfo>
<a:indexed>true</a:indexed>
<a:displayName>Org Bosses</a:displayName>
<a:displayOrder>138</a:displayOrder>
<a:help>ToDo</a:help>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Перзапускаем Midpoint
В Configuration\Import Object вставляем
код
<sequence xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3">
<name>Projects number</name>
<counter>1</counter>
<maxCounter>999999</maxCounter>
<allowRewind>true</allowRewind>
<maxUnusedValues>10</maxUnusedValues>
</sequence>
Это счетчик начинается с 1 идет до 999999 для name в проектах
В Configuration\Object Template\ создаем обжект темплейт POCP EMP001001 Project Role Object Template
в нем код
<item id="104">
<ref>assignment</ref>
<displayName>Auto assignment to POCP EMP001001 Person Project User from Project Role</displayName>
<mapping id="9">
<authoritative>true</authoritative>
<strength>strong</strength>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<oid>a9291b83-3b40-4581-91c8-63f05410ed63</oid>
</assignmentTargetSearch>
</expression>
</mapping>
</item>
<item id="105">
<ref>assignment</ref>
<displayName>Auto assignment to POCP Policy: Project Role only for Project User or Position User</displayName>
<mapping id="9">
<authoritative>true</authoritative>
<strength>strong</strength>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<oid>c35b6362-1f81-4f87-917b-1921a984fb54</oid>
</assignmentTargetSearch>
</expression>
</mapping>
</item>
<item id="5">
<ref>assignment</ref>
<displayName>Assignment to Position Role Catalog</displayName>
<mapping id="9">
<name>Name</name>
<source>
<path xmlns:gen569="http://example.com/xml/ns/mySchema">
c:extension/gen569:user_employment_parent</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>OrgType</targetType>
<filter>
<q:equal>
<q:path>identifier</q:path>
<expression>
<trace>true</trace>
<script>
<code>result = "\\RC\\" + user_employment_parent + "\\" + "Position"
return result</code>
</script>
</expression>
</q:equal>
</filter>
</assignmentTargetSearch>
</expression>
</mapping>
</item>
<item id="16">
<ref>assignment</ref>
<displayName>Auto assignment to POCE Policy: Forward Role for Employment in EMP01001 Company</displayName>
<mapping id="9">
<authoritative>true</authoritative>
<strength>strong</strength>
<source>
<_metadata id="19">
<provenance>
<acquisition id="20">
<actorRef oid="00000000-0000-0000-0000-000000000002" relation="org:default"
type="c:UserType">
<!-- administrator -->
</actorRef>
<channel>http://midpoint.evolveum.com/xml/ns/public/common/channels-3#user</channel>
<timestamp>2025-03-24T10:12:58.273Z</timestamp>
</acquisition>
</provenance>
</_metadata>
<path xmlns:gen569="http://example.com/xml/ns/mySchema">
c:extension/gen569:user_employment_parent</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<oid>8e4b4ea4-22b7-4b09-98ce-aa8fd5ace849</oid>
</assignmentTargetSearch>
</expression>
<condition>
<script>
<code>if (user_employment_parent == "EMP001001")
{return true}
else{return false}</code>
</script>
</condition>
</mapping>
</item>
<item id="17">
<ref>assignment</ref>
<displayName>Auto assignment to POCE Policy: Forward Role for Employment in EMP01002 Company</displayName>
<mapping id="9">
<authoritative>true</authoritative>
<strength>strong</strength>
<source>
<_metadata id="19">
<provenance>
<acquisition id="20">
<actorRef oid="00000000-0000-0000-0000-000000000002" relation="org:default"
type="c:UserType">
<!-- administrator -->
</actorRef>
<channel>http://midpoint.evolveum.com/xml/ns/public/common/channels-3#user</channel>
<timestamp>2025-03-24T10:12:58.273Z</timestamp>
</acquisition>
</provenance>
</_metadata>
<path xmlns:gen569="http://example.com/xml/ns/mySchema">
c:extension/gen569:user_employment_parent</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<oid>047dcf56-3555-4940-aac4-50b15b9071a3</oid>
</assignmentTargetSearch>
</expression>
<condition>
<script>
<code>if (user_employment_parent == "EMP001002")
{return true}
else{return false}</code>
</script>
</condition>
</mapping>
</item>
<mapping id="4">
<name>000</name>
<strength>weak</strength>
<expression>
<script>
<code>return actor.personalNumber</code>
</script>
</expression>
<target>
<path xmlns:gen74="http://example.com/xml/ns/mySchema">c:extension/gen74:user_boss</path>
</target>
</mapping>
<mapping id="13">
<name>001</name>
<strength>strong</strength>
<source>
<_metadata id="17">
<provenance>
<acquisition id="18">
<actorRef oid="00000000-0000-0000-0000-000000000002" relation="org:default"
type="c:UserType">
<!-- administrator -->
</actorRef>
<channel>http://midpoint.evolveum.com/xml/ns/public/common/channels-3#user</channel>
<timestamp>2025-05-08T12:21:58.394Z</timestamp>
</acquisition>
</provenance>
</_metadata>
<path>c:name</path>
</source>
<expression>
<script>
<code>
return "PRJ" +
basic.stringify(midpoint.getSequenceCounter("c725fbca-2392-45a1-83ff-91f5e3fd989a")).padLeft(6,'0')</code>
</script>
</expression>
<target>
<path>c:name</path>
</target>
<condition>
<script>
<code>if (basic.isEmpty(name))
{return true}
else
{
if (name.startsWith("PRJ"))
{return false}
else
{return true}
}</code>
</script>
</condition>
</mapping>
<mapping id="21">
<name>002</name>
<strength>weak</strength>
<expression>
<script>
<code>return "EMP001001"</code>
</script>
</expression>
<target>
<path xmlns:gen569="http://example.com/xml/ns/mySchema">
c:extension/gen569:user_employment_parent</path>
</target>
</mapping>
<mapping id="107">
<name>003</name>
<lifecycleState>active</lifecycleState>
<expression>
<script>
<code>return true</code>
</script>
</expression>
<target>
<path>c:indestructible</path>
</target>
</mapping>
<mapping id="31">
<name>004</name>
<expression>
<script>
<code>return "Positions and Projects"</code>
</script>
</expression>
<target>
<path xmlns:gen158="http://example.com/xml/ns/mySchema">c:extension/gen158:role_purpose_type</path>
</target>
</mapping>
<mapping id="118">
<name>005</name>
<strength>strong</strength>
<source>
<path>c:name</path>
</source>
<source>
<path>c:identifier</path>
</source>
<source>
<path>c:extension/role_active</path>
</source>
<expression>
<script>
<code>
if (role_active)
{
return name + ": " + identifier
}
else
{
return "[DEACTIVATED] " + name + ": " + identifier
}
</code>
</script>
</expression>
<target>
<path>c:displayName</path>
</target>
</mapping>
item по названиям понятно для чего
mapping 4 — пишем в роль проект в user_boss того кто его создает(потом сюда можно будет добавить еще кого‑то)
mapping 13 — создаем name вызываем созданный ранее счетчик по OID
mapping 21 — пишем identifier роли компании это для item 23, по умолчанию всегда будет основная компания но можно будет менять
В Configuration\ArchyTypes создаем архетип под названием POCP EMP001 001 Project Role ArcheType
в нем код
<archetypePolicy>
<display>
<label>Project EMP001001</label>
<singularLabel>Project EMP001001</singularLabel>
<pluralLabel>Projects EMP001001</pluralLabel>
<icon>
<cssClass>fa fa-briefcase-clock</cssClass>
<color>#d88222</color>
</icon>
</display>
...
<links>
<targetLink id="16">
<name>from Company to Project</name>
<selector>
<type>c:RoleType</type>
<archetypeRef oid="f44dc355-31d3-499b-9854-e0ae277a60dc" relation="org:default"
type="c:ArchetypeType">
<!-- POCE Company Role ArcheType -->
</archetypeRef>
</selector>
</targetLink>
</links>
</archetypePolicy>
Тут сразу создаем TargetLink в POCE Company Role ArcheType
и код
<inducement id="18">
<focusMappings>
<mapping id="7">
<name>to costCenter</name>
<documentation>displayName from Company Role</documentation>
<authoritative>false</authoritative>
<strength>strong</strength>
<expression>
<script>
<code>
linkedDATA = midpoint.findLinkedTarget('from Company to Project')
return linkedDATA.displayName
</code>
</script>
</expression>
<target>
<path>costCenter</path>
</target>
<condition>
<script>
<code>linkedDATA = midpoint.findLinkedTarget('from Company to Project')
if (basic.isEmpty(linkedDATA))
{return false}
else{return !basic.isEmpty(linkedDATA.displayName)}</code>
</script>
</condition>
</mapping>
</focusMappings>
</inducement>
В архетипе POCE Company Role ArcheType также добавляем
<inducement id="13">
<policyRule>
<name>Recompute Project Role on displayname change</name>
<policyConstraints>
<or id="13">
<modification id="14">
<item>c:displayName</item>
</modification>
</or>
</policyConstraints>
<policyActions>
<scriptExecution id="16">
<object>
<linkSource id="40">
<name>Company to Project</name>
</linkSource>
</object>
<executeScript xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
<s:recompute />
</executeScript>
</scriptExecution>
</policyActions>
</policyRule>
</inducement>
...
<archetypePolicy>
...
<links>
...
<sourceLink id="51">
<name>Company to Project</name>
<selector>
<type>c:RoleType</type>
<archetypeRef oid="49952180-49a0-4884-a8d1-5e1a50f26fa1" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project Role ArcheType -->
</archetypeRef>
</selector>
</sourceLink>
</links>
</archetypePolicy>
</archetype>
Рекомпутить роли проекты которые в ассаимент если менется displayName.
Из под админа роль создается, name заполнять ненадо или даже нельзя потому что он генерится.
Теперь нам надо чтобы эта роль делала User Проект. В Configuration\Object Template\ создаем обжект темплейт POCP EMP001001 Person Project User from Project Role Object Template
в нем код
<mapping id="2">
<name>01</name>
<source>
<path>c:name</path>
</source>
<expression />
<target>
<path>c:name</path>
</target>
</mapping>
<mapping id="4">
<name>02</name>
<source>
<path xmlns:gen56="http://example.com/xml/ns/mySchema">c:extension/gen56:user_boss</path>
</source>
<expression />
<target>
<path>c:extension/person_boss</path>
</target>
</mapping>
<mapping id="14">
<name>03</name>
<source>
<path>c:extension/user_employment_parent</path>
</source>
<expression />
<target>
<path>c:organization</path>
</target>
</mapping>
<mapping id="15">
<name>04</name>
<source>
<path>c:displayName</path>
</source>
<expression>
<script>
<code>return displayName</code>
</script>
</expression>
<target>
<path>c:fullName</path>
</target>
</mapping>
<mapping id="21">
<name>05</name>
<source>
<path>c:costCenter</path>
</source>
<expression />
<target>
<path>c:costCenter</path>
</target>
</mapping>
<mapping id="22">
<name>06</name>
<source>
<path>c:description</path>
</source>
<expression />
<target>
<path>c:description</path>
</target>
</mapping>
<mapping id="23">
<name>07</name>
<source>
<path>c:documentation</path>
</source>
<expression />
<target>
<path>c:documentation</path>
</target>
</mapping>
В Configuration\ArchyTypes создаем архетип под названием POCP EMP001001 Project User ArcheType.
в нем код
...
<archetypePolicy>
<display>
<icon>
<cssClass>fa fa-briefcase-clock</cssClass>
<color>#2d860a</color>
</icon>
</display>
</archetypePolicy>
</archetype>
В Configuration\Object Template\ создаем обжект темплейт POCP EMP001001 Project User Object Template.
в нем код
<item id="3">
<ref>assignment</ref>
<displayName>Assignment to Company Role</displayName>
<mapping id="9">
<source>
<path>organization</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<filter>
<q:text>identifier = $organization and archetypeRef matches (oid =
"f44dc355-31d3-499b-9854-e0ae277a60dc")</q:text>
</filter>
</assignmentTargetSearch>
</expression>
</mapping>
</item>
<item id="4">
<ref>assignment</ref>
<displayName>Assignment to Project Role</displayName>
<mapping id="9">
<source>
<path>name</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<filter>
<q:text>name = $name and archetypeRef matches (oid =
"49952180-49a0-4884-a8d1-5e1a50f26fa1")</q:text>
</filter>
</assignmentTargetSearch>
</expression>
</mapping>
</item>
В POCP EMP001001 Project User ArcheType в Object template reference утыкаем в этот обжект темплейт.
Пробуем, создаем Проект роль из под администратора

Заполняем только три атрибута. Название проект пишем в Identifier так надо!
Создался Проект Role

И проект User

Для продолжения создадим Forward роли под проекты.
Создам черну роль под названием POCP Policy: Forward Role only for Project User в ней код
<inducement id="30">
<policyRule>
<name>Member must have archetype POCP EMP001001 Project User ArcheType</name>
<policyConstraints>
<requirement id="31">
<targetRef oid="c2523d38-76ed-43bc-9e73-5158ed225042" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project User ArcheType -->
</targetRef>
</requirement>
</policyConstraints>
<policyActions>
<enforcement>
<name>Enf</name>
</enforcement>
</policyActions>
<evaluationTarget>assignment</evaluationTarget>
</policyRule>
</inducement>
Тут реф на архетип POCP EMP001001 Project User ArcheTyp.
Создаем черную роль POCP Policy: Project Role only for Project User or Position User
в ней код
<inducement id="30">
<policyRule>
<name>Member must have archetype POCE Position User ArcgeType or POCP EMP001001 Project Role
ArcheType</name>
<policyConstraints>
<or id="43">
<requirement id="44">
<name>02</name>
<targetRef oid="c2523d38-76ed-43bc-9e73-5158ed225042" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project User ArcheType -->
</targetRef>
</requirement>
</or>
<or id="435">
<requirement id="433">
<name>01</name>
<targetRef oid="0d1b1269-0011-49e6-b9f1-e62e7827dfed" relation="org:default"
type="c:ArchetypeType">
<!-- POCE Position User ArcheType -->
</targetRef>
</requirement>
</or>
</policyConstraints>
<policyActions>
<enforcement>
<name>Enf</name>
</enforcement>
</policyActions>
<evaluationTarget>assignment</evaluationTarget>
</policyRule>
</inducement>
Тут реф на архетип POCP EMP001001 Project User ArcheTyp.
В Configuration\Object Template\ в POCE Forward Role Object Template добавляем
<item id="105">
<ref>assignment</ref>
<displayName>Auto assignment to POCP Policy: Project Role only for Project User or Position User</displayName>
<mapping id="9">
<authoritative>true</authoritative>
<strength>strong</strength>
<source>
<path xmlns:gen569="http://example.com/xml/ns/mySchema">c:extension/gen569:role_purpose_type</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<oid>c35b6362-1f81-4f87-917b-1921a984fb54</oid>
</assignmentTargetSearch>
</expression>
<condition>
<script>
<code>if (role_purpose_type == "Positions and Projects")
{return true}
else{return false}</code>
</script>
</condition>
</mapping>
</item>
<item id="115">
<ref>assignment</ref>
<displayName>Auto assignment to POCE Policy: Forward Role only for Project User</displayName>
<mapping id="9">
<authoritative>true</authoritative>
<strength>strong</strength>
<source>
<path xmlns:gen569="http://example.com/xml/ns/mySchema">c:extension/gen569:role_purpose_type</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<oid>5fd6a8c5-7d61-4314-a37c-a5975717b1cf</oid>
</assignmentTargetSearch>
</expression>
<condition>
<script>
<code>
if (role_purpose_type == "Project")
{return true}
else{return false}
</code>
</script>
</condition>
</mapping>
</item>
Все роли будут из Windows MS AD так что накидываю там групп, а еще создаю в роль каталоге Positions в OOO ODN и запускаю реконсиляцию ресурса Windows MS AD OOO ODIN Forward Roles, в созданных ролях меняю Porpuse Type на Project и получаю следующие роли.

Да и делаем реконсиляцию MS AD group в Windows MS AD OOO ODIN.
Роль можно назначать, они запишут в User Проэкт в Forwerd roles что нужно выдавать! Но это надо дальше протащить в User Назначение на должность.
В Configuration\ArchyTypes в архетип под названием POCP EMP001001 Project Role ArcheType.
добавляем код
<sequence xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3">
<name>Projects number</name>
<counter>1</counter>
<maxCounter>999999</maxCounter>
<allowRewind>true</allowRewind>
<maxUnusedValues>10</maxUnusedValues>
</sequence>
A в Configuration\ArchyTypes в архетип под названием POCP EMP001001 Project Role ArcheType.
добавляем код
...
<inducement id="1222">
<policyRule>
<name>Recompute Project Role on Project User Forward Roles change</name>
<policyConstraints>
<or id="13">
<modification id="3344">
<item xmlns:gen26="http://example.com/xml/ns/mySchema">
c:extension/gen26:person_forward_roles</item>
</modification>
</or>
</policyConstraints>
<policyActions>
<scriptExecution id="16">
<object>
<linkTarget id="17">
<linkType>from Project User to Project Role</linkType>
</linkTarget>
</object>
<executeScript xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
<s:recompute />
</executeScript>
<privileges>
<runPrivileged>true</runPrivileged>
</privileges>
</scriptExecution>
</policyActions>
</policyRule>
</inducement>
...
<archetypePolicy>
...
<links>
<targetLink id="7">
<name>from Project User to Project Role</name>
<selector>
<type>c:RoleType</type>
<archetypeRef oid="49952180-49a0-4884-a8d1-5e1a50f26fa1" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project Role ArcheType -->
</archetypeRef>
</selector>
</targetLink>
</links>
</archetypePolicy>
</archetype>
Вкачалоcь в роль Project, которая когда то будет назначена User Назначений, через назначение этого Назначений в Проект role... и в этот момент надо в User Назначений вкачать Forward роли из роли Проекта! Пока вообще все просто, не представляете какой финт будет дальше!
В Configuration\ArchyTypes в архетип под названием POCE Position User ArcheType
добавляем код
...
<inducement id="12222">
<focusMappings>
<mapping id="8">
<name>01</name>
<authoritative>false</authoritative>
<exclusive>true</exclusive>
<strength>strong</strength>
<expression>
<script>
<code>
fr_list = []
fr_postion_roles = midpoint.findLinkedTargets('From Project Role to Position
User').collect { basic.getExtensionPropertyValues(it,
"http://example.com/xml/ns/mySchema", "user_forward_roles")}
for (i in fr_postion_roles)
{
fr_num = 0
for(ii in i)
{
if (ii.startsWith("NO CONNECTION"))
fr_num = 1
}
if (fr_num !=1)
{for (ii in i){fr_list.add(ii)}}
}
return fr_list
</code>
</script>
</expression>
<target>
<path>extension/person_forward_roles_inherited</path>
</target>
</mapping>
</focusMappings>
</inducement>
...
<archetypePolicy>
...
<links>
...
</targetLink>
<targetLink id="300085">
<name>From Project Role to Position User</name>
<selector>
<type>c:RoleType</type>
<archetypeRef oid="49952180-49a0-4884-a8d1-5e1a50f26fa1" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project Role ArcheType -->
</archetypeRef>
</selector>
</targetLink>
</links>
</archetypePolicy>
</archetype>
А в Configuration\ArchyTypes в архетип под названием POCP EMP001001 Project Role ArcheType.
добавляем код
...
<inducement id="1234">
<policyRule>
<name>Recompute Users Position</name>
<policyConstraints>
<or id="13">
<modification id="22">
<item xmlns:gen365="http://example.com/xml/ns/mySchema">
c:extension/gen365:user_forward_roles</item>
</modification>
</or>
</policyConstraints>
<policyActions>
<scriptExecution id="16">
<object>
<linkSource id="131">
<name>from Position User to me</name>
</linkSource>
</object>
<executeScript xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
<s:recompute />
</executeScript>
<privileges>
<runPrivileged>true</runPrivileged>
</privileges>
</scriptExecution>
</policyActions>
</policyRule>
</inducement>
...
<archetypePolicy>
...
<sourceLink id="1227">
<name>from Position User to me</name>
<selector>
<type>c:RoleType</type>
<archetypeRef oid="0d1b1269-0011-49e6-b9f1-e62e7827dfed" relation="org:default"
type="c:ArchetypeType">
<!-- POCE Position User ArcheType -->
</archetypeRef>
</selector>
</sourceLink>
...
</links>
</archetypePolicy>
</archetype>
В User назначение в Forward Roles Inherited попадает, но для случая учетка AD на User Назначение надо править.
В Configuration\Object Template\ в POCE Person Position MS AD Account Object Template.
в нем код
<mapping id="13">
<name>10</name>
<exclusive>true</exclusive>
<source>
<path>c:extension/person_forward_roles</path>
</source>
<source>
<path>c:extension/person_forward_roles_inherited</path>
</source>
<expression>
<script>
<relativityMode>absolute</relativityMode>
<code>
result = []
for (i in person_forward_roles)
{
if (i.startsWith("MSAD"))
{ii = i.tokenize( '|' )
result.add(ii[2])}
}
for (i in person_forward_roles_inherited)
{
if (i.startsWith("MSAD"))
{ii = i.tokenize( '|' )
result.add(ii[2])
}
return result.unique()</code>
</script>
</expression>
<target>
<path>c:extension/person_forward_roles</path>
</target>
</mapping>
Идем дальше, тащим дальше в Трудоустройство.
А в Configuration\ArchyTypes в архетипе POCE Position User ArcheType.
редактируем до вида
<inducement id="1222">
<policyRule>
<name>Recompute Position Role on Position User Forward Roles change</name>
<policyConstraints>
<or id="13">
<modification id="3342">
<item>c:activation/c:administrativeStatus</item>
</modification>
<modification id="3344">
<item xmlns:gen26="http://example.com/xml/ns/mySchema">
c:extension/gen26:person_forward_roles</item>
</modification>
<modification id="300087">
<item xmlns:gen26="http://example.com/xml/ns/mySchema">
c:extension/gen26:person_forward_roles_inherited</item>
</modification>
</or>
</policyConstraints>
<policyActions>
<scriptExecution id="16">
<object>
<linkTarget id="17">
<linkType>From Position Role to Position User</linkType>
</linkTarget>
</object>
<executeScript xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
<s:recompute />
</executeScript>
<privileges>
<runPrivileged>true</runPrivileged>
</privileges>
</scriptExecution>
</policyActions>
</policyRule>
</inducement>
А в Configuration\ArchyTypes в архетипе POCE Position Role ArcheType.
редактируем код
<inducement id="1226">
<focusMappings>
<mapping id="7">
<name>11</name>
<documentation>get Forward Roles from user</documentation>
<authoritative>true</authoritative>
<strength>strong</strength>
<expression>
<script>
<code>linkedDATA = midpoint.findLinkedSource('from me Position Role to Position User')
if (basic.isEmpty(linkedDATA))
{return "NO CONNECTION"}
else
{
f1 = basic.getExtensionPropertyValues(linkedDATA, "http://example.com/xml/ns/mySchema",
"person_forward_roles")
f2 = basic.getExtensionPropertyValues(linkedDATA, "http://example.com/xml/ns/mySchema",
"person_forward_roles_inherited")
f1 += f2
return f1.unique()
}</code>
</script>
</expression>
<target>
<path>$focus/extension/user_forward_roles</path>
<set>
<predefined>all</predefined>
</set>
</target>
</mapping>
</focusMappings>
</inducement>
...
</archetype>
а также меняем до вида
<inducement id="1234">
<policyRule>
<name>Recompute Users Employment</name>
<policyConstraints>
<or id="13">
<modification id="22">
<item xmlns:gen365="http://example.com/xml/ns/mySchema">
c:extension/gen365:user_forward_roles</item>
</modification>
<modification id="22231">
<item xmlns:gen365="http://example.com/xml/ns/mySchema">
c:extension/gen365:user_forward_roles_inherited</item>
</modification>
<modification id="21240">
<item xmlns:gen550="http://example.com/xml/ns/mySchema">
c:extension/gen550:user_account_number</item>
</modification>
</or>
</policyConstraints>
<policyActions>
<scriptExecution id="16">
<object>
<linkSource id="131">
<name>from Employment User to me</name>
</linkSource>
</object>
<executeScript xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
<s:recompute />
</executeScript>
<privileges>
<runPrivileged>true</runPrivileged>
</privileges>
</scriptExecution>
</policyActions>
</policyRule>
</inducement>
Все дальше не надо ничего менять так как в роли Назначение мы в User Forward Roles также засовываем User Forward Roles Inherited, их надо объединять чтобы, потому что только в списке User Forward Roles есть роль NICKNAME которая препятсвует передачи прав в Трудоустройство если Назначению назначен AD аккаунт — кстати останавливает передачу всех прав а не только AD групп... надо подумать логично ли это!
Делаем теперь GUI для сотрудника начальника
Добавляем еще один Object Collection в Configuration\Import object вставляем код
<objectCollection>
<name>my-projects-view</name>
<type>RoleType</type>
<filter>
<text>
extension/user_boss contains `actor.personalNumber`
</text>
</filter>
</objectCollection>
В Configuration\System\Admin GUI configuration\Object detail views
Добавляем кодом
<objectCollectionView id="100320">
<identifier>my-projects-view</identifier>
<display>
<label>My Projects</label>
<pluralLabel>My Projects</pluralLabel>
<icon>
<cssClass>fa fa-briefcase-clock</cssClass>
</icon>
</display>
<visibility>hidden</visibility>
<column id="100331">
<name>ID</name>
<path>c:name</path>
<display>
<label>ID</label>
</display>
</column>
<column id="100333">
<name>Project Name</name>
<path>c:identifier</path>
<display>
<label>Project Name</label>
</display>
<previousColumn>Company</previousColumn>
</column>
<column id="100335">
<name>Company</name>
<path>c:extension/user_employment_parent</path>
<display>
<label>Company</label>
</display>
<previousColumn>ID</previousColumn>
</column>
<column id="100337">
<name>Members</name>
<display>
<label>Members</label>
</display>
<previousColumn>Description</previousColumn>
<export>
<expression>
<script>
<code>import com.evolveum.midpoint.prism.query.*
import com.evolveum.midpoint.xml.ns._public.common.common_3.*
query =
prismContext.queryFor(UserType.class).item(AssignmentHolderType.F_ROLE_MEMBERSHIP_REF).ref(object.getOid()).build();
objects = midpoint.searchObjects(UserType.class, query)
return (objects.size() - 1);</code>
</script>
</expression>
</export>
</column>
<column id="100342">
<name>Description</name>
<path>c:description</path>
<display>
<label>Description</label>
</display>
<previousColumn>Project Name</previousColumn>
</column>
<column id="100344">
<name>Roles</name>
<path xmlns:gen458="http://example.com/xml/ns/mySchema">c:extension/gen458:user_forward_roles</path>
<display>
<label>Roles</label>
</display>
<previousColumn>Members</previousColumn>
<export>
<expression>
<script>
<code>if (basic.isEmpty(input))
{return "0"}
else
{
for (i in input)
{
if (basic.stringify(i) == "NO CONNECTION")
{return "0"}
}
return input.size()}</code>
</script>
</expression>
</export>
</column>
<type>c:RoleType</type>
<collection>
<collectionRef oid="49952180-49a0-4884-a8d1-5e1a50f26fa1" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project Role ArcheType -->
</collectionRef>
<baseCollectionRef>
<collectionRef oid="b2119133-e6a0-4a93-bb1f-8d48ee95b123" relation="org:default"
type="c:ObjectCollectionType">
<!-- my-projects-view -->
</collectionRef>
</baseCollectionRef>
</collection>
</objectCollectionView>
...
</objectCollectionViews>
Создаем черную роль POCP GUI Project Manager
Код
...
<archetypePolicy>
<display>
<icon>
<cssClass>fa fa-briefcase-clock</cssClass>
<color>#2d860a</color>
</icon>
</display>
</archetypePolicy>
</archetype>
В роли POCE GUI My Subordinates делаем в неё индусмент.
В роль POCE GUI My IDM Objects добавляем
...
<group id="17659">
<identifier>my-projects</identifier>
<display>
<label>My Projects</label>
<icon>
<cssClass>fa fa-briefcase-clock</cssClass>
</icon>
</display>
<collection>
<filter>
<q:text>extension/person_boss contains `actor.personalNumber` and archetypeRef matches (oid =
'c2523d38-76ed-43bc-9e73-5158ed225042')</q:text>
</filter>
</collection>
</group>
</targetSelection>
...
</accessRequest>
</adminGuiConfiguration>
</role>
Заходим под начальником, напоминаю это важно у начальником есть управляемые сотрудники им будет выдавать созданный проект.
В Administartion появилось Roles а в ней My Projects. На кнопку New role не смотрите, я её не хотел и она ничего не делает.

Создаём первый проект

В Identifier пишем название проекта, можно все пустым оставить все равно создаться.

Для начальника он первый, а глобально он 68. Это все атрибуты которые можно менять, не страшно, главное что name не сможет поменять. А и в User»s Boss не сможет удалить себя, а то сразу перестанет владеть, а значит мочь редактировать проект роль, но может кого то добавить и сказать ему убери меня... случайно получился механизм передачи проекта, гарантирующий что он всегда у кого‑то есть!
Запросим роли для проекта идем в Request Access

Жмем на My Project, выбираем наш проект тут он уже человеком

И в дереве каталога ролей выходим на роли для проектов в OOO ODIN

Жмем дальше дальше и ничего не происходит, а потому что до сих пор не существует авторизации для Linked Object опять буду делать таску которая рекомпилит проект Role если изменился проект User.
Заходим в Administration\Server Tasks\Iterative action tasks создаем пустой под именем POCP Recompute Project roles if Project User has been mod и наполняем его кодом
<schedule>
<recurrence>recurring</recurrence>
<interval>300</interval>
</schedule>
<activity>
<work>
<iterativeScripting>
<objects>
<type>c:UserType</type>
<archetypeRef oid="c2523d38-76ed-43bc-9e73-5158ed225042" relation="org:default"
type="c:ArchetypeType">
</archetypeRef>
<query>
<q:filter>
<q:and>
<q:text>
archetypeRef matches (oid = 'c2523d38-76ed-43bc-9e73-5158ed225042') and
assignment/@metadata/storage/createTimestamp greater ```
dateminus5m = basic.addDuration(basic.currentDateTime(), "-PT5M")
return dateminus5m
```
</q:text>
</q:and>
</q:filter>
</query>
<useRepositoryDirectly>true</useRepositoryDirectly>
</objects>
<scriptExecutionRequest xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
<s:action>
<s:type>execute-script</s:type>
<s:parameter>
<s:name>script</s:name>
<s:value xsi:type="c:ScriptExpressionEvaluatorType">
<code>
import com.evolveum.midpoint.xml.ns._public.common.common_3.*
import com.evolveum.midpoint.prism.delta.builder.*
import com.evolveum.midpoint.model.api.*
role_name = input.name
query_role= midpoint.queryFor(RoleType.class, "archetypeRef matches (oid =
'49952180-49a0-4884-a8d1-5e1a50f26fa1') and name equal '$role_name'")
result_role = midpoint.searchObjects(query_role)
midpoint.recompute(RoleType.class, basic.stringify(result_role.oid))
</code>
</s:value>
</s:parameter>
</s:action>
</scriptExecutionRequest>
</iterativeScripting>
</work>
</activity>
Теперь через пять минут записи созданные Forwad ролями появляются в проект Role.
Выдадим проект подчиненным идем в Request Access выбираем подчиненнего из компании EMP001001 (OOO ODIN) и в каталоге ролей для позиций выбираем проект Role.

И получается если начальник заходит в свою проект роль в Members то видит что там проект User и подчиненный позиция User.

В cписке своих проектов начальник видит сколько ролей по этому проекту Roles 5 и сколько реальных членов проекта Members 1.

Кстати начальнику надо себя добавить в проект, своё назначение на позицию!
Теперь когда у нас все назначается самое время подумать как отбирать проекты у подчиненных и роли у проекта! Midpoint совершенно не готов что то-отбирать, он рассчитывает что исчезнет причина назначать! Поэтому нам нужны админские кнопки и пр.
Добавляем в POCP GUI Project Manager
<authorization id="555">
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#adminUnassignMember</action>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-ui-3#adminUnassign</action>
</authorization>
<authorization id="556">
<name>unassign-project-roles-from-subordinates</name>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#unassign</action>
<object id="1768">
<orgRelation>
<subjectRelation>org:manager</subjectRelation>
<scope>allDescendants</scope>
<includeReferenceOrg>false</includeReferenceOrg>
</orgRelation>
</object>
<target id="1">
<type>RoleType</type>
<archetypeRef oid="49952180-49a0-4884-a8d1-5e1a50f26fa1" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project Role ArcheType -->
</archetypeRef>
<filter>
<q:text>extension/user_boss contains `actor.personalNumber`</q:text>
</filter>
</target>
<relation>org:default</relation>
</authorization>
<authorization id="600">
<name>unassign-project-roles-from-project-user</name>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#unassign</action>
<object id="1768">
<type>UserType</type>
<archetypeRef oid="c2523d38-76ed-43bc-9e73-5158ed225042" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project User ArcheType -->
</archetypeRef>
<filter>
<q:text>extension/person_boss contains `actor.personalNumber`</q:text>
</filter>
</object>
<target id="1">
<type>RoleType</type>
<archetypeRef oid="b527aa8f-9097-45d7-94c9-8c2d79e53832" relation="org:default"
type="c:ArchetypeType">
<!-- POCE Forward Role ArcheType -->
</archetypeRef>
<filter>
<q:text>extension/role_purpose_type = 'Project' or extension/role_purpose_type = 'Positions
and Projects'</q:text>
</filter>
</target>
<relation>org:default</relation>
</authorization>
555 — вешает кнопки заанасаинт в members в роли и в assigment вообще везде в роли в людей.
556 — а вот тут уже конкретно прописываем анассаинить роли наших проектов с наших подчиненных.
600 — с наших проектов User роли Forward которые с пометкой Project.
Чтобы убрать членов из проекта идем в свои проекты в Members

Вот тут с права нажимаем на перечеркнутую цепочка и случается анассаин если это позиция, если это проект не случается!
Теперь чтобы удалить права у проекта, тут же жмем на проект User, доходим у него до Assigments и там уже жмем на черточку

Возможность создавать проекты создана, назначение в него участников тоже, запрос и перетекание прав работаете — думаете всё? Да, конечно!
А давайте сделаем так чтобы у участников проекта были не одинаковые права!
Основные права предназначенные для проекта будут у всех участников проекта, а специфические права‑роли созданные специально под проект можно будет назначать индивидуально на назначения на должность Position User. Midpoint к этому совершенно не готов, то есть он вообще не готов к сложным сценариям, а к этому ну совсем!
Для начала нам надо сделать Forward роли индивидуальные для проекта. Конкретно возьмем необходимость сделать под проект AD группы. Нам нужна Forward роль назначенная на проект User, которая будет делать Forward роль, которая будет делать роль AD группу, которая будет делать AD группы в AD. Звучит просто и так оно и есть, если не задумываться о каждом этапе цикла существования проекта...
Механизм Persona которого мы и так используем не по назначению, имеет еще и минус, в следствии его недописанности и недосказанности, он не динамичен, мы не можем в него кинуть сделай нам что‑то с таким именем, мы в него кидаем object template где написано имя берем от сюда, или имя будет таким. Так что придется наделать Object темплейтов! А вот на архетипах попытаемся сэкономить!
Начнем с конца. В ресурсе Resource\All resources\Windows MS AD OOO ODIN\Schema handling\Object types\MS AD group\Mappings сделаем вот так

Добавим черную роль под названием POCP Create AD Group from Role in OOO ODIN в ней код
<inducement id="3">
<construction>
<resourceRef oid="b8618fba-cf8b-416c-8e3b-32ea34cf003d" relation="org:default"
type="c:ResourceType">
<!-- Windows MS AD OOO ODIN -->
</resourceRef>
<kind>entitlement</kind>
<intent>intent MS AD group</intent>
</construction>
</inducement>
В Object Template POCE Forward Role Object Template добавим код
<item id="116">
<ref>assignment</ref>
<displayName>Assignment or creation to AD Group [Project Name]-Admins</displayName>
<mapping id="9">
<strength>strong</strength>
<source>
<path>identifier</path>
</source>
<source>
<path xmlns:gen671="http://example.com/xml/ns/mySchema">c:extension/gen671:user_personalNumber</path>
</source>
<source>
<path xmlns:gen671="http://example.com/xml/ns/mySchema">
c:extension/gen671:user_forward_roles_inherited</path>
</source>
<source>
<path xmlns:gen671="http://example.com/xml/ns/mySchema">c:extension/gen671:user_boss</path>
</source>
<source>
<path>documentation</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<filter>
<q:text>identifier = $identifier and archetypeRef matches (oid =
"e9eda47b-b097-4814-9605-7177a2482fa1")</q:text>
</filter>
<createOnDemand>true</createOnDemand>
<populateObject>
<populateItem>
<expression>
<script>
<code>"ADG:" + user_personalNumber + documentation</code>
</script>
</expression>
<target>
<path>name</path>
</target>
</populateItem>
<populateItem>
<expression>
<script>
<code>"Auto-created AD group for Project" + user_personalNumber + " by " +
actor.personalNumber</code>
</script>
</expression>
<target>
<path>description</path>
</target>
</populateItem>
<populateItem>
<expression>
<script>
<code>user_personalNumber + documentation</code>
</script>
</expression>
<target>
<path>documentation</path>
</target>
</populateItem>
<populateItem>
<expression>
<script>
<code>identifier</code>
</script>
</expression>
<target>
<path>identifier</path>
</target>
</populateItem>
<populateItem>
<expression>
<script>
<code>user_boss</code>
</script>
</expression>
<target>
<path>extension/user_boss</path>
</target>
</populateItem>
<populateItem>
<expression>
<assignmentTargetSearch>
<targetType>ArchetypeType</targetType>
<oid>e9eda47b-b097-4814-9605-7177a2482fa1</oid>
</assignmentTargetSearch>
</expression>
<target>
<path>assignment</path>
</target>
</populateItem>
<populateItem>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<oid>7e9dbf52-eda7-4922-9e50-3ffe817143eb</oid>
</assignmentTargetSearch>
</expression>
<target>
<path>assignment</path>
</target>
</populateItem>
</populateObject>
</assignmentTargetSearch>
</expression>
<condition>
<script>
<relativityMode>absolute</relativityMode>
<code>for (i in user_forward_roles_inherited)
{if (i == "Create AD group for EMP001001")
{return true}}
return false</code>
</script>
</condition>
</mapping>
</item>
Если в Forward роли в user_forward_roles_inherited написано Create AD group for EMP001 001 то пытаемся эту роль за ассаинить к роли AD Group если её нет то создаем её. То что в Forward роли в assignment будет AD группа роль не страшно, она не попадет к пользователю... Тут не стал Person делать, если удаляется роль person то удаляется то что она сделала, а тут в цепочке действия person не удалилась, да и ладно пусть AD Group остается — она будет пустой всё равно.
Делаем Object темплейт под названием POCP Persona Forward Role AD Group [Project Name]-Admins
вставляем код
<mapping id="3">
<name>01 name</name>
<source>
<path>c:name</path>
</source>
<expression>
<script>
<code>return "OOO ODIN FR:PRJ for " + name + " AD Group " + name + "-Admins"</code>
</script>
</expression>
<target>
<path>c:name</path>
</target>
</mapping>
<mapping id="6">
<name>02</name>
<source>
<path>c:organization</path>
</source>
<expression/>
<target>
<path xmlns:gen531="http://example.com/xml/ns/mySchema">c:extension/gen531:user_employment_parent</path>
</target>
</mapping>
<mapping id="7">
<name>03</name>
<strength>weak</strength>
<expression>
<script>
<code>return "Positions and Projects"</code>
</script>
</expression>
<target>
<path xmlns:gen422="http://example.com/xml/ns/mySchema">c:extension/gen422:role_purpose_type</path>
</target>
</mapping>
<mapping id="9">
<name>04</name>
<expression>
<script>
<code>return "MSAD"</code>
</script>
</expression>
<target>
<path xmlns:gen578="http://example.com/xml/ns/mySchema">c:extension/gen578:role_root_system</path>
</target>
</mapping>
<mapping id="10">
<name>05</name>
<strength>weak</strength>
<expression>
<script>
<code>return "5"</code>
</script>
</expression>
<target>
<path>c:riskLevel</path>
</target>
</mapping>
<mapping id="13">
<name>06</name>
<source>
<path>c:name</path>
</source>
<expression>
<script>
<code>return "CN=" + name + "-Admins,OU=Groups,OU=OOO_ODIN,DC=168testserverhome,DC=com"</code>
</script>
</expression>
<target>
<path>c:identifier</path>
</target>
</mapping>
<mapping id="15">
<name>07</name>
<source>
<path>c:name</path>
</source>
<expression/>
<target>
<path xmlns:gen805="http://example.com/xml/ns/mySchema">c:extension/gen805:user_personalNumber</path>
</target>
</mapping>
<mapping id="16">
<name>08</name>
<source>
<path xmlns:gen232="http://example.com/xml/ns/mySchema">c:extension/gen232:person_boss</path>
</source>
<expression/>
<target>
<path xmlns:gen339="http://example.com/xml/ns/mySchema">c:extension/gen339:user_boss</path>
</target>
</mapping>
<mapping id="19">
<name>10</name>
<expression>
<value>POCP Policy: Project Project Role only for User with Project Role</value>
</expression>
<target>
<path xmlns:gen319="http://example.com/xml/ns/mySchema">c:extension/gen319:user_forward_roles_inherited</path>
</target>
</mapping>
<mapping id="20">
<name>09</name>
<source>
<path>c:organization</path>
</source>
<expression>
<script>
<code>return "Create AD group for " + organization </code>
</script>
</expression>
<target>
<path xmlns:gen319="http://example.com/xml/ns/mySchema">c:extension/gen319:user_forward_roles_inherited</path>
</target>
</mapping>
<mapping id="26">
<name>11</name>
<expression>
<value>-Admins</value>
</expression>
<target>
<path>c:documentation</path>
</target>
</mapping>
<mapping id="28">
<name>12</name>
<source>
<path>c:nickName</path>
</source>
<expression>
<script>
<code>if (nickName == "Deactivated")
{return false}
else
{return true}</code>
</script>
</expression>
<target>
<path xmlns:gen96="http://example.com/xml/ns/mySchema">c:extension/gen96:role_active</path>
</target>
</mapping>
В маппингах 1 и 11 надо будет прописать название конца папки «-Admins»
Делаем Forward роль под названием OOO ODIN FR:PRJ Creat AD Group [Project Name]-Admins
И заполняем её так.

И добавляем в неё код
<inducement id="125">
<personaConstruction>
<targetType>RoleType</targetType>
<objectMappingRef oid="ffc5b12d-23b8-43b2-abbf-aef3ac40f926" relation="org:default" type="c:ObjectTemplateType">
<!-- POCP Persona Forward Role AD Group [Project Name]-Admins -->
</objectMappingRef>
<archetypeRef oid="b527aa8f-9097-45d7-94c9-8c2d79e53832" relation="org:default" type="c:ArchetypeType">
<!-- POCE Forward Role ArcheType -->
</archetypeRef>
</personaConstruction>
</inducement>
Под админом назначаем проекту User роль OOO ODIN FR:PRJ Creat AD Group [Project Name]-Admins создаем одна Forward роль под проект, и одна роль Ad группа причем в ресурсе тоже создается проэкция сразу

Саму роль под проект под AD группу пока выдавать рано, мы же хотим чтобы её получали только User назначение который в этом проекте, да еще чтобы она отбиралась если они из проекта уходят!
Тут придется прибегнуть к политике... Политики это апофеоз гения Evolveum тут сошлось все и недописанность и недосказанность и глючность. Хотелось бы чтобы политика срабатывала только при изменении назначений то есть assigment и все слова для этого есть и дажу пару кнопок — но нет! Политика будет срабатывать всегда. Хотелось бы чтобы при попытке назначить проект проект роль была какая‑то информативная ошибка и все для этого есть message но нет, поля не активны, древний код(единственный найденный пример) нынешняя версия Midpoint уже не понимает...
Создаем черную роль POCP Policy: Project Project Role only for User with Project Role
в ней код
<inducement id="2">
<policyRule>
<name>Member must have </name>
<policyConstraints>
<assignmentState id="7">
<expression>
<script>
<code>import com.evolveum.midpoint.xml.ns._public.common.common_3.*
import com.evolveum.midpoint.prism.delta.builder.*
import com.evolveum.midpoint.model.api.*
assignmentsToDelete = []
boolean yes = false
boolean yes_my = false
user_oid = focus.getOid()
role_oid = target.getOid()
user = midpoint.getObject(UserType.class, user_oid)
role = midpoint.getObject(RoleType.class, role_oid)
role_f = basic.stringify(basic.getExtensionPropertyValue(role, "http://example.com/xml/ns/mySchema", "user_personalNumber"))
query_role_depend = midpoint.queryFor(RoleType.class, "name = '$role_f' and
archetypeRef matches (oid = '49952180-49a0-4884-a8d1-5e1a50f26fa1')")
role_depend = midpoint.searchObjects(query_role_depend)
for (i in user.assignment) {
if (i.targetRef?.oid == basic.stringify(role_depend.oid))
{ yes = true
}
if (i.targetRef?.oid == basic.stringify(role_oid))
{ yes_my = true
def removeAssignment = new AssignmentType()
removeAssignment.id = i.id
assignmentsToDelete.add removeAssignment.asPrismContainerValue()
}
}
if (yes && !yes_my)
{
return false}
else
{if (!yes && !yes_my)
{
return true
}else{
if (yes && yes_my){
return false
}else{
delta_un =
prismContext.deltaFor(UserType.class).item(UserType.F_ASSIGNMENT).delete(assignmentsToDelete).asObjectDelta(user_oid)
midpoint.modifyObject(delta_un, ModelExecuteOptions.createRaw())
midpoint.recompute(UserType, basic.stringify(user_oid))
return false}
}
}
</code>
</script>
</expression>
<messageExpression />
</assignmentState>
</policyConstraints>
<policyActions>
<enforcement>
<name>Enf</name>
</enforcement>
<suspendTask />
</policyActions>
<evaluationTarget>assignment</evaluationTarget>
</policyRule>
</inducement>
Эта политика срабатывает всегда если над пользователем что‑то происходит и у него есть роль носителя политики, или её только пытаемся назначить.
assignmentState — отвечает на вопрос выкидывать ошибку да или нет.
На входе всегда пользователь и сама роль на которой политика.
Есть роль Проекта / Нет роли носитель политики [Момент назначения проект проект роли] — ок молчим
Нет роли проекта / Нет роли носитель политики [Момент назначения проект проект роли] — выбрасываем ошибку
Нет роли проекта / Есть роль носитель политики у пользователя [Момент проект проект роль в назначениях]‑ молча удаляем её из assignment, рекомпилим пользователя.
В Object template POCP Persona Forward Role AD Group [Project Name]-Admins
добавляем код
<mapping id="19">
<name>10</name>
<expression>
<value>POCP Policy: Project Project Role only for User with Project Role</value>
</expression>
<target>
<path xmlns:gen319="http://example.com/xml/ns/mySchema">
c:extension/gen319:user_forward_roles_inherited</path>
</target>
</mapping>
В Object template POCE Forward Role Object Template
добавляем код
<item id="18">
<ref>assignment</ref>
<displayName>Auto assignment to POCP Policy: Project Project Role only for User with Project Role</displayName>
<mapping id="9">
<authoritative>true</authoritative>
<strength>strong</strength>
<source>
<path xmlns:gen671="http://example.com/xml/ns/mySchema">
c:extension/gen671:user_forward_roles_inherited</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<oid>e781c75e-17bb-45d5-910f-426b22ef37cf</oid>
</assignmentTargetSearch>
</expression>
<condition>
<script>
<relativityMode>absolute</relativityMode>
<code>for (i in user_forward_roles_inherited)
{if (i == "POCP Policy: Project Project Role only for User with Project Role")
{return true}}
return false</code>
</script>
</condition>
</mapping>
</item>
И меняем айтем 1 на
<item id="1">
<ref>assignment</ref>
<displayName>Assignment to Role Catalog</displayName>
<mapping id="9">
<name>Name</name>
<source>
<path xmlns:gen444="http://example.com/xml/ns/mySchema">
c:extension/gen444:user_employment_parent</path>
</source>
<source>
<path xmlns:gen189="http://example.com/xml/ns/mySchema">c:extension/gen189:role_purpose_type</path>
</source>
<expression>
<assignmentTargetSearch>
<targetType>OrgType</targetType>
<filter>
<q:equal>
<q:path>identifier</q:path>
<expression>
<trace>true</trace>
<script>
<code>
if (role_purpose_type == "Positions and Projects")
{
result = []
result1 = "\\RC\\" + user_employment_parent + "\\Position"
result.add(result1)
result2 = "\\RC\\" + user_employment_parent + "\\Project"
result.add(result2)
return result
}
else{
result = "\\RC\\" + user_employment_parent + "\\" + role_purpose_type
return result
}
</code>
</script>
</expression>
</q:equal>
</filter>
</assignmentTargetSearch>
</expression>
</mapping>
</item>
Чтобы роли с Positions and Projects в роле каталоге были и в Position и в Project.
Пытаемся назначению User назначить проектную роль под проект роли проекта которой у него нет!

Ни о чем не говорящая ошибка, но если красное и название роли которое только что пытались назначить то значит не надо её назначать. Добавим пользователя в проект — ДА кстати нельзя одновременно добавлять роль проект и проект проект роль под проект. После этого проект роль под проект спокойно добавляется!
Посмотрим на проект проект роль под проект!

В Assigment: 1 Системная роль — привязалась по факту создания, хотя нам надо было просто создать, 2 Организация роль — в этих папках роль каталога можно будет найти эту роль, 3 Политики — ну политику не комментирую и так все ясно.
В Inducement: 1 Политика — POCE POLICY: identifier from Forward Role to User Forward Roles List как и положено Forward ролям
Под админам работает пошли в GUI пользователя
В роль POCP GUI Project Manager добавляем
<mapping id="13">
<name>10</name>
<exclusive>true</exclusive>
<source>
<path>c:extension/person_forward_roles</path>
</source>
<source>
<path>c:extension/person_forward_roles_inherited</path>
</source>
<expression>
<script>
<relativityMode>absolute</relativityMode>
<code>
result = []
for (i in person_forward_roles)
{
if (i.startsWith("MSAD"))
{ii = i.tokenize( '|' )
result.add(ii[2])}
}
for (i in person_forward_roles_inherited)
{
if (i.startsWith("MSAD"))
{ii = i.tokenize( '|' )
result.add(ii[2])
}
return result.unique()</code>
</script>
</expression>
<target>
<path>c:extension/person_forward_roles</path>
</target>
</mapping>
77 700 — то что нужно чтобы создавать роли проекта под проект в которых пользователь в extension/user_boss это проеверяестя в момент в момент создания в будущей роли
77 703 — Чтобы работала POCP Policy: Project Project Role only for User with Project Role could work under GUI User нам надо в Forward роли прочитать extension/user_personalNumber
TODO: Если начальник добавлять проекту роль OOO ODIN FR:PRJ Creat AD Group [Project Name]‑Admins и еще какую‑то. То всё свершится но будет ошибка — так как Midpoint пытается два раза создать проект проект роль, и говорит что имя уже занято, потому что она создана... буду пытаться избавиться от неё в сборке для Demo‑Песочнице в рамках концепции Проектов она во первых не влияет, а во вторых совершенно из другой области, и возможно глюк!
Что происходит если проект закрывают
Если effectiveStatus станет отключен то случается страшное — что‑то отрубается например роли создания Persona, но отрубается так что остаются концы которые мешают дальше, а что то не отрубается например выданные роли, хотя роль создания Persona тоже роль. И Persona уничтожается, но не уничтожаются Persona созданные ролью Persona на этой Persona...
Нам нужен еще один атрибут, который будет указывать на то что проект активен, и по нему будем его корректно глушить! Этот атрибут role_active в роли!
В обжект теплейт POCP EMP001 001 Project Role Object Template уже есть под него маппинг 005 и добавляем
<inducement id="1222">
<policyRule>
<name>Recompute Position Role on Position User Forward Roles change</name>
<policyConstraints>
<or id="13">
<modification id="3342">
<item>c:activation/c:administrativeStatus</item>
</modification>
<modification id="3344">
<item xmlns:gen26="http://example.com/xml/ns/mySchema">
c:extension/gen26:person_forward_roles</item>
</modification>
<modification id="300087">
<item xmlns:gen26="http://example.com/xml/ns/mySchema">
c:extension/gen26:person_forward_roles_inherited</item>
</modification>
</or>
</policyConstraints>
<policyActions>
<scriptExecution id="16">
<object>
<linkTarget id="17">
<linkType>From Position Role to Position User</linkType>
</linkTarget>
</object>
<executeScript xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
<s:recompute />
</executeScript>
<privileges>
<runPrivileged>true</runPrivileged>
</privileges>
</scriptExecution>
</policyActions>
</policyRule>
</inducement>
Если проект создается без укзания role_active то ставиться true — слабо ставится
В обжект темплейт POCP EMP001001 Person Project User from Project Role Object Template добавляем
<mapping id="36">
<name>08</name>
<source>
<path xmlns:gen181="http://example.com/xml/ns/mySchema">c:extension/gen181:role_active</path>
</source>
<expression>
<script>
<code>if (role_active)
{return "Active"}
else
{return "Deactivated"}</code>
</script>
</expression>
<target>
<path>c:nickName</path>
</target>
</mapping>
В архетипе POCP EMP001001 Project Role ArcheType.
менеям индусмент 1226 на
<inducement id="1226">
<focusMappings>
<mapping id="7">
<name>11</name>
<documentation>get Forward Roles from Project user</documentation>
<authoritative>true</authoritative>
<strength>strong</strength>
<source>
<path xmlns:gen851="http://example.com/xml/ns/mySchema">c:extension/gen851:role_active</path>
</source>
<expression>
<script>
<code>linkedDATA = midpoint.findLinkedSource('from Project User to me')
if (basic.isEmpty(linkedDATA))
{return "NO CONNECTION"}
else
{
roles_result = []
roles = basic.getExtensionPropertyValues(linkedDATA,
"http://example.com/xml/ns/mySchema", "person_forward_roles")
for (i in roles)
{
if (!i.startsWith("ROLE|"))
{roles_result.add(i)}
}
return roles_result
}</code>
</script>
</expression>
<target>
<path>$focus/extension/user_forward_roles</path>
<set>
<predefined>all</predefined>
</set>
</target>
<condition>
<script>
<code>role_active</code>
</script>
</condition>
</mapping>
</focusMappings>
</inducement>
В обжект темплейт добавляем POCP Persona Forward Role AD Group [Project Name]-Admins
добавляем
<mapping id="28">
<name>12</name>
<source>
<path>c:nickName</path>
</source>
<expression>
<script>
<code>if (nickName == "Deactivated")
{return false}
else
{return true}</code>
</script>
</expression>
<target>
<path xmlns:gen96="http://example.com/xml/ns/mySchema">c:extension/gen96:role_active</path>
</target>
</mapping>
В обжект темплейт POCE Forward Role Object Template добавляем код
<mapping id="121">
<name>01</name>
<source>
<_metadata id="126">
<provenance>
<acquisition id="127">
<actorRef oid="00000000-0000-0000-0000-000000000002" relation="org:default"
type="c:UserType">
<!-- administrator -->
</actorRef>
<channel>http://midpoint.evolveum.com/xml/ns/public/common/channels-3#user</channel>
<timestamp>2025-05-20T05:35:01.850Z</timestamp>
</acquisition>
</provenance>
</_metadata>
<path xmlns:gen417="http://example.com/xml/ns/mySchema">c:extension/gen417:role_active</path>
</source>
<source>
<path>name</path>
</source>
<expression>
<script>
<code>if (basic.isEmpty(role_active) || role_active == true)
{return name}
else
{return "[DEACTIVATED] " + name}</code>
</script>
</expression>
<target>
<path>c:displayName</path>
</target>
</mapping>
В роли POCE POLICY: identifier from Forward Role to User Forward Roles List
меняем код
<script>
<code>import com.evolveum.midpoint.xml.ns._public.common.common_3.*
forward_role = midpoint.getObject(RoleType.class, assignmentPath[0].target.oid)
return ( basic.stringify(basic.getExtensionPropertyValue(forward_role,
"http://example.com/xml/ns/mySchema", "role_root_system")) + "|" +
basic.stringify(basic.getExtensionPropertyValue(forward_role,
"http://example.com/xml/ns/mySchema", "user_employment_parent")) + "|" +
basic.stringify(assignmentPath[0].target.identifier + "|" + name + "|" +
person_employment_parent + "|" + person_account_number))</code>
</script>
на
<script>
<code>import com.evolveum.midpoint.xml.ns._public.common.common_3.*
forward_role = midpoint.getObject(RoleType.class, assignmentPath[0].target.oid)
role_active = basic.getExtensionPropertyValue(forward_role,
"http://example.com/xml/ns/mySchema", "role_active")
if (basic.isEmpty(role_active) || role_active == true)
{return ( basic.stringify(basic.getExtensionPropertyValue(forward_role,
"http://example.com/xml/ns/mySchema", "role_root_system")) + "|" +
basic.stringify(basic.getExtensionPropertyValue(forward_role,
"http://example.com/xml/ns/mySchema", "user_employment_parent")) + "|" +
basic.stringify(assignmentPath[0].target.identifier + "|" + name + "|" +
person_employment_parent + "|" + person_account_number))
}
else
{return ( basic.stringify("[DEACTIVATED] " + basic.getExtensionPropertyValue(forward_role,
"http://example.com/xml/ns/mySchema", "role_root_system")) + "|" +
basic.stringify(basic.getExtensionPropertyValue(forward_role,
"http://example.com/xml/ns/mySchema", "user_employment_parent")) + "|" +
basic.stringify(assignmentPath[0].target.identifier + "|" + name + "|" +
person_employment_parent + "|" + person_account_number))
}
</code>
</script>
И во Configuration\System\Admin GUI configuration\Object detail views
меняем весь objectCollectionView 100320 на
<objectCollectionView id="100320">
<identifier>my-projects-view</identifier>
<display>
<label>My Projects</label>
<pluralLabel>My Projects</pluralLabel>
<icon>
<cssClass>fa fa-briefcase-clock</cssClass>
</icon>
</display>
<visibility>hidden</visibility>
<column id="100331">
<name>ID</name>
<path>c:name</path>
<display>
<label>ID</label>
</display>
</column>
<column id="100333">
<name>Project Name</name>
<path>c:identifier</path>
<display>
<label>Project Name</label>
</display>
<previousColumn>Company</previousColumn>
</column>
<column id="100335">
<name>Company</name>
<path>c:extension/user_employment_parent</path>
<display>
<label>Company</label>
</display>
<previousColumn>Status</previousColumn>
<export>
<expression>
<script>
<code>import com.evolveum.midpoint.xml.ns._public.common.common_3.*
orgId = basic.stringify(input)
query_org = midpoint.queryFor(OrgType.class, "identifier endsWith '$orgId' and
archetypeRef matches (oid = '7cab0b16-142a-4d37-8b60-9668e95b4b94') and
activation/effectiveStatus!='disabled'")
org_respond = midpoint.searchObjects(query_org)
orgIt = midpoint.getObject(OrgType.class, basic.stringify(org_respond.oid))
result = basic.stringify(input) + ":" + basic.stringify(orgIt.displayName)
return result</code>
</script>
</expression>
</export>
</column>
<column id="100337">
<name>Members</name>
<path>name</path>
<display>
<label>Members</label>
</display>
<previousColumn>Description</previousColumn>
<export>
<expression>
<script>
<code>import com.evolveum.midpoint.xml.ns._public.common.common_3.*
name = basic.stringify(input)
query = midpoint.queryFor(UserType.class, "assignment/targetRef/@/name = '$name' and
archetypeRef matches (oid = '0d1b1269-0011-49e6-b9f1-e62e7827dfed')")
objects = midpoint.searchObjects(query)
return objects.size()</code>
</script>
</expression>
</export>
</column>
<column id="100342">
<name>Description</name>
<path>c:description</path>
<display>
<label>Description</label>
</display>
<previousColumn>Project Name</previousColumn>
</column>
<column id="100344">
<name>Roles</name>
<path>name</path>
<display>
<label>Roles</label>
</display>
<previousColumn>Members</previousColumn>
<export>
<expression>
<script>
<code>
import com.evolveum.midpoint.xml.ns._public.common.common_3.*
result = 0
user_name = basic.stringify(input)
query_user = midpoint.queryFor(UserType.class, "name = '$user_name' and archetypeRef
matches (oid = 'c2523d38-76ed-43bc-9e73-5158ed225042')")
user = midpoint.searchObjects(query_user)
user_object = midpoint.getObject(UserType.class, basic.stringify(user.oid))
for (i in user_object.roleMembershipRef)
{
if (i.type?.localPart == "RoleType")
{
role_object = midpoint.getObject(RoleType.class, basic.stringify(i.oid))
for (ii in role_object.assignment)
{
if (ii.targetRef?.oid == "b527aa8f-9097-45d7-94c9-8c2d79e53832")
{
result++
}
}
}
}
return result
</code>
</script>
</expression>
</export>
</column>
<column id="1100335">
<name>Status</name>
<path xmlns:gen458="http://example.com/xml/ns/mySchema">c:extension/gen458:role_active</path>
<display>
<label>Status</label>
</display>
<previousColumn>ID</previousColumn>
<export>
<expression>
<script>
<code>if (input)
{return "OK"}
else
{return "DEACTIVATED"}</code>
</script>
</expression>
</export>
</column>
<type>c:RoleType</type>
<collection>
<collectionRef oid="49952180-49a0-4884-a8d1-5e1a50f26fa1" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project Role ArcheType -->
</collectionRef>
<baseCollectionRef>
<collectionRef oid="b2119133-e6a0-4a93-bb1f-8d48ee95b123" relation="org:default"
type="c:ObjectCollectionType">
<!-- my-projects-view -->
</collectionRef>
</baseCollectionRef>
</collection>
</objectCollectionView>
<objectCollectionView id="1100340">
<identifier>my-company-roles</identifier>
<display>
<singularLabel>Company Role</singularLabel>
<pluralLabel>Company Roles</pluralLabel>
<icon>
<imageUrl>fa fa-city</imageUrl>
</icon>
</display>
<visibility>hidden</visibility>
<type>c:RoleType</type>
<collection>
<collectionRef oid="f44dc355-31d3-499b-9854-e0ae277a60dc" relation="org:default"
type="c:ArchetypeType">
<!-- POCE Company Role ArcheType -->
</collectionRef>
</collection>
</objectCollectionView>
тут есть и другие полезные изменения
Виюха проектов в GUI пользователя теперь така.

В архетипе POCP EMP001001 Project Role ArcheType
добавляем еще одно условие в Recompute Users Position
было
<or id="13">
<modification id="22">
<item xmlns:gen365="http://example.com/xml/ns/mySchema">c:extension/gen365:user_forward_roles</item>
</modification>
</or>
стало
<or id="13">
<modification id="22">
<item xmlns:gen365="http://example.com/xml/ns/mySchema">c:extension/gen365:user_forward_roles</item>
</modification>
<modification id="2222">
<item xmlns:gen365="http://example.com/xml/ns/mySchema">c:extension/gen365:role_active</item>
</modification>
</or>
Под начальником в проекте ставим False на Active
Что происходит сразу
К имени проекта в проект Role и User добавляется [DEACTIVATED]
К имени проект роли под проект добавляется [DEACTIVATED]
У пользователя с проектом сразу исчезают роли пришедшие от проектах
Что не случилось
У пользователя не ушла роль проект роли под проект — она уйдёт при плановой реконсиляции пользователя
Но главный результат у нас не удалились проект роли под проект, нельзя удалять роль если в ней остаются member потому тогда у них в назначение будет «Not found» и это будет выдавать красные ошибки при следующих назначениях.
Нам нужна мега таска — которая будет вылавливать проект который был деактивирован за последние пять минут, и которая будет убирать этот роль проект у пользователей у которых он есть! Это решит недоактивированность проект ролей под проект!
Заходим в Administration\Server Tasks\Iterative action tasks создаем пустой под именем POCP Unassign deactivated projects и наполняем его кодом.
<schedule>
<recurrence>recurring</recurrence>
<interval>300</interval>
</schedule>
<activity>
<work>
<iterativeScripting>
<objects>
<type>c:RoleType</type>
<archetypeRef oid="49952180-49a0-4884-a8d1-5e1a50f26fa1" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project Role ArcheType -->
</archetypeRef>
<query>
<q:filter>
<q:and>
<q:text>
extension/role_active = "false" and metadata/modifyTimestamp greater ```
dateminus5m = basic.addDuration(basic.currentDateTime(), "-PT5M")
return dateminus5m
```
</q:text>
</q:and>
</q:filter>
</query>
<useRepositoryDirectly>true</useRepositoryDirectly>
</objects>
<scriptExecutionRequest xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
<s:action>
<s:type>execute-script</s:type>
<s:parameter>
<s:name>script</s:name>
<s:value xsi:type="c:ScriptExpressionEvaluatorType">
<code>
import com.evolveum.midpoint.xml.ns._public.common.common_3.*
import com.evolveum.midpoint.prism.delta.builder.*
import com.evolveum.midpoint.model.api.*
input_name = basic.stringify(input.name)
query_user = midpoint.queryFor(UserType.class, "assignment/targetRef/@/name =
'$input_name' and archetypeRef matches (oid =
'0d1b1269-0011-49e6-b9f1-e62e7827dfed')")
user_to_un = midpoint.searchObjects(query_user)
for (i in user_to_un)
{
user_oid = basic.stringify(i.oid)
user = midpoint.getObject(UserType.class, user_oid)
def assignmentsToDelete = []
for (a in user.assignment) {
if (a.targetRef?.oid == basic.stringify(input.oid)) {
def removeAssignment = new AssignmentType()
removeAssignment.id = a.id
assignmentsToDelete.add removeAssignment.asPrismContainerValue()
}
}
delta =
prismContext.deltaFor(UserType.class).item(UserType.F_ASSIGNMENT).delete(assignmentsToDelete).asObjectDelta(user_oid)
midpoint.modifyObject(delta, ModelExecuteOptions.createRaw())
midpoint.recompute(UserType, basic.stringify(user.oid))
}
</code>
</s:value>
</s:parameter>
</s:action>
</scriptExecutionRequest>
</iterativeScripting>
</work>
</activity>
<affectedObjects>
<activity id="8">
<activityType>c:iterativeScripting</activityType>
<objects>
<type>c:RoleType</type>
<archetypeRef oid="49952180-49a0-4884-a8d1-5e1a50f26fa1" relation="org:default"
type="c:ArchetypeType">
<!-- POCP EMP001001 Project Role ArcheType -->
</archetypeRef>
</objects>
<executionMode>full</executionMode>
<predefinedConfigurationToUse>production</predefinedConfigurationToUse>
</activity>
</affectedObjects>
Пробуем
Смотрим на проект PRJ000090
До того как поставим Active False
Проект в списке
Роли на участник проекта — роль Проекта (которая принесла еще две роли но тут мы их не видим), и проект проект роль персонально назначенная.
Группы AD которые получил его User учетка

Поставили Active False
Проект в списке поменялся Status и на самой проект роли displayName, и его больше нельзя выдать (так же и проект проект роль).
Роли на участник проекта — реальных изменений нет, только имя в списке но это весго лишь сработал поиск
Группы AD которые получил его User учетка — реальных изменений нет

Через 5 минут(максимум)
Сработал task POCP Unassign deactivated projects
Проект в списке теперь 0 Members
Роли на участник проекта сняты
Группы AD которые получил его User учетка сняты

Вот так просто а главное быстро можно реализовать концепцию Проект в IDM Midpoint!