com.netflix.genie.web.security.saml.SAMLUserDetailsServiceImplUnitTests.java Source code

Java tutorial

Introduction

Here is the source code for com.netflix.genie.web.security.saml.SAMLUserDetailsServiceImplUnitTests.java

Source

/*
 *
 *  Copyright 2016 Netflix, Inc.
 *
 *     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.
 *
 */
package com.netflix.genie.web.security.saml;

import com.netflix.genie.test.categories.UnitTest;
import com.netflix.spectator.api.Registry;
import com.netflix.spectator.api.Timer;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.Mockito;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.saml.SAMLCredential;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * Tests for the SAMLUserDetailsImpl class. Makes sure we're pulling the right attributes and authorities from the
 * SAML assertion.
 *
 * @author tgianos
 * @since 3.0.0
 */
@Category(UnitTest.class)
public class SAMLUserDetailsServiceImplUnitTests {

    private static final String USER_ATTRIBUTE_NAME = UUID.randomUUID().toString();
    private static final String GROUP_ATTRIBUTE_NAME = UUID.randomUUID().toString();
    private static final String ADMIN_GROUP = UUID.randomUUID().toString();

    private static final String USER_ID = UUID.randomUUID().toString();
    private static final String[] GROUPS = { UUID.randomUUID().toString(), ADMIN_GROUP,
            UUID.randomUUID().toString() };

    private SAMLUserDetailsServiceImpl service;
    private Timer loadAuthenticationTimer;

    /**
     * Setup the tests.
     */
    @Before
    public void setup() {
        final SAMLProperties samlProperties = new SAMLProperties();
        final SAMLProperties.Attributes attributes = new SAMLProperties.Attributes();
        final SAMLProperties.Attributes.User user = new SAMLProperties.Attributes.User();
        user.setName(USER_ATTRIBUTE_NAME);
        attributes.setUser(user);
        final SAMLProperties.Attributes.Groups groups = new SAMLProperties.Attributes.Groups();
        groups.setName(GROUP_ATTRIBUTE_NAME);
        groups.setAdmin(ADMIN_GROUP);
        attributes.setGroups(groups);
        samlProperties.setAttributes(attributes);
        this.loadAuthenticationTimer = Mockito.mock(Timer.class);
        final Registry registry = Mockito.mock(Registry.class);
        Mockito.when(registry.timer(Mockito.anyString())).thenReturn(this.loadAuthenticationTimer);
        this.service = new SAMLUserDetailsServiceImpl(samlProperties, registry);
    }

    /**
     * Test to make sure a null credential throws exception.
     */
    @Test(expected = UsernameNotFoundException.class)
    public void doesThrowErrorOnNullCredential() {
        this.service.loadUserBySAML(null);
        Mockito.verify(this.loadAuthenticationTimer, Mockito.times(1)).record(Mockito.anyLong(),
                Mockito.eq(TimeUnit.NANOSECONDS));
    }

    /**
     * Make sure if no username is found an exception is thrown.
     */
    @Test(expected = UsernameNotFoundException.class)
    public void doesThrowErrorOnUserIdNotFound() {
        final SAMLCredential credential = Mockito.mock(SAMLCredential.class);
        Mockito.when(credential.getAttributeAsString(Mockito.eq(USER_ATTRIBUTE_NAME))).thenReturn(null);
        this.service.loadUserBySAML(credential);
        Mockito.verify(this.loadAuthenticationTimer, Mockito.times(1)).record(Mockito.anyLong(),
                Mockito.eq(TimeUnit.NANOSECONDS));
    }

    /**
     * Make sure if no groups are found but a user id is that the user logs in but only gets role user.
     */
    @Test
    public void canLoadUserWithoutGroups() {
        final SAMLCredential credential = Mockito.mock(SAMLCredential.class);
        Mockito.when(credential.getAttributeAsString(Mockito.eq(USER_ATTRIBUTE_NAME))).thenReturn(USER_ID);
        Mockito.when(credential.getAttributeAsStringArray(Mockito.eq(GROUP_ATTRIBUTE_NAME))).thenReturn(null);
        final Object result = this.service.loadUserBySAML(credential);

        Assert.assertThat(result, Matchers.notNullValue());
        Assert.assertTrue(result instanceof User);
        final User user = (User) result;
        Assert.assertThat(user.getUsername(), Matchers.is(USER_ID));
        Assert.assertThat(user.getAuthorities(), Matchers.contains(new SimpleGrantedAuthority("ROLE_USER")));
        Mockito.verify(this.loadAuthenticationTimer, Mockito.times(1)).record(Mockito.anyLong(),
                Mockito.eq(TimeUnit.NANOSECONDS));
    }

    /**
     * Make sure if user logs in and has admin group they get admin rights.
     */
    @Test
    public void canLoadUserWithAdminGroup() {
        final SAMLCredential credential = Mockito.mock(SAMLCredential.class);
        Mockito.when(credential.getAttributeAsString(Mockito.eq(USER_ATTRIBUTE_NAME))).thenReturn(USER_ID);
        Mockito.when(credential.getAttributeAsStringArray(Mockito.eq(GROUP_ATTRIBUTE_NAME))).thenReturn(GROUPS);
        final Object result = this.service.loadUserBySAML(credential);

        Assert.assertThat(result, Matchers.notNullValue());
        Assert.assertTrue(result instanceof User);
        final User user = (User) result;
        Assert.assertThat(user.getUsername(), Matchers.is(USER_ID));
        Assert.assertThat(user.getAuthorities(), Matchers.hasItems(new SimpleGrantedAuthority("ROLE_USER"),
                new SimpleGrantedAuthority("ROLE_ADMIN")));
        Mockito.verify(this.loadAuthenticationTimer, Mockito.times(1)).record(Mockito.anyLong(),
                Mockito.eq(TimeUnit.NANOSECONDS));
    }

    /**
     * Make sure if user logs in and doesn't have admin group user only gets user role.
     */
    @Test
    public void canLoadUserWithoutAdminGroup() {
        final SAMLCredential credential = Mockito.mock(SAMLCredential.class);
        Mockito.when(credential.getAttributeAsString(Mockito.eq(USER_ATTRIBUTE_NAME))).thenReturn(USER_ID);
        Mockito.when(credential.getAttributeAsStringArray(Mockito.eq(GROUP_ATTRIBUTE_NAME)))
                .thenReturn(new String[] { UUID.randomUUID().toString(), UUID.randomUUID().toString() });
        final Object result = this.service.loadUserBySAML(credential);

        Assert.assertThat(result, Matchers.notNullValue());
        Assert.assertTrue(result instanceof User);
        final User user = (User) result;
        Assert.assertThat(user.getUsername(), Matchers.is(USER_ID));
        Assert.assertThat(user.getAuthorities(), Matchers.contains(new SimpleGrantedAuthority("ROLE_USER")));
        Assert.assertThat(user.getAuthorities().size(), Matchers.is(1));
        Mockito.verify(this.loadAuthenticationTimer, Mockito.times(1)).record(Mockito.anyLong(),
                Mockito.eq(TimeUnit.NANOSECONDS));
    }
}