/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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
 *
 *    https://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.
 */

package grails.plugin.springsecurity.ldap.userdetails

import spock.lang.Specification

import org.springframework.ldap.core.support.LdapContextSource
import org.springframework.security.core.authority.SimpleGrantedAuthority

class GrailsLdapAuthoritiesPopulatorSpec extends Specification {

    private static final String[] rolesToTest = [
            'EnHS-GLNE',
            'EnHS-NCS-Financial',
            'EnHS-WBFCR',
            'EnHS-HS-AssetTrackers',
            'EnHS-IT',
            'EnHS-NCS-All',
            'EnHS-NCS-Remove-List-Member',
            'EnHS-NCS-List-Viewer',
            'EnHS-NCS-Stress',
            'EnHS-HS-Lyris',
            'EnHS-Staff',
            'NCS-Protected-Stress',
            'EnHS-NCS-DocGen-Manage',
            'EnHS-NunStudy-Investigator',
            'EnHS-NCS-Segment',
            'EnHS-NCS',
            'EnHS-NCS-Protected-Exec-Function',
            'EnHS-MES',
            'EnHS-NCS-Edit-List-Member',
            'EnHS-NCS-Lookup',
            'EnHS-NCS-Protected-Ulnar-Length',
            'EnHS-NCS-Receipt',
            'NCS-HumanResources',
            'EnHS-NCS-Add-List-Member',
            'EnHS-HS-DBAs',
            'EnHS-NunStudy-Administrative',
            'EnHS-NCS-Calling',
            'EnHS-NCS-Exec-Function',
            'EnHS-NunStudy',
            'EnHS-NCS-Segment-Lookup',
            'EnHS-NCS-Security',
            'EnHS-Print-Admins',
            'EnHS-NCS-Formative',
            'EnHS-MTC-RemoteDesktopUsers',
            'NCS-Ulnar-Length',
            'EnHS-HS-All',
            'EnHS-AVAD',
            'EnHS-NCS-DLR',
            'EnHS-NCS-Protected',
            'EnHS-NCS-Incentives',
            'EnHS-NCST',
            'EnHS-HS-IT',
            'EnHS-NCS-Nutrition',
            'EnHS-HPVHSS',
            'EnHS-NCS-Assign-List-Auth',
            'EnHS-HS-Staff',
            'EnHS-NCS-DocGen',
            'EnHS-NCS-List-Admin',
            'EnHS-NCS-List-Tester',
            'EnHS-NCS-Protected-Nutrition',
            'EnHS-NCS-NORC-Data',
            'EnHS-NCS-Data',
            'EnHS-HS-BulkPrinters',
            'NCS-IT',
            'EnHS-All',
            'EnHS-NCS-Reports']

    private LdapContextSource contextSource = new LdapContextSource()

    private GrailsLdapAuthoritiesPopulator grailsLdapAuthoritiesPopulator = new GrailsLdapAuthoritiesPopulator(contextSource, '')

    void setup() {
        grailsLdapAuthoritiesPopulator.groupRoleAttribute = 'member'
        grailsLdapAuthoritiesPopulator.groupSearchFilter = 'fake={0}'
        grailsLdapAuthoritiesPopulator.searchSubtree = true
        grailsLdapAuthoritiesPopulator.defaultRole = 'ROLE_USER'
        grailsLdapAuthoritiesPopulator.ignorePartialResultException = false
        grailsLdapAuthoritiesPopulator.retrieveDatabaseRoles = false
        grailsLdapAuthoritiesPopulator.roleConvertDashes = true
        grailsLdapAuthoritiesPopulator.roleToUpperCase = true
    }

    /**
     * This one test should cover everything added in the cleanRole() function
     */
    void 'my roles'() {

        given:
        grailsLdapAuthoritiesPopulator.roleStripPrefix = 'EnHS-'

        when:

        def testRole = new SimpleGrantedAuthority('ROLE_' + roleName)

        // the settings should run through all the permutations in one swipe
        def newRole = grailsLdapAuthoritiesPopulator.cleanRole(testRole)

        String cleanRoleName = 'ROLE_' + roleName.toUpperCase().replaceAll('-', '_').replaceFirst('ENHS_', '')

        then:
        // make sure our test did what we expected it to
        cleanRoleName == newRole.authority

        where:
        roleName << rolesToTest
    }

    /**
     * This one test should cover everything added in the cleanRole() function
     */
    void 'get group membership roles'() {

        given:
        grailsLdapAuthoritiesPopulator.roleStripPrefix = 'Test-Pre'
        grailsLdapAuthoritiesPopulator.roleStripSuffix = 'Test-Post'

        when:
        def testRole = new SimpleGrantedAuthority('ROLE_Test-Pre Sys-AdminTest-Pre-Test-Post-Group Test-Post')

        // the settings should run through all the permutations in one swipe
        def newRole = grailsLdapAuthoritiesPopulator.cleanRole(testRole)

        then:
        // make sure our test did what we expected it to
        'ROLE_SYS_ADMINTEST_PRE_TEST_POST_GROUP' == newRole.authority
    }
}
