/** * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2016 * * 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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.glite.security.voms.admin.persistence.dao; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; import org.apache.commons.lang.Validate; import org.glite.security.voms.admin.apiv2.VOMSUserJSON; import org.glite.security.voms.admin.configuration.VOMSConfiguration; import org.glite.security.voms.admin.configuration.VOMSConfigurationConstants; import org.glite.security.voms.admin.error.NotFoundException; import org.glite.security.voms.admin.error.NullArgumentException; import org.glite.security.voms.admin.error.VOMSException; import org.glite.security.voms.admin.persistence.HibernateFactory; import org.glite.security.voms.admin.persistence.dao.generic.DAOFactory; import org.glite.security.voms.admin.persistence.dao.lookup.FindByCertificateDAO; import org.glite.security.voms.admin.persistence.dao.lookup.LookupPolicyProvider; import org.glite.security.voms.admin.persistence.error.AlreadyExistsException; import org.glite.security.voms.admin.persistence.error.AlreadyMemberException; import org.glite.security.voms.admin.persistence.error.AttributeAlreadyExistsException; import org.glite.security.voms.admin.persistence.error.AttributeValueAlreadyAssignedException; import org.glite.security.voms.admin.persistence.error.NoSuchAttributeException; import org.glite.security.voms.admin.persistence.error.NoSuchCAException; import org.glite.security.voms.admin.persistence.error.NoSuchGroupException; import org.glite.security.voms.admin.persistence.error.NoSuchUserException; import org.glite.security.voms.admin.persistence.error.UserAlreadyExistsException; import org.glite.security.voms.admin.persistence.error.VOMSDatabaseException; import org.glite.security.voms.admin.persistence.model.AUP; import org.glite.security.voms.admin.persistence.model.AUPAcceptanceRecord; import org.glite.security.voms.admin.persistence.model.AUPVersion; import org.glite.security.voms.admin.persistence.model.Certificate; import org.glite.security.voms.admin.persistence.model.VOMSCA; import org.glite.security.voms.admin.persistence.model.VOMSGroup; import org.glite.security.voms.admin.persistence.model.VOMSMapping; import org.glite.security.voms.admin.persistence.model.VOMSRole; import org.glite.security.voms.admin.persistence.model.VOMSUser; import org.glite.security.voms.admin.persistence.model.VOMSUser.SuspensionReason; import org.glite.security.voms.admin.persistence.model.attribute.VOMSAttributeDescription; import org.glite.security.voms.admin.persistence.model.attribute.VOMSUserAttribute; import org.glite.security.voms.admin.persistence.model.task.SignAUPTask; import org.glite.security.voms.admin.util.DNUtil; import org.hibernate.CacheMode; import org.hibernate.Criteria; import org.hibernate.ObjectNotFoundException; import org.hibernate.Query; import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class VOMSUserDAO implements FindByCertificateDAO<VOMSUser> { private static final Logger log = LoggerFactory.getLogger(VOMSUserDAO.class); public static VOMSUserDAO instance() { HibernateFactory.beginTransaction(); return new VOMSUserDAO(); } private VOMSUserDAO() { } public void requestAUPReacceptance(VOMSUser user, AUP aup) { if (user == null) throw new NullArgumentException("user cannot be null!"); if (aup == null) throw new NullArgumentException("aup cannot be null!"); AUPVersion aupVersion = aup.getActiveVersion(); if (aupVersion == null) throw new NotFoundException( "No registered version found for AUP '" + aup.getName() + "'."); log.debug("User '" + user + "' is request to reaccept aup version '" + aupVersion + "'"); AUPAcceptanceRecord r = user.getAUPAccceptanceRecord(aupVersion); if (r != null) { if (r.getValid()) r.setValid(false); else log.debug("Ignoring invalidation of already invalid record."); } } public void signAUP(VOMSUser user) { signAUP(user, DAOFactory.instance() .getAUPDAO() .getVOAUP()); } public void signAUP(VOMSUser user, AUP aup) { if (user == null) throw new NullArgumentException("user cannot be null!"); if (aup == null) throw new NullArgumentException("aup cannot be null!"); AUPVersion aupVersion = aup.getActiveVersion(); if (aupVersion == null) throw new NotFoundException( "No registered version found for AUP '" + aup.getName() + "'."); log.debug("User '" + user + "' signing aup version '" + aupVersion + "'"); AUPAcceptanceRecord r = user.getAUPAccceptanceRecord(aupVersion); if (r == null) { log.debug("Creating new aup acceptance record!"); AUPAcceptanceRecord aupRecord = new AUPAcceptanceRecord(user, aupVersion); aupRecord.setLastAcceptanceDate(new Date()); user.getAupAcceptanceRecords() .add(aupRecord); } else { log.debug("Updating existing acceptance record"); // User has signed but has been prompted to resign AUPAcceptanceRecord aupRecord = user.getAUPAccceptanceRecord(aupVersion); aupRecord.setLastAcceptanceDate(new Date()); aupRecord.setValid(true); } SignAUPTask pendingTask; do { pendingTask = user.getPendingSignAUPTask(aupVersion.getAup()); if (pendingTask != null) { log.debug("Setting task '" + pendingTask + "' completed"); pendingTask.setCompleted(); } } while (pendingTask != null); if (user.isSuspended() && user.getSuspensionReasonCode() .equals(SuspensionReason.FAILED_TO_SIGN_AUP)) { log.debug("Restoring user '" + user + "'"); user.restore(SuspensionReason.FAILED_TO_SIGN_AUP); } HibernateFactory.getSession() .saveOrUpdate(user); } @SuppressWarnings("unchecked") public List<VOMSUser> findUsersWithPendingSignAUPTask(AUP aup) { String queryString = "from VOMSUser u join u.tasks t where t.class = SignAUPTask and t.status != 'COMPLETED' and t.aup = :aup"; Query q = HibernateFactory.getSession() .createQuery(queryString); q.setEntity("aup", aup); return q.list(); } public Long countExpiredUsers() { Date now = new Date(); String queryString = "select count(*) from VOMSUser u where u.endTime < :now"; Query q = HibernateFactory.getSession() .createQuery(queryString); q.setDate("now", now); return (Long) q.uniqueResult(); } @SuppressWarnings("unchecked") public List<VOMSUser> findExpiredUsers() { Date now = new Date(); String queryString = "from VOMSUser u where u.endTime is not null and u.endTime < :now"; Query q = HibernateFactory.getSession() .createQuery(queryString); q.setDate("now", now); return q.list(); } @SuppressWarnings("unchecked") public List<VOMSUser> findAUPFailingUsers(AUP aup) { List<VOMSUser> result = new ArrayList<VOMSUser>(); AUPVersion activeVersion = aup.getActiveVersion(); // Get users First that do not have any acceptance records for the // active aupVersion String noAcceptanceRecordForActiveAUPVersionQuery = "select u from VOMSUser u where u not in (select u from VOMSUser u join u.aupAcceptanceRecords r where r.aupVersion.active = true)"; Query q = HibernateFactory.getSession() .createQuery(noAcceptanceRecordForActiveAUPVersionQuery); List<VOMSUser> noRecordUsers = q.list(); result.addAll(noRecordUsers); log.debug("Users without acceptance records for currently active aup: {}", result); // Add users that have an expired aup acceptance record due to aup // update or acceptance retriggering. String qString = "select u from VOMSUser u join u.aupAcceptanceRecords r where r.aupVersion.active = true and r.lastAcceptanceDate < :lastUpdateTime"; Query q2 = HibernateFactory.getSession() .createQuery(qString); Date aupLastUpdateTime = activeVersion.getLastUpdateTime(); log.debug("AUP version lastUpdateTime: {}", aupLastUpdateTime); q2.setTimestamp("lastUpdateTime", aupLastUpdateTime); List<VOMSUser> expiredDueToAUPUpdateUsers = q2.list(); result.addAll(expiredDueToAUPUpdateUsers); log.debug("Users that signed the AUP before it was last updated:" + expiredDueToAUPUpdateUsers); // Add users that have a valid aup acceptance record that needs to be // checked against // the reacceptance period Query q3 = HibernateFactory.getSession() .createQuery( "select u from VOMSUser u join u.aupAcceptanceRecords r where r.aupVersion.active = true" + " and r.lastAcceptanceDate > :lastUpdateTime "); q3.setTimestamp("lastUpdateTime", aupLastUpdateTime); List<VOMSUser> potentiallyExpiredUsers = q3.list(); HibernateFactory.getSession() .flush(); log.debug( "Users that needs checking since their aup acceptance record could be expired:" + potentiallyExpiredUsers); for (VOMSUser u : potentiallyExpiredUsers) { AUPAcceptanceRecord r = u.getAUPAccceptanceRecord(aup.getActiveVersion()); if (r.hasExpired()) { log.debug("Adding user{} to results due to expired aup acceptance report (aup validity expiration)", u); result.add(u); } } // Filter out expired users ListIterator<VOMSUser> iter = result.listIterator(); while (iter.hasNext()){ VOMSUser u = iter.next(); if (u.hasExpired() && u.isSuspended()){ log.debug("Removing supended user {} from results since " + "membership expired", u); iter.remove(); } } return result; } public Certificate addCertificate(VOMSUser u, String dn, String caDn) { Validate.notNull(u, "User must be non-null!"); Validate.notEmpty(dn, "DN must be non-null & not empty!"); Validate.notEmpty(caDn, "CA must be non-null & not empty!"); VOMSCA ca = VOMSCADAO.instance() .getByName(caDn); if (ca == null) throw new NoSuchCAException("CA '" + caDn + "' not found in database."); Certificate cert = CertificateDAO.instance() .lookup(dn, caDn); if (cert != null) throw new AlreadyExistsException("Certificate already bound!"); cert = new Certificate(); cert.setSubjectString(dn); cert.setCa(ca); cert.setCreationTime(new Date()); cert.setSuspended(false); cert.setUser(u); u.addCertificate(cert); if (u.isSuspended()) { cert.setSuspended(true); cert.setSuspensionReason(u.getSuspensionReason()); } HibernateFactory.getSession() .saveOrUpdate(cert); HibernateFactory.getSession() .saveOrUpdate(u); return cert; } public Certificate addCertificate(VOMSUser u, X509Certificate x509Cert) { Validate.notNull(u, "User must be non-null!"); Validate.notNull(x509Cert, "Certificate must be non-null!"); // Assume the certificate have been already validated // at this stage. String caDN = DNUtil.getOpenSSLSubject(x509Cert.getIssuerX500Principal()); VOMSCA ca = VOMSCADAO.instance() .getByName(caDN); if (ca == null) throw new NoSuchCAException("CA '" + caDN + "' not recognized!"); Certificate cert = CertificateDAO.instance() .find(x509Cert); if (cert != null) throw new AlreadyExistsException("Certificate already bound!"); cert = new Certificate(); String subjectString = DNUtil .getOpenSSLSubject(x509Cert.getSubjectX500Principal()); cert.setSubjectString(subjectString); cert.setCreationTime(new Date()); cert.setSuspended(false); cert.setCa(ca); cert.setUser(u); if (u.isSuspended()) { cert.setSuspended(true); cert.setSuspensionReason(u.getSuspensionReason()); } u.addCertificate(cert); HibernateFactory.getSession() .saveOrUpdate(cert); HibernateFactory.getSession() .saveOrUpdate(u); return cert; } public void addToGroup(VOMSUser u, VOMSGroup g) { log.debug("Adding user \"" + u + "\" to group \"" + g + "\"."); if (!HibernateFactory.getSession() .contains(u)) { VOMSUser checkUser = findById(u.getId()); if (checkUser == null) throw new NoSuchUserException( "User \"" + u + "\" not found in database."); } // Check that the group exists if (VOMSGroupDAO.instance() .findByName(g.getName()) == null) throw new NoSuchGroupException( "Group \"" + g + "\" is not defined in database."); VOMSMapping m = new VOMSMapping(u, g, null); if (u.getMappings() .contains(m)) throw new AlreadyMemberException( "User \"" + u + "\" is already a member of group \"" + g + "\"."); u.getMappings() .add(m); HibernateFactory.getSession() .save(u); } public void assignRole(VOMSUser u, VOMSGroup g, VOMSRole r) { u.assignRole(g, r); HibernateFactory.getSession() .update(u); } @SuppressWarnings("deprecation") private void checkNullFields(VOMSUser usr) { if (!VOMSConfiguration.instance() .getBoolean("voms.admin.compatibility-mode", true)) { if (usr.getName() == null) throw new NullArgumentException("Please specify a name for the user!"); if (usr.getSurname() == null) throw new NullArgumentException( "Please specify a surname for the user!"); if (usr.getInstitution() == null) throw new NullArgumentException( "Please specify an instituion for the user!"); if (usr.getAddress() == null) throw new NullArgumentException( "Please specify an address for the user!"); if (usr.getPhoneNumber() == null) throw new NullArgumentException( "Please specify a phone number for the user!"); if (usr.getEmailAddress() == null) throw new NullArgumentException( "Please specify an email address for the user!"); } else { if (usr.getDn() == null) throw new NullArgumentException("Please specify a dn for the user!"); if (usr.getEmailAddress() == null) throw new NullArgumentException( "Please specify an email address for the user!"); } } public int countMatches(String searchString) { String sString = "%" + searchString + "%"; String countString = "select count(distinct u) from VOMSUser u join u.certificates as cert where lower(u.surname) like lower(:searchString) " + "or lower(u.name) like lower(:searchString) or u.emailAddress like :searchString " + " or lower(u.institution) like lower(:searchString) " + " or cert.subjectString like(:searchString) or cert.ca.subjectString like(:searchString) " + " order by u.surname asc"; Query q = HibernateFactory.getSession() .createQuery(countString); q.setString("searchString", sString); Long count = (Long) q.uniqueResult(); return count.intValue(); } public Long countUsers() { Query q = HibernateFactory.getSession() .createQuery("select count(*) from VOMSUser"); Long count = (Long) q.uniqueResult(); return count; } public VOMSUser create(String dn, String caDN, String cn, String certURI, String emailAddress) { if (dn == null) throw new NullArgumentException("dn must be non-null!"); if (caDN == null) throw new NullArgumentException("ca must be non-null!"); if (emailAddress == null) throw new NullArgumentException("emailAddress must be non-null!"); dn = DNUtil.normalizeDN(dn); caDN = DNUtil.normalizeDN(caDN); VOMSUser u = lookup(dn, caDN); if (u != null) { throw new UserAlreadyExistsException("User " + u + " already exists!"); } VOMSCA ca = VOMSCADAO.instance() .getByName(caDN); if (ca == null) { throw new NoSuchCAException( "Unknown ca " + caDN + ". Will not create user " + dn); } u = new VOMSUser(); u.setEmailAddress(emailAddress); log.debug("Creating user \"" + u + "\"."); // Add user to default VO group VOMSGroup voGroup = VOMSGroupDAO.instance() .getVOGroup(); HibernateFactory.getSession() .save(u); addToGroup(u, voGroup); return u; } public VOMSUser create(VOMSUserJSON usr, String certificateSubject, String caSubject) { VOMSUser u = VOMSUser.fromVOMSUserJSON(usr); u.setDn(certificateSubject); return create(u, caSubject); } protected Certificate createCertificate(String certificateSubject, String caSubject) { CertificateDAO certDAO = CertificateDAO.instance(); return certDAO.create(certificateSubject, caSubject); } protected Certificate lookupCertificate(String certificateSubject, String certificateIssuer) { CertificateDAO certDAO = CertificateDAO.instance(); Certificate cert = certDAO.lookup(certificateSubject, certificateIssuer); return cert; } protected Certificate assertCertificateIsNotBound(String certificateSubject, String caSubject) { Certificate cert = lookupCertificate(certificateSubject, caSubject); if (cert != null) throw new UserAlreadyExistsException( "A user holding a certificate with the following subject '" + certificateSubject + "' already exists in this VO."); return cert; } protected VOMSUser initUserMembership(VOMSUser user) { Calendar c = Calendar.getInstance(); // Membership start and end time user.setCreationTime(c.getTime()); // Default lifetime for membership is 12 months int lifetime = VOMSConfiguration.instance() .getInt(VOMSConfigurationConstants.DEFAULT_MEMBERSHIP_LIFETIME, 12); c.add(Calendar.MONTH, lifetime); user.setEndTime(c.getTime()); return user; } @SuppressWarnings("deprecation") public VOMSUser create(VOMSUser usr, String caDN) { checkNullFields(usr); Certificate cert = assertCertificateIsNotBound(usr.getDn(), caDN); // Initialize user membership initUserMembership(usr); // Create certificate and link it to the membership cert = createCertificate(usr.getDn(), caDN); usr.addCertificate(cert); HibernateFactory.getSession() .save(usr); // Add user to VO root group VOMSGroup voGroup = VOMSGroupDAO.instance() .getVOGroup(); usr.addToGroup(voGroup); return usr; } public VOMSUser create(VOMSUser usr) { return create(usr, null); } public VOMSUserAttribute createAttribute(VOMSUser u, String attrName, String attrDesc, String value) { if (u.getAttributeByName(attrName) != null) throw new AttributeAlreadyExistsException("Attribute \"" + attrName + "\" already defined for user \"" + u + "\"."); VOMSAttributeDescription desc = VOMSAttributeDAO.instance() .getAttributeDescriptionByName(attrName); if (desc == null) desc = VOMSAttributeDAO.instance() .createAttributeDescription(attrName, attrDesc); log.debug("Creating attribute \"(" + attrName + "," + value + ")\" for user \"" + u + "\"."); VOMSUserAttribute val = VOMSUserAttribute.instance(desc, value, u); u.addAttribute(val); return val; } public VOMSUser delete(Long userId) { VOMSUser u = findById(userId); if (u == null) throw new NoSuchUserException( "User identified by \"" + userId + "\" not found in database!"); try { delete(u); return u; } catch (ObjectNotFoundException e) { // Still don't understand why sometimes findById fails in returnin // null... throw new NoSuchUserException( "User identified by \"" + userId + "\" not found in database!"); } } public VOMSUser delete(VOMSUser u) { log.debug("Deleting user \"{}\"", u); DAOFactory.instance() .getRequestDAO() .deleteRequestFromUser(u); u.getCertificates() .clear(); u.cleanMappings(); u.getAttributes() .clear(); u.getAupAcceptanceRecords() .clear(); u.getPersonalInformations() .clear(); u.getTasks() .clear(); HibernateFactory.getSession() .delete(u); return u; } public void deleteAll() { Iterator<VOMSUser> users = findAll().iterator(); while (users.hasNext()) { delete(users.next()); } } public VOMSUserAttribute deleteAttribute(VOMSUser u, String attrName) { VOMSUserAttribute attribute = u.getAttributeByName(attrName); if (attribute == null) { throw new NoSuchAttributeException( "Attribute \"" + attrName + "\" not defined for user \"" + u + "\"."); } log.debug("Deleting attribute \"{}\" for user \"{}\".", attrName, u); u.deleteAttribute(attribute); HibernateFactory.getSession() .update(u); return attribute; } public void deleteCertificate(Certificate cert) { Validate.notNull(cert, "Cannot delete a null certificate"); VOMSUser u = cert.getUser(); deleteCertificate(u, cert); } public void deleteCertificate(VOMSUser u, Certificate cert) { Validate.notNull(u, "Please provide a non-null user."); Validate.notNull(cert, "Cannot delete a null certificate."); if (u.getCertificates() .size() == 1 && u.hasCertificate(cert)) throw new VOMSException( "User has only one certificate registered, so it cannot be removed!"); if (!u.getCertificates() .remove(cert)) { // This should never happen throw new VOMSDatabaseException( "Inconsistent database! It was not possible to remove certificate '" + cert + "' from user '" + u + "', even if it seemed user actually possessed such certificate."); } } public void dismissRole(VOMSUser u, VOMSGroup g, VOMSRole r) { u.dismissRole(g, r); HibernateFactory.getSession() .update(u); } public VOMSUser findBySubject(String subject) { if (subject == null) throw new NullArgumentException("subject cannot be null!"); String query = "select u from org.glite.security.voms.admin.persistence.model.VOMSUser u join u.certificates c where c.subjectString = :subjectString"; Query q = HibernateFactory.getSession() .createQuery(query); q.setString("subjectString", subject); VOMSUser u = (VOMSUser) q.uniqueResult(); return u; } public VOMSUser findBySubjectAndIssuer(String subject, String issuer) { if (subject == null) { throw new NullArgumentException("subject cannot be null!"); } if (issuer == null) { throw new NullArgumentException("issuer cannot be null!"); } String normalizedSubject = DNUtil.normalizeDN(subject); String normalizedIssuer = DNUtil.normalizeDN(issuer); String query = "select u from VOMSUser u join u.certificates c where c.subjectString = :subjectString and c.ca.subjectString = :issuerSubjectString"; Query q = HibernateFactory.getSession() .createQuery(query); q.setString("subjectString", normalizedSubject); q.setString("issuerSubjectString", normalizedIssuer); VOMSUser u = (VOMSUser) q.uniqueResult(); return u; } public VOMSUser findByEmail(String emailAddress) { if (emailAddress == null) throw new NullArgumentException("emailAddress must be non-null!"); String query = "from org.glite.security.voms.admin.persistence.model.VOMSUser as u where u.emailAddress = :emailAddress"; Query q = HibernateFactory.getSession() .createQuery(query); q.setString("emailAddress", emailAddress); return (VOMSUser) q.uniqueResult(); } public VOMSUser findById(Long userId) { return (VOMSUser) HibernateFactory.getSession() .get(VOMSUser.class, userId); } public List<VOMSUser> findByOrgdbId(Long orgdbId) { CriteriaBuilder builder = HibernateFactory .getSession().getCriteriaBuilder(); CriteriaQuery<VOMSUser> query = builder.createQuery(VOMSUser.class); Root<VOMSUser> userRoot = query.from(VOMSUser.class); query.where(builder.equal(userRoot.get("orgDbId"), orgdbId)); return HibernateFactory.getSession().createQuery(query).getResultList(); } public ScrollableResults findAllWithCursor() { Query q = HibernateFactory.getSession() .createQuery("select u from VOMSUser u order by u.surname asc"); q.setCacheMode(CacheMode.IGNORE) .scroll(ScrollMode.FORWARD_ONLY); return q.scroll(); } @SuppressWarnings("unchecked") public List<VOMSUser> findAll() { Query q = HibernateFactory.getSession() .createQuery("select u from VOMSUser u order by u.surname asc"); List<VOMSUser> result = q.list(); return result; } private SearchResults paginatedFind(Query q, Query countQuery, String searchString, int firstResults, int maxResults) { SearchResults res = SearchResults.instance(); res.setSearchString(searchString); q.setFirstResult(firstResults); q.setMaxResults(maxResults); res.setResults(q.list()); Long count = (Long) countQuery.uniqueResult(); res.setCount(count.intValue()); res.setFirstResult(firstResults); res.setResultsPerPage(maxResults); return res; } private String getUserOrderClause() { // If endTime is ignored by configuration, we should not consider // it for sorting the search results boolean endTimeDisabled = VOMSConfiguration.instance() .getBoolean(VOMSConfigurationConstants.DISABLE_MEMBERSHIP_END_TIME, false); if (endTimeDisabled){ return "order by u.surname asc"; } else { return "order by u.endTime asc, u.surname asc"; } } public SearchResults findAll(int firstResults, int maxResults) { String query = "from VOMSUser as u " + getUserOrderClause(); Query q = HibernateFactory.getSession() .createQuery(query); Query countQ = HibernateFactory.getSession() .createQuery("select count(*) from VOMSUser"); return paginatedFind(q, countQ, null, firstResults, maxResults); } public List<VOMSRole> getUnAssignedRoles(Long userId, Long groupId) { VOMSUser u = findById(userId); VOMSGroup g = VOMSGroupDAO.instance() .findById(groupId); String query = "from VOMSRole r where r not in " + "(select m.role from VOMSMapping m where m.user = :user " + "and m.group = :group and m.role is not null)"; Query<VOMSRole> hq = HibernateFactory.getSession().createQuery(query, VOMSRole.class); hq.setParameter("user", u); hq.setParameter("group", g); List<VOMSRole> result = hq.getResultList(); return result; } public List<VOMSGroup> getUnsubscribedGroups(Long userId) { VOMSUser u = findById(userId); String query = "from VOMSGroup g where g not in " + "(select m.group from VOMSMapping m where m.user = :user " + "and m.role is null)"; Query<VOMSGroup> hq = HibernateFactory.getSession().createQuery(query, VOMSGroup.class); hq.setParameter("user", u); List<VOMSGroup> result = hq.getResultList(); return result; } public void removeFromGroup(VOMSUser u, VOMSGroup g) { log.debug("Removing user \"" + u + "\" from group \"" + g + "\"."); if (VOMSGroupDAO.instance() .findByName(g.getName()) == null) throw new NoSuchGroupException( "Group \"" + g + "\" is not defined in database."); u.removeFromGroup(g); } @SuppressWarnings("unchecked") public List<VOMSUser> findSuspendedUsers() { String queryString = "from VOMSUser u where u.suspended = true"; Query q = HibernateFactory.getSession() .createQuery(queryString); return q.list(); } @SuppressWarnings("unchecked") public List<VOMSUser> findSuspendedUsers(int firstResult, int maxResults) { String queryString = "from VOMSUser u where u.suspended = true"; Query q = HibernateFactory.getSession() .createQuery(queryString); return q.list(); } public Long countSuspendedUsers() { String queryString = "select count(*) from VOMSUser u where u.suspended = true"; Query q = HibernateFactory.getSession() .createQuery(queryString); return (Long) q.uniqueResult(); } public SearchResults searchExpired(String searchString, int firstResults, int maxResults) { log.debug("searchString:" + searchString + ",firstResults: " + firstResults + ",maxResults: " + maxResults); if (searchString == null || searchString.trim() .equals("") || searchString.length() == 0) return findAll(firstResults, maxResults); SearchResults res = SearchResults.instance(); String sString = "%" + searchString + "%"; String queryString = "select distinct u from VOMSUser u join u.certificates as cert where u.expired = true and (lower(u.surname) like lower(:searchString) " + "or lower(u.name) like lower(:searchString) or u.emailAddress like :searchString " + " or lower(u.institution) like lower(:searchString) " + " or cert.subjectString like(:searchString) or cert.ca.subjectString like(:searchString))" + getUserOrderClause(); Query q = HibernateFactory.getSession() .createQuery(queryString); q.setString("searchString", sString); q.setFirstResult(firstResults); q.setMaxResults(maxResults); res.setCount(countMatches(searchString)); res.setFirstResult(firstResults); res.setResultsPerPage(maxResults); res.setResults(q.list()); res.setSearchString(searchString); return res; } public SearchResults searchWithPendingAUPRequest(String searchString, int firstResults, int maxResults) { AUP aup = DAOFactory.instance() .getAUPDAO() .getVOAUP(); String queryString = "from VOMSUser u join u.tasks as t join u.certificates as cert " + "where t.class = SignAUPTask and t.status != 'COMPLETED' " + "and t.aup = :aup"; String commonSearchString = "and (lower(u.surname) like lower(:searchString) " + "or lower(u.name) like lower(:searchString) " + "or u.emailAddress like :searchString " + "or lower(u.institution) like lower(:searchString) " + "or cert.subjectString like(:searchString) " + "or cert.ca.subjectString like(:searchString))"; if (searchStringEmpty(searchString)) { Query q = HibernateFactory.getSession() .createQuery("select distinct u " + queryString) .setEntity("aup", aup); String countQuery = String.format("select count(distinct u) %s", queryString); Query countQ = HibernateFactory.getSession() .createQuery(countQuery) .setEntity("aup", aup); return paginatedFind(q, countQ, null, firstResults, maxResults); } else { String sString = "%" + searchString + "%"; String commonQueryPart = String.format("%s %s", queryString, commonSearchString); Query q = HibernateFactory.getSession() .createQuery(String.format("select distinct u %s", commonQueryPart)) .setEntity("aup", aup); Query count = HibernateFactory.getSession() .createQuery( String.format("select count(distinct u) %s", commonQueryPart)) .setEntity("aup", aup); q.setString("searchString", sString); count.setString("searchString", sString); return paginatedFind(q, count, searchString, firstResults, maxResults); } } public SearchResults searchSuspended(String searchString, int firstResults, int maxResults) { if (searchStringEmpty(searchString)) { Query q = HibernateFactory.getSession() .createQuery("from VOMSUser u where u.suspended = true"); Query countQ = HibernateFactory.getSession() .createQuery( "select count(*) from VOMSUser u where u.suspended = true"); return paginatedFind(q, countQ, null, firstResults, maxResults); } else { String sString = "%" + searchString + "%"; String commonQueryPart = "from VOMSUser u join u.certificates as cert where u.suspended = true and (lower(u.surname) like lower(:searchString) " + "or lower(u.name) like lower(:searchString) or u.emailAddress like :searchString " + " or lower(u.institution) like lower(:searchString) " + " or cert.subjectString like(:searchString) or cert.ca.subjectString like(:searchString))" + getUserOrderClause(); // FIXME: this is *UGLY*, use Criteria API instead Query q = HibernateFactory.getSession() .createQuery(String.format("select distinct u %s", commonQueryPart)); Query count = HibernateFactory.getSession() .createQuery(String.format("select count(*) %s", commonQueryPart)); q.setString("searchString", sString); count.setString("searchString", sString); return paginatedFind(q, count, searchString, firstResults, maxResults); } } private boolean searchStringEmpty(String searchString) { return (searchString == null || searchString.trim() .equals("") || searchString.length() == 0); } public SearchResults search(String searchString, int firstResults, int maxResults) { log.debug("searchString:" + searchString + ",firstResults: " + firstResults + ",maxResults: " + maxResults); if (searchStringEmpty(searchString)) return findAll(firstResults, maxResults); String sString = "%" + searchString + "%"; String commonPart = "from VOMSUser u join u.certificates as cert where lower(u.surname) like lower(:searchString) " + "or lower(u.name) like lower(:searchString) or u.emailAddress like :searchString " + " or lower(u.institution) like lower(:searchString) " + " or cert.subjectString like(:searchString) or cert.ca.subjectString like(:searchString) " + getUserOrderClause(); Query q = HibernateFactory.getSession() .createQuery(String.format("select distinct u %s", commonPart)); Query count = HibernateFactory.getSession() .createQuery(String.format("select count(*) %s", commonPart)); q.setString("searchString", sString); count.setString("searchString", sString); return paginatedFind(q, count, searchString, firstResults, maxResults); } public VOMSUserAttribute setAttribute(VOMSUser u, String attrName, String attrValue) { VOMSAttributeDescription desc = VOMSAttributeDAO.instance() .getAttributeDescriptionByName(attrName); log.debug("AttributeDescription:" + desc); if (desc == null) throw new NoSuchAttributeException( "Attribute '" + attrName + "' is not defined in this vo."); if (!VOMSAttributeDAO.instance() .isAttributeValueAlreadyAssigned(u, desc, attrValue)) { VOMSUserAttribute val = u.getAttributeByName(desc.getName()); if (val == null) { val = VOMSUserAttribute.instance(desc, attrValue, u); u.addAttribute(val); } else val.setValue(attrValue); return val; } throw new AttributeValueAlreadyAssignedException("Value '" + attrValue + "' for attribute '" + attrName + "' has been already assigned to another user in this vo! Choose a different value."); } public VOMSUser update(VOMSUser u) { HibernateFactory.getSession() .update(u); return u; } public Long countExpiringUsers(Integer intervalInDays) { Criteria crit = HibernateFactory.getSession() .createCriteria(VOMSUser.class); Calendar cal = Calendar.getInstance(); Date now = cal.getTime(); cal.add(Calendar.DAY_OF_YEAR, intervalInDays); Date intervalDate = cal.getTime(); crit.add(Restrictions.between("endTime", now, intervalDate)); crit.add(Restrictions.eq("suspended", false)); crit.setProjection(Projections.rowCount()); return (Long) crit.list() .get(0); } @SuppressWarnings("unchecked") public List<VOMSUser> findExpiringUsers(Integer intervalInDays) { Criteria crit = HibernateFactory.getSession() .createCriteria(VOMSUser.class); Calendar cal = Calendar.getInstance(); Date now = cal.getTime(); cal.add(Calendar.DAY_OF_YEAR, intervalInDays); Date intervalDate = cal.getTime(); crit.add(Restrictions.between("endTime", now, intervalDate)); crit.add(Restrictions.eq("suspended", false)); crit.addOrder(Order.asc("endTime")); return crit.list(); } public VOMSUser lookup(String certificateSubject, String certificateIssuer) { return LookupPolicyProvider.instance() .lookupStrategy() .lookup(this, certificateSubject, certificateIssuer); } }