Package ch.entwine.weblounge.security.sql.impl

Source Code of ch.entwine.weblounge.security.sql.impl.SQLDirectoryProviderImpl

/*
*  Weblounge: Web Content Management System
*  Copyright (c) 2011 The Weblounge Team
*  http://weblounge.o2it.ch
*
*  This program 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 2
*  of the License, or (at your option) any later version.
*
*  This program 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 program; if not, write to the Free Software Foundation
*  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package ch.entwine.weblounge.security.sql.impl;

import static ch.entwine.weblounge.common.impl.security.SystemRole.EDITOR;
import static ch.entwine.weblounge.common.impl.security.SystemRole.GUEST;
import static ch.entwine.weblounge.common.impl.security.SystemRole.PUBLISHER;
import static ch.entwine.weblounge.common.impl.security.SystemRole.SITEADMIN;
import static ch.entwine.weblounge.common.impl.security.SystemRole.SYSTEMADMIN;

import ch.entwine.weblounge.common.impl.security.PasswordImpl;
import ch.entwine.weblounge.common.impl.security.RoleImpl;
import ch.entwine.weblounge.common.impl.security.SecurityUtils;
import ch.entwine.weblounge.common.impl.security.WebloungeUserImpl;
import ch.entwine.weblounge.common.security.DigestType;
import ch.entwine.weblounge.common.security.DirectoryService;
import ch.entwine.weblounge.common.security.Role;
import ch.entwine.weblounge.common.security.Security;
import ch.entwine.weblounge.common.security.User;
import ch.entwine.weblounge.common.security.UserExistsException;
import ch.entwine.weblounge.common.security.UserShadowedException;
import ch.entwine.weblounge.common.security.WebloungeUser;
import ch.entwine.weblounge.common.site.Site;
import ch.entwine.weblounge.security.sql.SQLDirectoryProvider;
import ch.entwine.weblounge.security.sql.SQLDirectoryProviderPersistence;
import ch.entwine.weblounge.security.sql.entities.JpaAccount;
import ch.entwine.weblounge.security.sql.entities.JpaRole;

import org.apache.commons.lang.StringUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
* This directory provider connects to a central database that can hold users
* for multiple sites.
*/
public class SQLDirectoryProviderImpl implements SQLDirectoryProvider {

  /** The logging facility */
  private static final Logger logger = LoggerFactory.getLogger(SQLDirectoryProviderImpl.class);

  /** Identifier of this directory provider */
  private static final String PROVIDER_IDENTIFIER = "weblounge-sql-database";

  /** The bundle context */
  private BundleContext bundleCtx = null;

  /** The persistence layer */
  private SQLDirectoryProviderPersistence persistence = null;

