net.webpasswordsafe.server.dao.PasswordDAOHibernate.java Source code

Java tutorial

Introduction

Here is the source code for net.webpasswordsafe.server.dao.PasswordDAOHibernate.java

Source

/*
Copyright 2008-2013 Josh Drummond
    
This file is part of WebPasswordSafe.
    
WebPasswordSafe is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
    
WebPasswordSafe 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 General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with WebPasswordSafe; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
package net.webpasswordsafe.server.dao;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.webpasswordsafe.common.model.AccessLevel;
import net.webpasswordsafe.common.model.Group;
import net.webpasswordsafe.common.model.Password;
import net.webpasswordsafe.common.model.Subject;
import net.webpasswordsafe.common.model.Tag;
import net.webpasswordsafe.common.model.User;
import net.webpasswordsafe.common.util.Constants.Function;
import net.webpasswordsafe.common.util.Constants.Match;
import net.webpasswordsafe.server.plugin.authorization.Authorizer;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Subqueries;
import org.hibernate.impl.SessionFactoryImpl;
import org.hibernate.type.StandardBasicTypes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 * DAO implementation for Password
 * 
 * @author Josh Drummond
 *
 */
@Repository("passwordDAO")
public class PasswordDAOHibernate extends GenericHibernateDAO<Password, Long> implements PasswordDAO {
    @Autowired
    private Authorizer authorizer;

    @Override
    @SuppressWarnings("unchecked")
    public List<Password> findPasswordByFuzzySearch(String query, User user, boolean activeOnly,
            Collection<Tag> tags, Match tagMatch) {
        //kludge to not use ilike on text column if MSSQL
        boolean isMSSQL = ((SessionFactoryImpl) getSessionFactory()).getDialect().toString().contains("SQLServer");
        Criteria crit = getSession().createCriteria(getPersistentClass());
        crit.setFetchMode("tags", FetchMode.JOIN);
        crit.add(Restrictions.or(
                Restrictions.or(Restrictions.ilike("name", query, MatchMode.ANYWHERE),
                        Restrictions.ilike("username", query, MatchMode.ANYWHERE)),
                isMSSQL ? Restrictions.like("notes", query, MatchMode.ANYWHERE)
                        : Restrictions.ilike("notes", query, MatchMode.ANYWHERE)));
        if (activeOnly) {
            crit.add(Restrictions.eq("active", true));
        }
        Criterion tagsCriterion = null;
        for (Tag tag : tags) {
            Criterion tc = Restrictions.sqlRestriction(
                    "? in (select tag_id from password_tags where password_id = {alias}.id)", tag.getId(),
                    StandardBasicTypes.LONG);
            if (null == tagsCriterion) {
                tagsCriterion = tc;
            } else {
                tagsCriterion = tagMatch.equals(Match.AND) ? Restrictions.and(tagsCriterion, tc)
                        : Restrictions.or(tagsCriterion, tc);
            }
        }
        if (tagsCriterion != null)
            crit.add(tagsCriterion);
        crit.createAlias("permissions", "pm");
        crit.add(Restrictions.in("pm.accessLevel",
                new String[] { AccessLevel.READ.name(), AccessLevel.WRITE.name(), AccessLevel.GRANT.name() }));
        if (!authorizer.isAuthorized(user, Function.BYPASS_PASSWORD_PERMISSIONS.name())) {
            DetachedCriteria groupQuery = DetachedCriteria.forClass(Group.class);
            groupQuery.setProjection(Projections.id());
            groupQuery.createCriteria("users", "u").add(Restrictions.eq("u.id", user.getId()));
            crit.add(Restrictions.or(Restrictions.eq("pm.subject", user),
                    Subqueries.propertyIn("pm.subject", groupQuery)));
        }
        crit.addOrder(Order.asc("name"));
        crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return crit.list();
    }

