/**
   * {@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.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.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#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);
 }
 /**
  * {@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#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#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#getAccounts(Site)
  */
 @Override
 public List<JpaAccount> getAccounts(Site site) throws Exception {
   return persistence.getAccounts(site.getIdentifier());
 }
 /**
  * {@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#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#removeAccount(ch.entwine.weblounge.common.site.Site,
  *     java.lang.String)
  */
 public void removeAccount(Site site, String login) throws Exception {
   persistence.removeAccount(site.getIdentifier(), login);
 }