  /**
   * OSGi callback on component activation.
   *
   * @param context
   *          the context
   */
  void activate(ComponentContext context) {
    this.bundleCtx = context.getBundleContext();
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.security.DirectoryService#loadUser(java.lang.String,
   *      ch.entwine.weblounge.common.site.Site)
   */
  public User loadUser(String login, Site site) {
    JpaAccount jpaAccount = null;

    // Load the user account and the user
    try {
      jpaAccount = persistence.getAccount(site.getIdentifier(), login, true);
    } catch (Throwable e) {
      logger.error("Error loading user '{}' from the database: {}", login, e.getMessage());
      return null;
    }

    // Is that user known
    if (jpaAccount == null) {
      logger.debug("User '{}' is not known in site '{}'", login, site.getIdentifier());
      return null;
    }

    // Create the weblounge user

    WebloungeUser user = new WebloungeUserImpl(login, site.getIdentifier());

    // Standard attributes like first name, name, ...
    if (StringUtils.isNotBlank(jpaAccount.getFirstname()))
      user.setFirstName(jpaAccount.getFirstname());
    if (StringUtils.isNotBlank(jpaAccount.getLastname()))
      user.setLastName(jpaAccount.getLastname());
    if (StringUtils.isNotBlank(jpaAccount.getEmail()))
      user.setEmail(jpaAccount.getEmail());
    if (StringUtils.isNotBlank(jpaAccount.getInitials()))
      user.setInitials(jpaAccount.getInitials());

    // Password
    user.addPrivateCredentials(new PasswordImpl(jpaAccount.getPassword(), DigestType.md5));

    // Roles
    for (JpaRole r : jpaAccount.getRoles()) {

      // Make sure weblounge roles get special treatment in order
      // to support role inheritance. Other directories will need
      // to implement this through a LoginListener implementation
      if (Security.SYSTEM_CONTEXT.equals(r.getContext())) {
        if (SYSTEMADMIN.getIdentifier().equals(r.getRolename())) {
          user.addPublicCredentials(SYSTEMADMIN);
        } else if (SITEADMIN.getIdentifier().equals(r.getRolename())) {
          user.addPublicCredentials(SITEADMIN);
        } else if (PUBLISHER.getIdentifier().equals(r.getRolename())) {
          user.addPublicCredentials(PUBLISHER);
        } else if (EDITOR.getIdentifier().equals(r.getRolename())) {
          user.addPublicCredentials(EDITOR);
        } else if (GUEST.getIdentifier().equals(r.getRolename())) {
          user.addPublicCredentials(GUEST);
        }
      } else {
        user.addPublicCredentials(new RoleImpl(r.getContext(), r.getRolename()));
      }
    }

    return user;
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.security.DirectoryService#getRoles()
   */
  public Role[] getRoles() {
    return new Role[] {};
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.security.DirectoryService#getLocalRole(ch.entwine.weblounge.common.security.Role)
   */
  public Role getLocalRole(Role role) {
    return role;
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.security.DirectoryService#getSystemRoles(ch.entwine.weblounge.common.security.Role)
   */
  public Role[] getSystemRoles(Role role) {
    return new Role[] {};
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.security.DirectoryProvider#getIdentifier()
   */
  public String getIdentifier() {
    return PROVIDER_IDENTIFIER;
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#addAccount(ch.entwine.weblounge.common.site.Site,
   *      java.lang.String, String)
   */
  public JpaAccount addAccount(Site site, String user, String password)
      throws Exception {

    // Check for existing administrative accounts with the same login
    ServiceReference userDirectoryRef = bundleCtx.getServiceReference(DirectoryService.class.getName());
    if (userDirectoryRef != null) {
      DirectoryService systemDirectory = (DirectoryService) bundleCtx.getService(userDirectoryRef);
      logger.debug("Checking new site '{}' user '{}' for shadowing of site or system account");
      User shadowedUser = systemDirectory.loadUser(user, site);
      if (shadowedUser != null) {
        if (SecurityUtils.userHasRole(shadowedUser, SYSTEMADMIN))
          throw new UserShadowedException("Site '" + site.getIdentifier() + "' account '" + user + "' is shadowing the system account");
        else if (SecurityUtils.userHasRole(shadowedUser, SITEADMIN))
          throw new UserShadowedException("Site '" + site.getIdentifier() + "' account '" + user + "' is shadowing the site account");
        else
          throw new UserExistsException("Site '" + site.getIdentifier() + "' account '" + user + "' already exists");
      }
    } else {
      logger.warn("Directory service not found, site '{}' user '{}' cannot be checked for user shadowing", site.getIdentifier(), user);
    }
   
    return persistence.addAccount(site.getIdentifier(), user, password);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#removeAccount(ch.entwine.weblounge.common.site.Site,
   *      java.lang.String)
   */
  public void removeAccount(Site site, String login) throws Exception {
    persistence.removeAccount(site.getIdentifier(), login);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#updateAccount(ch.entwine.weblounge.security.sql.entities.JpaAccount)
   */
  public void updateAccount(JpaAccount account) throws Exception {
    persistence.updateAccount(account);
    logger.info("Account '{}@{}' has been updated", account.getLogin(), account.getSite().getName());
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#getAccount(ch.entwine.weblounge.common.site.Site,
   *      java.lang.String)
   */
  public JpaAccount getAccount(Site site, String login) throws Exception {
    return getAccount(site, login, false);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#getAccount(ch.entwine.weblounge.common.site.Site,
   *      java.lang.String, boolean)
   */
  @Override
  public JpaAccount getAccount(Site site, String login, boolean enabledOnly)
      throws Exception {
    return persistence.getAccount(site.getIdentifier(), login, enabledOnly);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#getAccounts(Site)
   */
  @Override
  public List<JpaAccount> getAccounts(Site site) throws Exception {
    return persistence.getAccounts(site.getIdentifier());
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#activateAccount(ch.entwine.weblounge.common.site.Site,
   *      java.lang.String, java.lang.String)
   */
  public boolean activateAccount(Site site, String login, String activationCode)
      throws Exception {
    if (StringUtils.isBlank(login))
      throw new IllegalArgumentException("Login must not be blank");
    if (StringUtils.isBlank(activationCode))
      throw new IllegalArgumentException("Activation code must not be blank");
    JpaAccount account = persistence.getAccount(site.getIdentifier(), login, true);
    if (account == null)
      return false;
    if (!activationCode.equals(account.getActivationCode()))
      return false;

    account.setEnabled(true);
    account.setActivationCode(null);
    persistence.updateAccount(account);
    logger.info("Account '{}' has been activated", login);
    return true;
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#enableSite(ch.entwine.weblounge.common.site.Site)
   */
  public void enableSite(Site site) throws Exception {
    persistence.enableSite(site.getIdentifier());
    logger.info("Logins into site '{}' have been enabled", site.getIdentifier());
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#disableSite(ch.entwine.weblounge.common.site.Site)
   */
  public void disableSite(Site site) throws Exception {
    persistence.disableSite(site.getIdentifier());
    logger.info("Logins into site '{}' have been disabled", site.getIdentifier());
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#isSiteEnabled(ch.entwine.weblounge.common.site.Site)
   */
  @Override
  public boolean isSiteEnabled(Site site) throws Exception {
    return persistence.isSiteEnabled(site.getIdentifier());
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#enableAccount(ch.entwine.weblounge.common.site.Site,
   *      java.lang.String)
   */
  public void enableAccount(Site site, String user) throws Exception {
    persistence.enableAccount(site.getIdentifier(), user);
    logger.info("Logins into account '{}@{}' have been enabled", user, site.getIdentifier());
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#disableAccount(ch.entwine.weblounge.common.site.Site,
   *      java.lang.String)
   */
  public void disableAccount(Site site, String user) throws Exception {
    persistence.disableAccount(site.getIdentifier(), user);
    logger.info("Logins into account '{}@{}' have been disabled", user, site.getIdentifier());
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.security.sql.SQLDirectoryProvider#isAccountEnabled(ch.entwine.weblounge.common.site.Site,
   *      java.lang.String)
   */
  @Override
  public boolean isAccountEnabled(Site site, String user) throws Exception {
    return persistence.isAccountEnabled(site.getIdentifier(), user);
  }

  /**
   * OSGi Declarative Services callback to set the persistence layer that is
   * instantiated using Blueprint Services.
   *
   * @param persistence
   *          the persistence layer
   */
  void setPersistence(SQLDirectoryProviderPersistence persistence) {
    this.persistence = persistence;
  }

}
TOP

Related Classes of ch.entwine.weblounge.security.sql.impl.SQLDirectoryProviderImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.