<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright (C) 2010-2023 Evolveum and contributors
  ~
  ~ Licensed under the EUPL-1.2 or later.
  -->

<report xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
        xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
        xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
        oid="00000000-0000-0000-0000-b8249b79d2b5">
    <name>IGA: Who has access to what and why</name>
    <description>Displays IGA representation of user access - all roles, ORGs and services (applications) assigned to users directly or indirectly.
        Formerly known as Indirect assignment report.</description>
    <assignment id="1">
        <identifier>archetype</identifier>
        <targetRef oid="00000000-0000-0000-0000-000000000171" type="ArchetypeType"/>
    </assignment>
    <objectCollection>
        <collection>
            <!-- Type is declared in the view element. -->
            <filter>
                <q:text>
                    . ownedBy (
                        @type = UserType
                        and @path = roleMembershipRef
                        and name = yaml```
                            queryInterpretationOfNoValue: filterAll
                            path: $userName
                        ```
                    ) and . = yaml```
                        queryInterpretationOfNoValue: filterAll
                        path: $roleRef
                    ```
                </q:text>
            </filter>
        </collection>
        <parameter id="2">
            <name>userName</name>
            <type>string</type>
        </parameter>
        <parameter id="3">
            <name>roleRef</name>
            <type>c:ObjectReferenceType</type>
            <targetType>c:AbstractRoleType</targetType>
        </parameter>

        <subreport id="4">
            <!--
            This subreport generates additional lines per each metadata value,
            in case there are multiple distinct assignment paths.
            -->
            <name>data</name>
            <order>1</order>
            <resultHandling>
                <multipleValues>splitParentRow</multipleValues>
            </resultHandling>
            <expression>
                <script>
                    <objectVariableMode>prismReference</objectVariableMode>
                    <code>report.generateAssignmentPathRows(object)</code>
                </script>
            </expression>
        </subreport>
        <view>
            <type>c:ObjectReferenceType</type>
            <paging>
                <q:orderBy>../name</q:orderBy>
            </paging>
            <!--
            IMPORTANT:
            All the scripts must use objectVariableMode=prismReference for the case the target does not exist.
            -->
            <column id="5">
                <name>user</name>
                <display>
                    <label>
                        <orig>User</orig>
                        <translation>
                            <key>reportIndirectAssignments.userColumn.label</key>
                        </translation>
                    </label>
                </display>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>data?.owner?.name?.orig ?: 'Unknown owner'</code>
                        </script>
                    </expression>
                </export>
            </column>
            <column id="6">
                <name>nameColumn</name>
                <display>
                    <label>
                        <orig>Name</orig>
                        <translation>
                            <key>reportIndirectAssignments.nameColumn.label</key>
                        </translation>
                    </label>
                </display>
                <previousColumn>user</previousColumn>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>data?.role?.name?.orig</code>
                        </script>
                    </expression>
                </export>
            </column>
            <column id="7">
                <name>archetypeName</name>
                <display>
                    <label>
                        <orig>Type</orig>
                        <translation>
                            <key>reportIndirectAssignments.archetypeNameColumn.label</key>
                        </translation>
                    </label>
                </display>
                <previousColumn>nameColumn</previousColumn>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>data?.roleArchetype?.name?.orig</code>
                        </script>
                    </expression>
                </export>
            </column>
            <column id="8">
                <name>relation</name>
                <display>
                    <label>
                        <orig>Relation</orig>
                        <translation>
                            <key>reportIndirectAssignments.relationColumn.label</key>
                        </translation>
                    </label>
                </display>
                <previousColumn>archetypeName</previousColumn>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>object?.relation</code>
                        </script>
                    </expression>
                </export>
            </column>
            <column id="9">
                <name>allPath</name>
                <display>
                    <label>
                        <orig>Path</orig>
                        <translation>
                            <key>reportIndirectAssignments.allPathColumn.label</key>
                        </translation>
                    </label>
                </display>
                <previousColumn>relation</previousColumn>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>
                                return data?.segmentTargets?.collect(o -> o?.name?.orig)?.join(' -> ') ?: '?'
                            </code>
                        </script>
                    </expression>
                </export>
            </column>
            <column id="10">
                <!-- This is probably not important column, everything is in the path column anyway. -->
                <name>parent</name>
                <display>
                    <label>
                        <orig>Parent</orig>
                        <translation>
                            <key>reportIndirectAssignments.parentColumn.label</key>
                        </translation>
                    </label>
                </display>
                <previousColumn>allPath</previousColumn>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>
                                if (!data?.segmentTargets) {
                                    return "?"
                                }

                                def segLen = data.segmentTargets.size()
                                if (segLen == 1) {
                                    return 'Direct'
                                } else {
                                    return data.segmentTargets[segLen - 2]?.name?.orig
                                }
                            </code>
                        </script>
                    </expression>
                </export>
            </column>
            <column id="11">
                <!-- We don't store refs/metadata for disabled assignments, so this is always Enabled. -->
                <name>activation</name>
                <display>
                    <label>
                        <orig>Activation</orig>
                        <translation>
                            <key>reportIndirectAssignments.activationColumn.label</key>
                        </translation>
                    </label>
                </display>
                <previousColumn>parent</previousColumn>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>data?.assignment?.activation?.effectiveStatus</code>
                        </script>
                    </expression>
                </export>
            </column>
            <column id="12">
                <name>validTo</name>
                <display>
                    <label>
                        <orig>Valid to</orig>
                        <translation>
                            <key>reportIndirectAssignments.validToColumn.label</key>
                        </translation>
                    </label>
                </display>
                <previousColumn>activation</previousColumn>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>data?.assignment?.activation?.validTo</code>
                        </script>
                    </expression>
                </export>
            </column>
            <column id="13">
                <name>since</name>
                <display>
                    <label>
                        <orig>Since</orig>
                        <translation>
                            <key>reportIndirectAssignments.sinceColumn.label</key>
                        </translation>
                    </label>
                </display>
                <previousColumn>validTo</previousColumn>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>data?.createTimestamp</code>
                        </script>
                    </expression>
                </export>
            </column>
            <column id="14">
                <name>createChannel</name>
                <display>
                    <label>
                        <orig>Source</orig>
                        <translation>
                            <key>reportIndirectAssignments.createChannelColumn.label</key>
                        </translation>
                    </label>
                </display>
                <previousColumn>since</previousColumn>
                <export>
                    <expression>
                        <script>
                            <objectVariableMode>prismReference</objectVariableMode>
                            <code>
                                // Explicit String to use the right split() and not random Groovy default method.
                                String channel = data?.assignment?.metadata?.createChannel
                                return channel?.split('#')?.last()?.with(s -> midpoint.translate('Channel.' + s))
                            </code>
                        </script>
                    </expression>
                </export>
            </column>
        </view>
    </objectCollection>
</report>
