<!--
  ~ Copyright (c) 2019 Evolveum
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<securityPolicy oid="6276728e-f98c-11e9-90ba-0785c1563bb1"
                xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
                xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
                xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
                xmlns:piracy="http://midpoint.evolveum.com/xml/ns/samples/piracy">
    <name>System security policy</name>

    <description>
        Authentication/credentials configuration for midPoint 4.1.
    </description>

    <authentication>
        <!-- Definition of AUTHENTICATION methods that midPoint supports.
             Credentials in this section are considered to be read-only. -->
        <modules>
            <!-- Definition and configuration of all authentication modules that can be used in the system -->
            <loginForm>
                <name>internalLoginForm</name>
                <description>Internal username/password authentication, default user password, login form</description>
                <!-- Credential name is not specified. Default password is used. -->
            </loginForm>
            <httpBasic>
                <name>internalBasic</name>
                <description>Internal username/password authentication, using HTTP basic auth</description>
            </httpBasic>
            <saml2>
                <name>mySamlSso</name>
                <description>My internal enterprise SAML-based SSO system.</description>
                <serviceProvider>
                    <entityId>midpoint</entityId>
                </serviceProvider>
                <!-- ... other SAML configuration that the module needs -->
            </saml2>

            <!-- Nice to have. Otherwise the "nonce" flows may work as they were in 3.x -->
            <mailNonce>
                <name>registrationMail</name>
                <description>Authentication based on mail message with a nonce. Used for user registration.</description>
                <!-- This has to be a name of nonce credential. This credential will be generated and stored. -->
                <credentialName>mailNonce</credentialName>
                <!-- no emailAddressItem specified, therefore the default emailAddreess item will be used -->
            </mailNonce>
            <smsNonce>
                <name>passwordResetSms</name>
                <description>Authentication based on SMS message with a nonce. Used for password resets.</description>
                <!-- This has to be a name of nonce credential. This credential will be generated and stored. -->
                <credentialName>smsNonce</credentialName>
                <mobileTelephoneNumberItemPath>extension/mobile</mobileTelephoneNumberItemPath>
            </smsNonce>

            <!-- Nice to have. Rework of security questions will be really nice thing to do. -->
            <securityQuestionsForm>
                <name>SecQ</name>
                <description>
                    This is interactive, form-based authentication by using security questions.
                </description>
                <!-- No credentialName here. Looks for default security questions credentials. -->
                <!-- Define security question validation.
                     E.g. how many questions to present, how many need to be answered successfuly, randomize order, etc.  -->
            </securityQuestionsForm>
            <httpSecQ>
                <name>httpSecQ</name>
                <description>
                    Special "HTTP SecQ" authentication based on security question answers.
                    It is used for REST service.
                </description>
                <!-- No credentialName here. Looks for default security questions credentials. -->
                <!-- Define security question validation.
                     E.g. how many questions to present, how many need to be answered successfuly, randomize order, etc.  -->
            </httpSecQ>
        </modules>

        <sequence>
            <name>admin-gui-default</name>
            <description>
                Default GUI authentication sequence.
                We want to try company SSO, federation and internal. In that order.
                Just one of then need to be successful to let user in.
            </description>
            <channel>
                <!-- Default sequence for the user channel. Usual admin GUI login code will look for this configuration. -->
                <channelId>http://midpoint.evolveum.com/xml/ns/public/model/channels-3#user</channelId>
                <default>true</default>
            </channel>
            <module>
                <name>mySamlSso</name> <!-- This is reference to module defined above -->
                <order>10</order>
                <necessity>sufficient</necessity>
            </module>
            <module>
                <name>internalLoginForm</name>
                <order>20</order>
                <necessity>sufficient</necessity>
            </module>
        </sequence>

        <sequence>
            <name>admin-gui-emergency</name>
            <description>
                Special GUI authentication sequence that is using just the internal user password.
                It is used only in emergency. It allows to skip SAML authentication cycles, e.g. in case
                that the SAML authentication is redirecting the browser incorrectly.
            </description>
            <channel>
                <!-- Non-default sequence for the user channel.
                     It can be used for admin GUI. But special URL will be needed to initiate this sequence. -->
                <channelId>http://midpoint.evolveum.com/xml/ns/public/model/channels-3#user</channelId>
                <default>false</default>
                <!-- e.g. http://localhost/midpoint/auth/emergency -->
                <urlSuffix>emergency</urlSuffix>
            </channel>
            <!-- This authentication sequence will only work for users that have superuser role -->
            <requireAssignmentTarget oid="00000000-0000-0000-0000-000000000004" type="RoleType"/> <!-- Role superuser -->
            <module>
                <name>internalLoginForm</name>
                <order>30</order>
                <necessity>sufficient</necessity>
            </module>
        </sequence>

        <!-- Nice to have. Otherwise REST authentication can still be hardcoded to HTTP basic/SecQ. -->
        <sequence>
            <name>rest</name>
            <description>
                Authentication sequence for REST service.
                We want just OIDC auth here, HTTP basic as fallback.
                There is also HTTP SecQ authorization used by custom GUI front end. However, that SecQ
                authorization can be used only to reset a password.
                All modules have the same order. Therefore they are both advertised in HTTP WWW-Authentication
                header. The client can decide which one to use.
            </description>
            <channel>
                <!-- Default (and only) authentication sequence for the REST channel.
                     This is how REST authorization code will know to look for this auth sequence definition. -->
                <channelId>http://midpoint.evolveum.com/xml/ns/public/model/channels-3#rest</channelId>
                <default>true</default>
            </channel>
            <module>
                <name>internalBasic</name>
                <order>10</order>
                <necessity>sufficient</necessity>
            </module>
            <module>
                <name>httpSecQ</name>
                <order>10</order>
                <necessity>sufficient</necessity>
                <!-- TODO: reduce authorizations, allow password reset only -->
            </module>
        </sequence>

        <!-- Nice to have. Do this only if security questions are cleaned up -->
        <sequence>
            <name>userPasswordResetAuth</name>
            <description>
                Just plain and simple security questions.
            </description>
            <channel>
                <channelId>http://midpoint.evolveum.com/xml/ns/public/gui/channels-3#resetPassword</channelId>
            </channel>
            <module>
                <name>SecQ</name>
                <order>10</order>
                <necessity>sufficient</necessity>
            </module>
        </sequence>

        <!-- Self registration can still be hardcoded in 4.1. Rework self-registration auth only if there is
             no other option. -->
        <!--
        <sequence>
            <name>selfRegistrationAuth</name>
            <description>
                Just a nonce mail to validate e-mail address.
            </description>
            <channel>
                <channelId>http://midpoint.evolveum.com/xml/ns/public/gui/channels-3#selfRegistration</channelId>
            </channel>
            <module>
                <name>registrationMail</name>
                <order>10</order>
                <necessity>required</necessity>
            </module>
        </sequence> -->
    </authentication>

    <credentials>
        <!-- Definition of user credentials that midPoint can MANAGE. Which means writing/changing them.
             This has nothing to do with authentication or credential reset. Not directly.
             But there may be dependencies. E.g. password reset may use password policy to generate/validate new password.
             Also, resource-side passwords need to be defined here to be used by authentication modules. -->
        <password>
            <name>userPassword</name>
            <description>Ordinary midPoint password (internal)</description>
            <!-- Default password policy. -->
        </password>
        <securityQuestions>
            <name>SecQ</name>
            <!-- Define credential management,
                e.g. how many questions to set up. Allow user-provided questions or pre-defined questions only. -->
        </securityQuestions>
        <nonce>
            <name>mailNonce</name>
            <valuePolicyRef oid="12345"/> <!-- 30-char alphanumeric -->
        </nonce>
        <nonce>
            <name>smsNonce</name>
            <valuePolicyRef oid="43421233"/> <!-- 6-char alphanumeric (lowercase letters only) -->
        </nonce>
    </credentials>

    <flow>
        <!-- User interface "flows" such as self-service registration -->
        <selfRegistration>
            <name>selfRegistration</name>
            <initialLifecycleState>draft</initialLifecycleState>
            <displayName>Self Registration</displayName>
            <additionalAuthenticationName>selfRegistrationAuth</additionalAuthenticationName>
            <defaultRole oid="00000000-0000-0000-0000-000000000008" type="c:RoleType"/>
        </selfRegistration>
        <postAuthentication>
            <!-- TODO -->
            <formRef oid="23423535653"/>
        </postAuthentication>
    </flow>

    <credentialsReset>
        <name>userPasswordReset</name>
        <description>
            Credential reset procedure for default user password.
            Security questions are used.
        </description>
        <authenticationSequenceName>userPasswordResetAuth</authenticationSequenceName>
        <newCredentialSource>userEntry</newCredentialSource>
    </credentialsReset>

</securityPolicy>
