com.formkiq.core.service.SpringSecurityService.java Source code

Java tutorial

Introduction

Here is the source code for com.formkiq.core.service.SpringSecurityService.java

Source

/*
 * Copyright (C) 2016 FormKiQ 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.formkiq.core.service;

import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.util.StringUtils;

import com.formkiq.core.dao.UserDao;
import com.formkiq.core.domain.FolderAccess;
import com.formkiq.core.domain.User;
import com.formkiq.core.domain.type.FolderPermission;
import com.formkiq.core.domain.type.UserRole;
import com.formkiq.core.util.Strings;

/**
 * Spring Security Services.
 *
 */
public class SpringSecurityService {

    /** OAuthService. */
    @Autowired
    private OAuthService oauthservice;

    /** UserDao. */
    @Autowired
    private UserDao userDao;

    /** UserService. */
    @Autowired
    private UserService userservice;

    /**
     * Check Request for Basic Authorization.
     * @param authorization {@link String}
     * @return clientid {@link String}
     */
    public String checkBasicAuthorization(final String authorization) {

        String value = authorization;

        if (!StringUtils.isEmpty(value)) {

            value = value.replaceAll("Basic ", "");
            String[] args = Strings.decode(value, ":");
            String clientid = args[0];
            String clientSecret = args[1];

            if (this.oauthservice.isValidClient(clientid, clientSecret)) {
                return clientid;
            }
        }

        throw new BadCredentialsException("User does not have access to Client");
    }

    /**
     * @return {@link String}
     */
    public String getClientId() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        String clientid = null;

        if (auth instanceof OAuth2Authentication) {

            OAuth2Authentication a = (OAuth2Authentication) auth;
            clientid = a.getOAuth2Request().getClientId();

        } else if (auth instanceof UsernamePasswordAuthenticationToken) {

            User user = this.userDao.findUser(auth.getName());
            clientid = user.getClientid();

        } else {

            throw new UnsupportedOperationException(auth.getClass().getName() + " is not supported");
        }

        return clientid;
    }

    /**
     * Gets the System User.
     * @return {@link UserDetails}
     */
    public UserDetails getSystemUser() {

        User user = new User();
        user.setUserid(UUID.fromString("a549c513-b5d0-4309-b5dc-c6fa970454c9"));
        return user;
    }

    /**
     * @return UserDetails
     */
    public UserDetails getUserDetails() {

        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth instanceof OAuth2Authentication) {
            OAuth2Authentication oauth = (OAuth2Authentication) auth;
            return (UserDetails) oauth.getUserAuthentication().getPrincipal();
        }

        if (auth instanceof UsernamePasswordAuthenticationToken) {
            return (UserDetails) ((UsernamePasswordAuthenticationToken) auth).getPrincipal();
        }

        return null;
    }

    /**
     * Returns user by email only if admin, otherwise
     * current user.
     * @param email {@link String}
     * @return {@link UserDetails}
     */
    public UserDetails getUserDetailsByEmail(final String email) {

        UserDetails user = getUserDetails();

        if (isAdmin() && !StringUtils.isEmpty(email)) {
            // TODO test invalid email
            UserDetails euser = this.userservice.findUserByEmail(email);
            if (euser != null) {
                user = euser;
            }
        }

        if (user == null) {
            throw new BadCredentialsException("User is not authenticated");
        }

        return user;
    }

    /**
     * Get logged in username.
     * @return {@link String}
     */
    public String getUsername() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        return auth != null ? auth.getName() : null;
    }

    /**
     * Whether request has Accept Header.
     * @param headers {@link Enumeration}
     * @param type {@link MediaType}
     * @return boolean
     */
    public boolean hasAcceptHeader(final Enumeration<String> headers, final MediaType type) {

        if (headers != null) {

            while (headers.hasMoreElements()) {
                String accept = headers.nextElement();

                if (accept.contains(type.toString())) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Returns whether has permission.
     * @param accessForm {@link FolderAccess}
     * @param list {@link FolderPermission}
     * @return boolean
     */
    public boolean hasPermission(final FolderAccess accessForm, final FolderPermission... list) {

        if (accessForm != null) {
            List<FolderPermission> perms = toPermissions(accessForm.getPermissions());
            for (FolderPermission up : perms) {

                if (FolderPermission.PERM_FORM_ADMIN.equals(up) || ArrayUtils.contains(list, up)) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Whether User is admin.
     * @return boolean
     */
    public boolean isAdmin() {

        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        if (auth != null) {

            for (GrantedAuthority grantedAuthority : auth.getAuthorities()) {
                if (UserRole.ROLE_ADMIN.name().equals(grantedAuthority.getAuthority())) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Check logged in user.
     * @param email {@link String}
     * @return boolean
     */
    public boolean isUser(final String email) {

        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        return auth != null && email.equals(auth.getName());
    }

    /**
     * Login Spring Security as a particular user.
     * @param userid {@link String}
     * @return {@link UserDetails}
     */
    public UserDetails login(final String userid) {

        UserDetails user = this.userservice.findUser(userid);

        Authentication auth = new OAuth2Authentication(null, new UsernamePasswordAuthenticationToken(user, user));
        SecurityContextHolder.getContext().setAuthentication(auth);

        return user;
    }

    /**
     * Logout of Spring Security.
     */
    public void logout() {
        SecurityContextHolder.getContext().setAuthentication(null);
    }

    /**
     * Convert string permissions to real permissions.
     * @param permissions {@link String}
     * @return {@link List}
     */
    public List<FolderPermission> toPermissions(final String permissions) {
        return toPermissions(permissions.split(","));
    }

    /**
     * Converts permissions to UserPermissions.
     * @param permissions {@link String}
     * @return {@link List}
     */
    public List<FolderPermission> toPermissions(final String[] permissions) {
        List<FolderPermission> perms = Arrays.asList(permissions).stream()
                .map(s -> FolderPermission.valueOf(s.toUpperCase())).collect(Collectors.toList());
        return perms;
    }

    /**
     * Verify user has access to Client.
     * @param clientid {@link String}
     */
    public void verifyUserHasAccessToClient(final String clientid) {

        if (isAdmin() || clientid.equals(getClientId())) {
            return;
        }

        throw new BadCredentialsException("User does not have access to Client");
    }
}