org.schedoscope.metascope.service.MetascopeUserService.java Source code

Java tutorial

Introduction

Here is the source code for org.schedoscope.metascope.service.MetascopeUserService.java

Source

/**
 * Copyright 2017 Otto (GmbH & Co KG)
 * <p>
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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 org.schedoscope.metascope.service;

import org.schedoscope.metascope.config.MetascopeConfig;
import org.schedoscope.metascope.model.MetascopeMetadata;
import org.schedoscope.metascope.model.MetascopeTable;
import org.schedoscope.metascope.model.MetascopeUser;
import org.schedoscope.metascope.model.MetascopeUser.Role;
import org.schedoscope.metascope.repository.MetascopeMetadataRepository;
import org.schedoscope.metascope.repository.MetascopeUserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.ldap.userdetails.LdapUserDetailsImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
public class MetascopeUserService {

    private static final Logger LOG = LoggerFactory.getLogger(MetascopeUserService.class);

    @Autowired
    private MetascopeUserRepository metascopeUserRepository;
    @Autowired
    private MetascopeMetadataRepository metascopeMetadataRepository;
    @Autowired
    private LdapTemplate ldap;
    @Autowired
    private MetascopeConfig config;

    /**
     * Checks if the user browsing the application is logged in
     *
     * @return true if the user is logged in, false otherwise
     */
    public boolean isAuthenticated() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            Object principal = authentication.getPrincipal();
            return (principal instanceof String) == false;
        }
        return false;
    }

    /**
     * Get the user object for the logged in user
     *
     * @return
     * @throws NamingException
     */
    public MetascopeUser getUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication == null) {
            return null;
        }

        Object principal = authentication.getPrincipal();

        if (principal instanceof LdapUserDetailsImpl) {
            LdapUserDetailsImpl ldapUser = (LdapUserDetailsImpl) principal;
            MetascopeUser userEntity = metascopeUserRepository.findByUsername(ldapUser.getUsername());
            if (userEntity == null) {
                createUser(ldapUser.getUsername(), "", "", sha256("" + System.currentTimeMillis()), false, null);
            }

            // sync user with ldap
            userEntity = metascopeUserRepository.findByUsername(ldapUser.getUsername());
            DirContextAdapter dca = (DirContextAdapter) ldap.lookup(ldapUser.getDn());
            Attributes attr = dca.getAttributes();
            String mail = "";
            String fullname = "";
            try {
                mail = (String) attr.get("mail").get();
                fullname = (String) attr.get("displayName").get();
            } catch (NamingException e) {
                // if not found, ignore ..
            }
            boolean admin = false;
            for (GrantedAuthority authoritiy : ldapUser.getAuthorities()) {
                for (String adminGroup : config.getAdminGroups().split(",")) {
                    String role = "ROLE_" + adminGroup.toUpperCase();
                    if (authoritiy.getAuthority().equalsIgnoreCase(role)) {
                        admin = true;
                    }
                }
            }

            boolean changes = false;
            if (userEntity.getEmail() == null || !userEntity.getEmail().equals(mail)) {
                userEntity.setEmail(mail);
                changes = true;
            }
            if (userEntity.getFullname() == null || !userEntity.getFullname().equals(fullname)) {
                userEntity.setFullname(fullname);
                changes = true;
            }

            if (admin) {
                if (!userEntity.isAdmin()) {
                    changes = true;
                }
                userEntity.setUserrole(Role.ROLE_ADMIN);
            } else {
                if (userEntity.isAdmin()) {
                    changes = true;
                }
                userEntity.setUserrole(Role.ROLE_USER);
            }

            if (changes) {
                metascopeUserRepository.save(userEntity);
            }
            return userEntity;
        } else if (principal instanceof User) {
            User userDetails = (User) principal;
            MetascopeUser user = metascopeUserRepository.findByUsername(userDetails.getUsername());

            if (user == null) {
                LOG.warn("User from session not found. username={}", userDetails.getUsername());
                return null;
            }

            return user;
        }

        return null;
    }

    public Iterable<MetascopeUser> getAllUser() {
        return metascopeUserRepository.findAll();
    }

    public List<String> getAllFullNames() {
        List<String> names = new ArrayList<String>();
        for (MetascopeUser user : getAllUser()) {
            names.add(user.getFullname());
        }
        return names;
    }

    public MetascopeUser findByUsername(String username) {
        return metascopeUserRepository.findByUsername(username);
    }

    public MetascopeUser findByFullname(String fullname) {
        return metascopeUserRepository.findByFullname(fullname);
    }

    /**
     * Checks if a user exists
     *
     * @param username username which is checked if it already exists
     * @return true if user already exist, false otherwise
     */
    public boolean userExists(String username) {
        return username != null && metascopeUserRepository.findByUsername(username) != null;
    }

    /**
     * Checks if an email exists
     *
     * @param email email which is checked if it already exists
     * @return true if email already exist, false otherwise
     */
    public boolean emailExists(String email) {
        return email != null && metascopeUserRepository.findByEmail(email) != null;
    }

    /**
     * Registers a user in the database
     *
     * @param username username of the new user
     * @param email    email of the new user
     * @param fullname the full name of the user
     * @param password password of the new user
     * @param admin    has admin rights
     * @param group    the associcated group of the user
     * @return The new user object
     */
    @Transactional
    public void createUser(String username, String email, String fullname, String password, boolean admin,
            String group) {
        if (!isAuthenticated()) {
            return;
        }

        MetascopeUser user = new MetascopeUser();
        user.setUsername(username);
        user.setEmail(email);
        user.setFullname(fullname);
        user.setPasswordHash(sha256(password));
        user.setUsergroup(group);
        user.setFavourites(Collections.<String>emptyList());
        if (admin) {
            user.setUserrole(Role.ROLE_ADMIN);
        } else {
            user.setUserrole(Role.ROLE_USER);
        }
        metascopeUserRepository.save(user);
        LOG.info("User '{}' has created a new user '{}'", getUser().getUsername(), username);
    }

    @Transactional
    public void editUser(String username, String email, String fullname, String password, boolean admin,
            String group) {
        if (!isAuthenticated()) {
            return;
        }

        MetascopeUser user = metascopeUserRepository.findByUsername(username);

        if (!user.getEmail().equals(email)) {
            return;
        }

        user.setFullname(fullname);

        if (!password.isEmpty()) {
            user.setPasswordHash(sha256(password));
        }

        user.setUsergroup(group);
        if (admin) {
            user.setUserrole(Role.ROLE_ADMIN);
        } else {
            user.setUserrole(Role.ROLE_USER);
        }
        metascopeUserRepository.save(user);
        LOG.info("User '{}' has edited the user '{}'", getUser().getUsername(), username);
    }

    @Transactional
    public void deleteUser(String username) {
        if (!isAuthenticated()) {
            return;
        }

        MetascopeUser user = metascopeUserRepository.findByUsername(username);

        if (user == null) {
            return;
        }

        String thisUser = getUser().getUsername();
        metascopeUserRepository.delete(user);

        LOG.info("User '{}' has deleted the user '{}'", thisUser, username);
    }

    public List<String> getFavourites() {
        return getUser().getFavourites();
    }

    public boolean isAdmin() {
        if (getUser().isAdmin()) {
            return true;
        }

        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        if (principal instanceof LdapUserDetailsImpl) {
            LdapUserDetailsImpl ldapUser = (LdapUserDetailsImpl) principal;
            for (GrantedAuthority authoritiy : ldapUser.getAuthorities()) {
                for (String adminGroup : config.getAdminGroups().split(",")) {
                    String role = "ROLE_" + adminGroup.toUpperCase();
                    if (authoritiy.getAuthority().equalsIgnoreCase(role)) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    public void createAdminAccount() {
        MetascopeUser adminUser = metascopeUserRepository.findByUsername("admin");
        MetascopeMetadata alreadyCreated = metascopeMetadataRepository.findOne("adminCreated");
        if (adminUser == null && alreadyCreated == null) {
            adminUser = new MetascopeUser();
            adminUser.setUsername("admin");
            adminUser.setPasswordHash("8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"); // sha256("admin")
            adminUser.setFullname("Admin");
            adminUser.setUserrole("ROLE_ADMIN");
            adminUser.setUsergroup("BUSINESS_USER");
            adminUser.setEmail("admin@metascope.com");
            metascopeUserRepository.save(adminUser);
        }
    }

    private String sha256(String password) {
        return new ShaPasswordEncoder(256).encodePassword(password, null);
    }

    public void logoutUser(SessionRegistry sessionRegistry, String username) {
        final List<Object> allPrincipals = sessionRegistry.getAllPrincipals();
        for (final Object principal : allPrincipals) {
            if (principal instanceof User) {
                User springUserDetails = (User) principal;
                if (springUserDetails.getUsername().equals(username)) {
                    for (SessionInformation sessionInformation : sessionRegistry.getAllSessions(principal, true)) {
                        sessionInformation.expireNow();
                    }
                }
            }
        }
    }

    public void setmetascopeUserRepository(MetascopeUserRepository metascopeUserRepository) {
        this.metascopeUserRepository = metascopeUserRepository;
    }

    public boolean isFavourite(MetascopeTable table) {
        List<String> favourites = getFavourites();
        for (String fav : favourites) {
            if (table.getFqdn().equals(fav)) {
                return true;
            }
        }
        return false;
    }

    public void save(MetascopeUser user) {
        this.metascopeUserRepository.save(user);
    }

}