org.netxilia.api.impl.user.UserServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.netxilia.api.impl.user.UserServiceImpl.java

Source

/*******************************************************************************
 * 
 * Copyright 2010 Alexandru Craciun, and individual contributors as indicated
 * by the @authors tag. 
 * 
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 ******************************************************************************/
package org.netxilia.api.impl.user;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.netxilia.api.INetxiliaSystem;
import org.netxilia.api.command.CellCommands;
import org.netxilia.api.exception.AlreadyExistsException;
import org.netxilia.api.exception.NetxiliaBusinessException;
import org.netxilia.api.exception.NetxiliaResourceException;
import org.netxilia.api.exception.NotFoundException;
import org.netxilia.api.exception.StorageException;
import org.netxilia.api.formula.Formula;
import org.netxilia.api.impl.model.SheetNames;
import org.netxilia.api.impl.model.WorkbookIds;
import org.netxilia.api.model.CellData;
import org.netxilia.api.model.ISheet;
import org.netxilia.api.model.SheetType;
import org.netxilia.api.model.WorkbookId;
import org.netxilia.api.operation.ISheetOperations;
import org.netxilia.api.reference.AreaReference;
import org.netxilia.api.reference.CellReference;
import org.netxilia.api.user.AclPrivilegedMode;
import org.netxilia.api.user.IUserService;
import org.netxilia.api.user.Role;
import org.netxilia.api.user.User;
import org.netxilia.api.utils.Matrix;
import org.netxilia.api.value.IGenericValue;
import org.netxilia.api.value.StringValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class UserServiceImpl implements UserDetailsService, IUserService, ISpringUserService {
    private final static Logger log = Logger.getLogger(UserServiceImpl.class);

    private String userSheetName = SheetNames.USERS;

    @Autowired
    private INetxiliaSystem workbookProcessor;

    @Autowired
    private ISheetOperations sheetOperations;

    public INetxiliaSystem getWorkbookProcessor() {
        return workbookProcessor;
    }

    public void setWorkbookProcessor(INetxiliaSystem workbookProcessor) {
        this.workbookProcessor = workbookProcessor;
    }

    public String getUserSheetName() {
        return userSheetName;
    }

    public void setUserSheetName(String userSheetName) {
        this.userSheetName = userSheetName;
    }

    public ISheetOperations getSheetOperations() {
        return sheetOperations;
    }

    public void setSheetOperations(ISheetOperations sheetOperations) {
        this.sheetOperations = sheetOperations;
    }

    protected ISheet getUsersSheet() throws StorageException, NotFoundException {
        try {
            return workbookProcessor.getWorkbook(WorkbookIds.SYSTEM).getSheet(userSheetName);
        } catch (NotFoundException e) {
            return null;
        }

    }

    protected ISheet getWriteableUsersSheet() throws StorageException, NotFoundException {
        try {
            return workbookProcessor.getWorkbook(WorkbookIds.SYSTEM).getSheet(userSheetName);
        } catch (NotFoundException e) {
            try {
                return workbookProcessor.getWorkbook(WorkbookIds.SYSTEM).addNewSheet(userSheetName,
                        SheetType.normal);
            } catch (AlreadyExistsException e1) {
                // try one more time
                return workbookProcessor.getWorkbook(WorkbookIds.SYSTEM).getSheet(userSheetName);
            }
        }

    }

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
        ISheet sheet = null;
        try {
            log.info("Load user details for " + userName);
            AclPrivilegedMode.set();
            sheet = getUsersSheet();
            if (sheet == null) {
                throw new UsernameNotFoundException(userName);
            }
            CellReference ref = sheetOperations.find(sheet, null, new Formula("=A1=\"" + userName + "\""))
                    .getNonBlocking();
            if (ref == null) {
                throw new UsernameNotFoundException(userName);
            }
            // A=username
            // B=password
            // all=ROLE_USER,
            // ROLE_ADMIN=?

            Matrix<CellData> cells = sheet
                    .receiveCells(new AreaReference(null, ref.getRowIndex(), 0, ref.getRowIndex(), 3))
                    .getNonBlocking();
            String password = cells.get(0, 1).getValue().getStringValue();
            String roles = cells.get(0, 3).getValue().getStringValue();
            String[] rolesArray = StringUtils.split(roles, ",");
            Role[] netxiliaRoles = new Role[rolesArray.length];
            GrantedAuthority[] springRoles = new GrantedAuthority[rolesArray.length];
            for (int i = 0; i < rolesArray.length; ++i) {
                springRoles[i] = new GrantedAuthorityImpl(rolesArray[i]);
                netxiliaRoles[i] = Role.valueOf(rolesArray[i]);
            }

            User netxiliaUser = new User();
            netxiliaUser.setLogin(userName);
            netxiliaUser.setPassword(password);
            netxiliaUser.setRoles(netxiliaRoles);

            SpringUserAdapter springUser = new SpringUserAdapter(netxiliaUser, true, true, true, true, springRoles);
            log.info("Done user details for " + userName);
            return springUser;
        } catch (NotFoundException e) {
            throw new DataRetrievalFailureException("Sheet 'system.users' not found", e);

        } catch (StorageException e) {
            throw new DataRetrievalFailureException("Sheet 'system.users' not found", e);
        } catch (NetxiliaResourceException e) {
            throw new DataRetrievalFailureException("Sheet 'system.users' not found", e);
        } catch (NetxiliaBusinessException e) {
            throw new DataRetrievalFailureException("Sheet 'system.users' not found", e);
        } finally {
            AclPrivilegedMode.clear();
        }

    }

    @Override
    public void addUser(User user) throws StorageException {
        ISheet sheet = null;

        Map<String, IGenericValue> values = new HashMap<String, IGenericValue>();
        values.put("A", new StringValue(user.getLogin()));
        values.put("B", new StringValue(user.getPassword()));
        if (user.getEmail() != null) {
            values.put("C", new StringValue(user.getEmail().getEmail()));
        }
        values.put("D", new StringValue(StringUtils.join(user.getRoles(), ',')));
        try {
            AclPrivilegedMode.set();
            sheet = getWriteableUsersSheet();
            sheet.sendCommand(CellCommands.mapValues(AreaReference.lastRow(0, 3), values));

        } catch (NotFoundException e) {
            // should not happen as the sheet was previously created
            throw new RuntimeException(e);
        } finally {
            AclPrivilegedMode.clear();
        }

    }

    @Override
    public boolean isAdminAccountCreated() throws NetxiliaResourceException, NetxiliaBusinessException {
        ISheet sheet = null;
        try {
            AclPrivilegedMode.set();
            sheet = getUsersSheet();
            if (sheet == null) {
                return false;
            }
            List<Integer> rows = sheetOperations.filter(sheet, new Formula("=D1=\"ROLE_ADMIN\"")).getNonBlocking();
            return rows != null && rows.size() > 0;
        } catch (NotFoundException e) {
            return false;
        } finally {
            AclPrivilegedMode.clear();
        }

    }

    @Override
    public User getCurrentUser() {
        if (SecurityContextHolder.getContext() != null
                && SecurityContextHolder.getContext().getAuthentication() != null) {
            if (!(SecurityContextHolder.getContext().getAuthentication()
                    .getPrincipal() instanceof SpringUserAdapter)) {
                return null;
            }
            SpringUserAdapter springUserAdapter = (SpringUserAdapter) SecurityContextHolder.getContext()
                    .getAuthentication().getPrincipal();
            if (springUserAdapter != null) {
                return springUserAdapter.getNetxiliaUser();
            }
        }

        return null;
    }

    public Authentication getSpringAuthentication() {
        if (SecurityContextHolder.getContext() != null) {
            return SecurityContextHolder.getContext().getAuthentication();
        }
        return null;
    }

    public void setSpringAuthentication(Authentication auth) {
        if (SecurityContextHolder.getContext() != null) {
            SecurityContextHolder.getContext().setAuthentication(auth);
        }

    }

    @Override
    public WorkbookId getWorkbookId() {
        return WorkbookIds.SYSTEM;
    }
}