    @Override
    @SuppressWarnings("unchecked")
    public Password findAllowedPasswordById(long passwordId, User user, AccessLevel accessLevel) {
        Password foundPassword = null;
        String sqlAccessLevelIn = null;
        switch (accessLevel) {
        case GRANT:
            sqlAccessLevelIn = "(:aclgrant) ";
            break;
        case WRITE:
            sqlAccessLevelIn = "(:aclwrite, :aclgrant) ";
            break;
        case READ:
            sqlAccessLevelIn = "(:aclread, :aclwrite, :aclgrant) ";
            break;
        }
        StringBuilder hqlString = new StringBuilder();
        hqlString
                .append("select distinct pw.id from Password pw join pw.permissions pm where pw.id = :passwordId ");
        if (!authorizer.isAuthorized(user, Function.BYPASS_PASSWORD_PERMISSIONS.name())) {
            hqlString.append(" and pm.accessLevel in ");
            hqlString.append(sqlAccessLevelIn);
            hqlString.append(
                    "and ((pm.subject = :user) or (pm.subject in (select g from Group g join g.users u where u = :user)))");
        }
        Query hqlQuery = getSession().createQuery(hqlString.toString());
        hqlQuery.setLong("passwordId", passwordId);
        if (!authorizer.isAuthorized(user, Function.BYPASS_PASSWORD_PERMISSIONS.name())) {
            hqlQuery.setEntity("user", user);
            if (accessLevel.equals(AccessLevel.GRANT) || accessLevel.equals(AccessLevel.WRITE)
                    || accessLevel.equals(AccessLevel.READ)) {
                hqlQuery.setString("aclgrant", AccessLevel.GRANT.name());
            }
            if (accessLevel.equals(AccessLevel.WRITE) || accessLevel.equals(AccessLevel.READ)) {
                hqlQuery.setString("aclwrite", AccessLevel.WRITE.name());
            }
            if (accessLevel.equals(AccessLevel.READ)) {
                hqlQuery.setString("aclread", AccessLevel.READ.name());
            }
        }
        List<Long> passwordIds = hqlQuery.list();
        if (passwordIds.size() > 0) {
            foundPassword = findById(passwordIds.get(0));
            foundPassword.getPermissions().size();
            foundPassword.getTags().size();
        }
        return foundPassword;
    }

    @Override
    @SuppressWarnings("unchecked")
    public AccessLevel getMaxEffectiveAccessLevel(Password password, User user) {
        AccessLevel maxEffectiveAccessLevel = null;
        if (authorizer.isAuthorized(user, Function.BYPASS_PASSWORD_PERMISSIONS.name())) {
            maxEffectiveAccessLevel = AccessLevel.GRANT;
        } else {
            StringBuilder hqlString = new StringBuilder();
            hqlString.append("select distinct pm.accessLevel from Permission pm ");
            hqlString.append("where pm.password = :password ");
            hqlString.append("and pm.accessLevel in (:aclread, :aclwrite, :aclgrant) ");
            hqlString.append(
                    "and ((pm.subject = :user) or (pm.subject in (select g from Group g join g.users u where u = :user)))");
            Query hqlQuery = getSession().createQuery(hqlString.toString());
            hqlQuery.setEntity("password", password);
            hqlQuery.setEntity("user", user);
            hqlQuery.setString("aclread", AccessLevel.READ.name());
            hqlQuery.setString("aclwrite", AccessLevel.WRITE.name());
            hqlQuery.setString("aclgrant", AccessLevel.GRANT.name());
            Set<String> accessLevels = new HashSet<String>(hqlQuery.list());
            if (accessLevels.contains(AccessLevel.GRANT.name())) {
                maxEffectiveAccessLevel = AccessLevel.GRANT;
            } else if (accessLevels.contains(AccessLevel.WRITE.name())) {
                maxEffectiveAccessLevel = AccessLevel.WRITE;
            } else if (accessLevels.contains(AccessLevel.READ.name())) {
                maxEffectiveAccessLevel = AccessLevel.READ;
            }
        }
        return maxEffectiveAccessLevel;
    }

    @Override
    public Password findPasswordByName(String passwordName, String username) {
        List<Password> passwords = findByCriteria(
                Restrictions.and(Restrictions.eq("name", passwordName), Restrictions.eq("username", username)));
        return (passwords.size() > 0) ? passwords.get(0) : null;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Password> findPasswordsByPermissionSubject(Subject subject) {
        Query hqlQuery = getSession()
                .createQuery("select distinct p from Password p join p.permissions pm where pm.subject = :subject");
        hqlQuery.setEntity("subject", subject);
        return hqlQuery.list();
    }

}