diff --git a/src/main/java/org/olat/basesecurity/AuthHelper.java b/src/main/java/org/olat/basesecurity/AuthHelper.java index 76a9a83726779edfb02bdb1d340c1fcf78105315..1352d2abf5a1bdc060f14178c46896787d4dbdc5 100644 --- a/src/main/java/org/olat/basesecurity/AuthHelper.java +++ b/src/main/java/org/olat/basesecurity/AuthHelper.java @@ -32,11 +32,11 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.UUID; import javax.servlet.http.Cookie; import javax.servlet.http.HttpSession; +import org.olat.basesecurity.manager.GroupDAO; import org.olat.commons.rss.RSSUtil; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.fullWebApp.BaseFullWebappController; @@ -70,6 +70,7 @@ import org.olat.core.util.prefs.Preferences; import org.olat.core.util.session.UserSessionManager; import org.olat.login.AuthBFWCParts; import org.olat.login.GuestBFWCParts; +import org.olat.portfolio.manager.InvitationDAO; import org.olat.user.UserManager; import org.olat.util.logging.activity.LoggingResourceable; @@ -221,14 +222,16 @@ public class AuthHelper { } public static int doInvitationLogin(String invitationToken, UserRequest ureq, Locale locale) { - boolean hasPolicies = BaseSecurityManager.getInstance().hasInvitationPolicies(invitationToken, new Date()); + InvitationDAO invitationDao = CoreSpringFactory.getImpl(InvitationDAO.class); + boolean hasPolicies = invitationDao.hasInvitations(invitationToken, new Date()); if(!hasPolicies) { return LOGIN_DENIED; } UserManager um = UserManager.getInstance(); BaseSecurity securityManager = BaseSecurityManager.getInstance(); - Invitation invitation = securityManager.findInvitation(invitationToken); + GroupDAO groupDao = CoreSpringFactory.getImpl(GroupDAO.class); + Invitation invitation = invitationDao.findInvitation(invitationToken); if(invitation == null) { return LOGIN_DENIED; } @@ -242,8 +245,8 @@ public class AuthHelper { return LOGIN_DENIED; } else { //fxdiff FXOLAT-151: add eventually the identity to the security group - if(!securityManager.isIdentityInSecurityGroup(identity, invitation.getSecurityGroup())) { - securityManager.addIdentityToSecurityGroup(identity, invitation.getSecurityGroup()); + if(!groupDao.hasRole(invitation.getBaseGroup(), identity, GroupRoles.invitee.name())) { + groupDao.addMembership(invitation.getBaseGroup(), identity, GroupRoles.invitee.name()); DBFactory.getInstance().commit(); } @@ -262,13 +265,8 @@ public class AuthHelper { } //invitation ok -> create a temporary user - //TODO make an username beautifier??? - String tempUsername = UUID.randomUUID().toString(); - User user = UserManager.getInstance().createAndPersistUser(invitation.getFirstName(), invitation.getLastName(), invitation.getMail()); - user.getPreferences().setLanguage(locale.toString()); - Identity invited = securityManager.createAndPersistIdentity(tempUsername, user, null, null, null); - securityManager.addIdentityToSecurityGroup(invited, invitation.getSecurityGroup()); - return doLogin(invited, BaseSecurityModule.getDefaultAuthProviderIdentifier(), ureq); + Identity invitee = invitationDao.createIdentityFrom(invitation, locale); + return doLogin(invitee, BaseSecurityModule.getDefaultAuthProviderIdentifier(), ureq); } /** diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java index f56672dd8633013754e9f04152780b45b7ed2167..9e4917a688070726a8786613d90513cdf11389de 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurity.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java @@ -62,21 +62,6 @@ public interface BaseSecurity { */ public boolean isIdentityPermittedOnResourceable(Identity identity, String permission, OLATResourceable olatResourceable); - /** - * Return the list of "allowed to..." - * @param identity - * @param olatResourceable - * @return - */ - public List<String> getIdentityPermissionOnresourceable(Identity identity, OLATResourceable olatResourceable); - - /** - * - * @param permission - * @param olatResourceableTypeName - * @return - */ - public List<Identity> getIdentitiesWithPermissionWithOlatResourceableType(String permission, String olatResourceableTypeName); /** @@ -463,89 +448,11 @@ public interface BaseSecurity { * @return the newly created policy */ public Policy createAndPersistPolicy(SecurityGroup secGroup, String permission, OLATResourceable olatResourceable); - - public Policy createAndPersistPolicy(SecurityGroup secGroup, String permission, Date from, Date to, OLATResourceable olatResourceable); - - - /** - * Creates and persist a policy for certain OLAT-resource (instead of OLAT-resourceable) - * - * @param secGroup - * @param permission - * @param olatResource - * @return the newly created policy - */ - public Policy createAndPersistPolicyWithResource(SecurityGroup secGroup, String permission, OLATResource olatResource); - - - public Policy findPolicy(SecurityGroup secGroup, String permission, OLATResource olatResource); - - /** - * Create and persist an invitation with its security group and security token. - * @return - */ - public Invitation createAndPersistInvitation(); - - /** - * Update the invitation - * @param invitation - */ - public void updateInvitation(Invitation invitation); - - /** - * Is the invitation linked to any valid policies - * @param token - * @param atDate - * @return - */ - public boolean hasInvitationPolicies(String token, Date atDate); - - /** - * Find an invitation by its security group - * @param secGroup - * @return The invitation or null if not found - */ - public Invitation findInvitation(SecurityGroup secGroup); - - /** - * Find an invitation by its security token - * @param token - * @return The invitation or null if not found - */ - public Invitation findInvitation(String token); - - /** - * Check if the identity has an invitation, valid or not - * @param identity - * @return - */ - public boolean isIdentityInvited(Identity identity); - - /** - * Delete an invitation - * @param invitation - */ - public void deleteInvitation(Invitation invitation); - - /** - * Clean up old invitation and set to deleted temporary users - */ - public void cleanUpInvitations(); - - /** - * @param secGroup - * @param permission - * @param olatResourceable - */ - public void deletePolicy(SecurityGroup secGroup, String permission, OLATResource olatResourceable); - /** * Delete all policies of a resource */ public void deletePolicies(OLATResource olatResourceable); - - public boolean deletePolicies(Collection<SecurityGroup> secGroups, Collection<OLATResource> resources); // some queries mainly for the group/groupcontext management /** @@ -554,29 +461,15 @@ public interface BaseSecurity { */ public List<Policy> getPoliciesOfSecurityGroup(SecurityGroup secGroup); + /** - * - * @param secGroups + * Return the policies + * @param resource The resource (mandatory) + * @param securityGroup The securityGroup (optional) * @return */ - public List<Policy> getPoliciesOfSecurityGroup(List<SecurityGroup> secGroups, OLATResource... resources); - -/** - * Return the policies - * @param resource The resource (mandatory) - * @param securityGroup The securityGroup (optional) - * @return - */ public List<Policy> getPoliciesOfResource(OLATResource resource, SecurityGroup securityGroup); - /** - * Update the policy valid dates - * @param policy - * @param from - * @param to - */ - public void updatePolicy(Policy policy, Date from, Date to); - /** * for debugging and info by the olat admins: * diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java index 8c9bd474711246f5964d9fdc6cf08116a54cae20..fd8dadc02f788ee33fa1f65f723df61015206b07 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java @@ -26,7 +26,6 @@ package org.olat.basesecurity; import java.util.ArrayList; -import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -34,7 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.UUID; import javax.persistence.EntityNotFoundException; import javax.persistence.LockModeType; @@ -48,12 +46,10 @@ import org.olat.admin.sysinfo.SysinfoController; import org.olat.admin.user.UserAdminController; import org.olat.admin.user.UserChangePasswordController; import org.olat.admin.user.UserCreateController; -import org.olat.admin.user.delete.service.UserDeletionManager; import org.olat.basesecurity.events.NewIdentityCreatedEvent; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.commons.persistence.DBQuery; -import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.ModifiedInfo; @@ -70,8 +66,8 @@ import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.coordinate.SyncerCallback; import org.olat.core.util.resource.OresHelper; import org.olat.login.LoginModule; +import org.olat.portfolio.manager.InvitationDAO; import org.olat.resource.OLATResource; -import org.olat.resource.OLATResourceImpl; import org.olat.resource.OLATResourceManager; import org.olat.user.ChangePasswordController; import org.olat.user.PersonalSettingsController; @@ -89,6 +85,7 @@ import org.olat.user.UserManager; public class BaseSecurityManager extends BasicManager implements BaseSecurity { private DB dbInstance; private OLATResourceManager orm; + private InvitationDAO invitationDao; private String dbVendor = ""; private static BaseSecurityManager INSTANCE; private static String GUEST_USERNAME_PREFIX = "guest_"; @@ -124,6 +121,14 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { public void setDbInstance(DB dbInstance) { this.dbInstance = dbInstance; } + + /** + * [used by Spring] + * @param invitationDao + */ + public void setInvitationDao(InvitationDAO invitationDao) { + this.invitationDao = invitationDao; + } /** * @see org.olat.basesecurity.Manager#init() @@ -290,31 +295,6 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { .getResultList(); return policies; } - - @Override - public List<Policy> getPoliciesOfSecurityGroup(List<SecurityGroup> secGroups, OLATResource... resources) { - if(secGroups == null || secGroups.isEmpty()) return Collections.emptyList(); - - StringBuilder sb = new StringBuilder(); - sb.append("select poi from ").append(PolicyImpl.class.getName()).append(" as poi") - .append(" inner join fetch poi.securityGroup as secGroup") - .append(" inner join fetch poi.olatResource as resource") - .append(" where secGroup.key in (:secGroupKeys)"); - if(resources != null && resources.length > 0) { - sb.append(" and resource.key in (:resourceKeys)"); - } - - List<Long> secGroupKeys = PersistenceHelper.toKeys(secGroups); - TypedQuery<Policy> queryPolicies = DBFactory.getInstance().getCurrentEntityManager() - .createQuery(sb.toString(), Policy.class) - .setParameter("secGroupKeys", secGroupKeys); - if(resources != null && resources.length > 0) { - List<Long> resourceKeys = PersistenceHelper.toKeys(resources); - queryPolicies.setParameter("resourceKeys", resourceKeys); - } - List<Policy> policies = queryPolicies.getResultList(); - return policies; - } /** * @see org.olat.basesecurity.BaseSecurity#getPoliciesOfResource(org.olat.core.id.OLATResourceable) @@ -336,40 +316,6 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { } return query.getResultList(); } - - @Override - public List<Identity> getIdentitiesWithPermissionWithOlatResourceableType( - String permission, String olatResourceableTypeName) { - // if the olatResourceable is not persisted as OLATResource, then the answer - // is false, therefore we can use the query assuming there is an OLATResource - StringBuilder sb = new StringBuilder(); - sb.append("select distinct im from ").append(SecurityGroupMembershipImpl.class.getName()).append(" as sgmsi,") - .append(IdentityImpl.class.getName()).append(" as im,") - .append(PolicyImpl.class.getName()).append(" as poi,") - .append(OLATResourceImpl.class.getName()).append(" as ori ") - .append("where im=sgmsi.identity and sgmsi.securityGroup=poi.securityGroup ") - .append(" and poi.permission=:permission and poi.olatResource=ori and ori.resName=:resName"); - - return dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Identity.class) - .setParameter("permission", permission) - .setParameter("resName", olatResourceableTypeName) - .getResultList(); - } - - @Override - public List<String> getIdentityPermissionOnresourceable(Identity identity, OLATResourceable olatResourceable) { - Long oresid = olatResourceable.getResourceableId(); - if (oresid == null) { - oresid = new Long(0); - } - List<String> permissions = dbInstance.getCurrentEntityManager() - .createNamedQuery("getIdentityPermissionsOnResourceableCheckType", String.class) - .setParameter("identitykey", identity.getKey()) - .setParameter("resid", oresid) - .setParameter("resname", olatResourceable.getResourceableTypeName()) - .getResultList(); - return permissions; - } @Override public boolean isIdentityPermittedOnResourceable(Identity identity, String permission, OLATResourceable olatResourceable) { @@ -426,7 +372,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { boolean poolManager = admin || rolesStr.contains(Constants.GROUP_POOL_MANAGER); if(!rolesStr.contains(Constants.GROUP_OLATUSERS)) { - isInvitee = isIdentityInvited(identity); + isInvitee = invitationDao.isInvitee(identity); isGuestOnly = isIdentityPermittedOnResourceable(identity, Constants.PERMISSION_HASROLE, Constants.ORESOURCE_GUESTONLY); } @@ -529,13 +475,6 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { .setParameter("identityKey", identity.getKey()) .getResultList(); } - - @Override - public void updatePolicy(Policy policy, Date from, Date to) { - ((PolicyImpl)policy).setFrom(from); - ((PolicyImpl)policy).setTo(to); - DBFactory.getInstance().updateObject(policy); - } /** * @see org.olat.basesecurity.Manager#isIdentityInSecurityGroup(org.olat.core.id.Identity, org.olat.basesecurity.SecurityGroup) @@ -665,23 +604,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { */ @Override public Policy createAndPersistPolicy(SecurityGroup secGroup, String permission, OLATResourceable olatResourceable) { - return createAndPersistPolicy(secGroup, permission, null, null, olatResourceable); - } - - /** - * @see org.olat.basesecurity.BaseSecurity#createAndPersistPolicy(org.olat.basesecurity.SecurityGroup, java.lang.String, java.util.Date, java.util.Date, org.olat.core.id.OLATResourceable) - */ - @Override - public Policy createAndPersistPolicy(SecurityGroup secGroup, String permission, Date from, Date to, OLATResourceable olatResourceable) { OLATResource olatResource = orm.findOrPersistResourceable(olatResourceable); - return createAndPersistPolicyWithResource(secGroup, permission, from, to, olatResource); - } - - /** - * @see org.olat.basesecurity.BaseSecurity#createAndPersistPolicyWithResource(org.olat.basesecurity.SecurityGroup, java.lang.String, org.olat.resource.OLATResource) - */ - @Override - public Policy createAndPersistPolicyWithResource(SecurityGroup secGroup, String permission, OLATResource olatResource) { return createAndPersistPolicyWithResource(secGroup, permission, null, null, olatResource); } @@ -733,41 +656,6 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { return null; } return policies.get(0); - } - - private void deletePolicy(Policy policy) { - DBFactory.getInstance().deleteObject(policy); - } - - @Override - public boolean deletePolicies(Collection<SecurityGroup> secGroups, Collection<OLATResource> resources) { - if(secGroups == null || secGroups.isEmpty() || resources == null || resources.isEmpty()) return false; - - StringBuilder sb = new StringBuilder(); - sb.append("delete from ").append(PolicyImpl.class.getName()).append(" as poi ") - .append(" where poi.olatResource.key in (:resourceKey) and poi.securityGroup.key in (:secGroupKeys)"); - - List<Long> secGroupKeys = PersistenceHelper.toKeys(secGroups); - List<Long> resourceKeys = PersistenceHelper.toKeys(resources); - int rows = DBFactory.getInstance().getCurrentEntityManager() - .createQuery(sb.toString()) - .setParameter("resourceKey", resourceKeys) - .setParameter("secGroupKeys", secGroupKeys) - .executeUpdate(); - return rows > 0; - } - - /** - * @see org.olat.basesecurity.Manager#deletePolicy(org.olat.basesecurity.SecurityGroup, java.lang.String, org.olat.core.id.OLATResourceable - */ - @Override - public void deletePolicy(SecurityGroup secGroup, String permission, OLATResource resource) { - if (resource == null) throw new AssertException("cannot delete policy of a null olatresourceable!"); - Policy p = findPolicy(secGroup, permission, resource); - // fj: introduced strict testing here on purpose - if (p != null) { - deletePolicy(p); - } } @Override @@ -785,169 +673,6 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { } } - /** - * - * @see org.olat.basesecurity.BaseSecurity#createAndPersistInvitation() - */ - @Override - public Invitation createAndPersistInvitation() { - SecurityGroup secGroup = new SecurityGroupImpl(); - DBFactory.getInstance().saveObject(secGroup); - - InvitationImpl invitation = new InvitationImpl(); - invitation.setToken(UUID.randomUUID().toString()); - invitation.setSecurityGroup(secGroup); - DBFactory.getInstance().saveObject(invitation); - return invitation; - } - - /** - * @see org.olat.basesecurity.BaseSecurity#updateInvitation(org.olat.basesecurity.Invitation) - */ - @Override - public void updateInvitation(Invitation invitation) { - DBFactory.getInstance().updateObject(invitation); - } - - /** - * @see org.olat.basesecurity.BaseSecurity#hasInvitationPolicies(java.lang.String, java.util.Date) - */ - @Override - public boolean hasInvitationPolicies(String token, Date atDate) { - StringBuilder sb = new StringBuilder(); - sb.append("select count(policy) from ").append(PolicyImpl.class.getName()).append(" as policy, ") - .append(InvitationImpl.class.getName()).append(" as invitation ") - .append(" inner join policy.securityGroup secGroup ") - .append(" where invitation.securityGroup=secGroup ") - .append(" and invitation.token=:token"); - if(atDate != null) { - sb.append(" and (policy.from is null or policy.from<=:date)") - .append(" and (policy.to is null or policy.to>=:date)"); - } - - DBQuery query = DBFactory.getInstance().createQuery(sb.toString()); - query.setString("token", token); - if(atDate != null) { - query.setDate("date", atDate); - } - - Number counter = (Number)query.uniqueResult(); - return counter.intValue() > 0; - } - - /** - * @see org.olat.basesecurity.BaseSecurity#findInvitation(org.olat.basesecurity.SecurityGroup) - */ - @Override - public Invitation findInvitation(SecurityGroup secGroup) { - StringBuilder sb = new StringBuilder(); - sb.append("select invitation from ").append(InvitationImpl.class.getName()).append(" as invitation ") - .append(" where invitation.securityGroup=:secGroup "); - - List<Invitation> invitations = dbInstance.getCurrentEntityManager() - .createQuery(sb.toString(), Invitation.class) - .setParameter("secGroup", secGroup) - .getResultList(); - if(invitations.isEmpty()) return null; - return invitations.get(0); - } - - /** - * @see org.olat.basesecurity.BaseSecurity#findInvitation(java.lang.String) - */ - @Override - public Invitation findInvitation(String token) { - StringBuilder sb = new StringBuilder(); - sb.append("select invitation from ").append(InvitationImpl.class.getName()).append(" as invitation ") - .append(" where invitation.token=:token"); - - DBQuery query = DBFactory.getInstance().createQuery(sb.toString()); - query.setString("token", token); - - List<Invitation> invitations = query.list(); - if(invitations.isEmpty()) return null; - return invitations.get(0); - } - - /** - * @see org.olat.basesecurity.BaseSecurity#isIdentityInvited(org.olat.core.id.Identity) - */ - @Override - public boolean isIdentityInvited(Identity identity) { - StringBuilder sb = new StringBuilder(); - sb.append("select count(invitation) from ").append(InvitationImpl.class.getName()).append(" as invitation ") - .append("inner join invitation.securityGroup secGroup ") - .append("where secGroup in (") - .append(" select membership.securityGroup from ").append(SecurityGroupMembershipImpl.class.getName()).append(" as membership") - .append(" where membership.identity=:identity") - .append(")"); - - DBQuery query = DBFactory.getInstance().createQuery(sb.toString()); - query.setEntity("identity", identity); - - Number invitations = (Number)query.uniqueResult(); - return invitations.intValue() > 0; - } - - /** - * @see org.olat.basesecurity.BaseSecurity#deleteInvitation(org.olat.basesecurity.Invitation) - */ - @Override - public void deleteInvitation(Invitation invitation) { - //fxdiff: FXOLAT-251: nothing persisted, nothing to delete - if(invitation == null || invitation.getKey() == null) return; - DBFactory.getInstance().deleteObject(invitation); - } - - /** - * @see org.olat.basesecurity.BaseSecurity#cleanUpInvitations() - */ - @Override - public void cleanUpInvitations() { - Calendar cal = Calendar.getInstance(); - cal.setTime(new Date()); - Date currentTime = cal.getTime(); - cal.add(Calendar.HOUR, -6); - Date dateLimit = cal.getTime(); - - StringBuilder sb = new StringBuilder(); - sb.append("select invitation from ").append(InvitationImpl.class.getName()).append(" as invitation ") - .append(" inner join invitation.securityGroup secGroup ") - .append(" where invitation.creationDate<:dateLimit")//someone can create an invitation but not add it to a policy within millisecond - .append(" and secGroup not in (") - //select all valid policies from this security group - .append(" select policy.securityGroup from ").append(PolicyImpl.class.getName()).append(" as policy ") - .append(" where (policy.from is null or policy.from<=:currentDate)") - .append(" and (policy.to is null or policy.to>=:currentDate)") - .append(" )"); - - DBQuery query = DBFactory.getInstance().createQuery(sb.toString()); - query.setDate("currentDate", currentTime); - query.setDate("dateLimit", dateLimit); - List<Invitation> oldInvitations = query.list(); - if(oldInvitations.isEmpty()) { - return; - } - - SecurityGroup olatUserSecGroup = findSecurityGroupByName(Constants.GROUP_OLATUSERS); - for(Invitation invitation:oldInvitations) { - List<Identity> identities = getIdentitiesOfSecurityGroup(invitation.getSecurityGroup()); - //normally only one identity - for(Identity identity:identities) { - if(identity.getStatus().compareTo(Identity.STATUS_VISIBLE_LIMIT) >= 0) { - //already deleted - } else if(isIdentityInSecurityGroup(identity, olatUserSecGroup)) { - //out of scope - } else { - //delete user - UserDeletionManager.getInstance().deleteIdentity(identity); - } - } - DBFactory.getInstance().deleteObject(invitation); - DBFactory.getInstance().intermediateCommit(); - } - } - /** * @param username the username * @param user the presisted User diff --git a/src/main/java/org/olat/basesecurity/GroupRoles.java b/src/main/java/org/olat/basesecurity/GroupRoles.java index 4c5f291a87244268208cd634d52be09843f76c27..0ad5ce8836b4d9e6be7f395cccfeec28c2e2c297 100644 --- a/src/main/java/org/olat/basesecurity/GroupRoles.java +++ b/src/main/java/org/olat/basesecurity/GroupRoles.java @@ -34,6 +34,7 @@ public enum GroupRoles { owner, coach, participant, + invitee, waiting; diff --git a/src/main/java/org/olat/basesecurity/IdentityNames.java b/src/main/java/org/olat/basesecurity/IdentityNames.java index 86d22f62a848628aff01104e6e4e0efeaf988ccc..97bdbbe6b921cb4503a2a98c20ed62e468ec682f 100644 --- a/src/main/java/org/olat/basesecurity/IdentityNames.java +++ b/src/main/java/org/olat/basesecurity/IdentityNames.java @@ -27,8 +27,6 @@ package org.olat.basesecurity; */ public interface IdentityNames extends IdentityRef { - public Long getKey(); - public String getName(); public String getFirstName(); diff --git a/src/main/java/org/olat/basesecurity/Invitation.java b/src/main/java/org/olat/basesecurity/Invitation.java index 3235aba94e29b9a353180f3b8649f92a7590bf1e..84069f8307e4df18d792d1acd1dd29ba54154a3f 100644 --- a/src/main/java/org/olat/basesecurity/Invitation.java +++ b/src/main/java/org/olat/basesecurity/Invitation.java @@ -46,5 +46,5 @@ public interface Invitation { public void setMail(String mail); - public SecurityGroup getSecurityGroup(); + public Group getBaseGroup(); } diff --git a/src/main/java/org/olat/basesecurity/InvitationImpl.hbm.xml b/src/main/java/org/olat/basesecurity/InvitationImpl.hbm.xml deleted file mode 100644 index 90aa24dfcc49963536be3335b177dec7fb0ec4f7..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/basesecurity/InvitationImpl.hbm.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - -<hibernate-mapping default-lazy="false"> - - <class name="org.olat.basesecurity.InvitationImpl" table="o_bs_invitation"> - <!-- the default columns --> - <id name="key" column="id" type="long" unsaved-value="null"> - <generator class="hilo"/> - </id> - <version name="version" access="field" column="version" type="int"/> - <property name="creationDate" column="creationdate" type="timestamp" /> - - <property name="token" column="token" type="string" length="64"/> - <property name="firstName" column="first_name" type="string" length="64"/> - <property name="lastName" column="last_name" type="string" length="64"/> - <property name="mail" column="mail" type="string" length="128"/> - - <many-to-one name="securityGroup" class="org.olat.basesecurity.SecurityGroupImpl" fetch="join" cascade="none" - column="fk_secgroup" not-null="true" unique-key="policy_unique"/> - </class> -</hibernate-mapping> - diff --git a/src/main/java/org/olat/basesecurity/InvitationImpl.java b/src/main/java/org/olat/basesecurity/InvitationImpl.java deleted file mode 100644 index 250b0996dd3834abcaa5321b7ad5b4e9dc30c7f6..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/basesecurity/InvitationImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ - -package org.olat.basesecurity; - -import org.olat.core.commons.persistence.PersistentObject; - -/** - * - * Description:<br> - * Implementation of Invitation - * - * <P> - * Initial Date: 10 nov. 2010 <br> - * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com - */ -public class InvitationImpl extends PersistentObject implements Invitation { - - private String token; - private String firstName; - private String lastName; - private String mail; - private SecurityGroup securityGroup; - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getMail() { - return mail; - } - - public void setMail(String mail) { - this.mail = mail; - } - - public SecurityGroup getSecurityGroup() { - return securityGroup; - } - - public void setSecurityGroup(SecurityGroup securityGroup) { - this.securityGroup = securityGroup; - } - - @Override - public boolean equals(Object obj) { - if(this == obj) { - return true; - } else if (obj instanceof InvitationImpl) { - InvitationImpl invitation = (InvitationImpl)obj; - return getKey() != null && getKey().equals(invitation.getKey()); - } - return false; - } -} diff --git a/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml b/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml index 0cc171d1c18ab6c76dadb9d211d1c32452958c3e..0a43cb6cd73176ca9f9eebf46e145804cb11a1df 100644 --- a/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml +++ b/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml @@ -15,6 +15,7 @@ depends-on="database, i18nModule, triggerI18nModuleInit"> <property name="resourceManager" ref="resourceManager"/> <property name="dbInstance" ref="database"/> + <property name="invitationDao" ref="invitationDao" /> <property name="dbVendor" value="${db.vendor}" /> </bean> @@ -130,35 +131,4 @@ </property> </bean> -<bean id="invitationCleanupTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> - <property name="jobDetail" ref="invitationCleanupJob.${cluster.singleton.services}" /> - <!-- adjust cron style syntax for your notification needs - "0 10 0 * *" e.g. 10 minutes after midnight - - A "Cron-Expression" is a string comprised of 6 or 7 fields separated by white space. The 6 mandatory and 1 optional fields are as follows: - Field Name Allowed Values Allowed Special Characters - Seconds 0-59 , - * / - Minutes 0-59 , - * / - Hours 0-23 , - * / - Day-of-month 1-31 , - * ? / L W C - Month 1-12 or JAN-DEC , - * / - Day-of-Week 1-7 or SUN-SAT , - * ? / L C # - Year (Optional) empty, 1970-2099 , - * / - - As of OLAT 6.3 it's best to let the cronjob run every two hours since users can now choose how often - they will get notified. The shortest interval is set to two hours. - --> - <property name="cronExpression" value="0 2 */12 * * ?" /> - <property name="startDelay" value="150000" /> -</bean> - -<bean id="invitationCleanupJob.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> - <property name="jobClass" value="org.olat.basesecurity.InvitationCleanupJob" /> -</bean> - -<!-- dummy bean --> -<bean id="invitationCleanupJob.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> - <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> -</bean> - </beans> \ No newline at end of file diff --git a/src/main/java/org/olat/basesecurity/manager/GroupDAO.java b/src/main/java/org/olat/basesecurity/manager/GroupDAO.java index dbc26a096492201eab9015041d8cba5aa31b99f4..c624071c0c66e4f5fc447b6d51699d47b96416b5 100644 --- a/src/main/java/org/olat/basesecurity/manager/GroupDAO.java +++ b/src/main/java/org/olat/basesecurity/manager/GroupDAO.java @@ -59,6 +59,15 @@ public class GroupDAO { return group; } + public Group createGroup(String name) { + GroupImpl group = new GroupImpl(); + group.setCreationDate(new Date()); + group.setName(name); + dbInstance.getCurrentEntityManager().persist(group); + return group; + } + + public Group removeGroup(Group group) { EntityManager em = dbInstance.getCurrentEntityManager(); GroupImpl reloadedGroup = em.getReference(GroupImpl.class, group.getKey()); diff --git a/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml b/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml index 359476e50c242c3ae23779ae7b9c5ff6be5e66e2..38f4953bc1061ab3da22aea1fc7da298124bdccc 100644 --- a/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml +++ b/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml @@ -34,7 +34,6 @@ <mapping-file>org/olat/resource/accesscontrol/provider/paypal/model/PaypalTransaction.hbm.xml</mapping-file> <mapping-file>org/olat/basesecurity/AuthenticationImpl.hbm.xml</mapping-file> <mapping-file>org/olat/basesecurity/PolicyImpl.hbm.xml</mapping-file> - <mapping-file>org/olat/basesecurity/InvitationImpl.hbm.xml</mapping-file> <mapping-file>org/olat/basesecurity/IdentityImpl.hbm.xml</mapping-file> <mapping-file>org/olat/basesecurity/NamedGroupImpl.hbm.xml</mapping-file> <mapping-file>org/olat/basesecurity/SecurityGroupImpl.hbm.xml</mapping-file> @@ -86,6 +85,8 @@ <mapping-file>org/olat/upgrade/model/RepositoryEntryUpgrade.hbm.xml</mapping-file> <mapping-file>org/olat/upgrade/model/EPMapUpgrade.hbm.xml</mapping-file> <class>org.olat.upgrade.model.RepositoryEntryUpgradeToGroupRelation</class> + <class>org.olat.upgrade.model.EPMapUpgradeToGroupRelation</class> + <class>org.olat.upgrade.model.InvitationUpgrade</class> <!-- End upgraders mapping --> <class>org.olat.basesecurity.model.GroupImpl</class> @@ -140,6 +141,8 @@ <class>org.olat.modules.qpool.model.QItemType</class> <class>org.olat.modules.qpool.model.QLicense</class> <class>org.olat.ims.lti.model.LTIOutcomeImpl</class> + <class>org.olat.portfolio.model.InvitationImpl</class> + <class>org.olat.portfolio.model.structel.EPStructureElementToGroupRelation</class> <properties> <property name="hibernate.generate_statistics" value="true"/> <property name="hibernate.archive.autodetection" value=""/> diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java index d1024f2742882211c3a5e4e8287d253f67ba4a62..d442d120a8eac135582f43799657167d324a4610 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java @@ -399,6 +399,20 @@ public class BusinessGroupDAO { return query.getResultList(); } + public BusinessGroup findBusinessGroup(Group baseGroup) { + StringBuilder sb = new StringBuilder(); + sb.append("select bgs from ").append(BusinessGroupImpl.class.getName()).append(" as bgs ") + .append(" inner join fetch bgs.resource as bgResource") + .append(" inner join fetch bgs.baseGroup as baseGroup") + .append(" where baseGroup=:group"); + + List<BusinessGroup> groups = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), BusinessGroup.class) + .setParameter("group", baseGroup) + .getResultList(); + return groups.isEmpty() ? null : groups.get(0); + } + public List<BusinessGroup> findBusinessGroupsWithWaitingListAttendedBy(Identity identity, RepositoryEntryRef repoEntry) { StringBuilder sb = new StringBuilder(); sb.append("select bgs from ").append(BusinessGroupImpl.class.getName()).append(" as bgs ") diff --git a/src/main/java/org/olat/gui/control/OlatFooterController.java b/src/main/java/org/olat/gui/control/OlatFooterController.java index 40766d2ff6bdf9ebb80016511e7c164a4882258e..852643390892033bb382da7eba3fd4e64389e4cd 100644 --- a/src/main/java/org/olat/gui/control/OlatFooterController.java +++ b/src/main/java/org/olat/gui/control/OlatFooterController.java @@ -89,7 +89,7 @@ public class OlatFooterController extends BasicController { if (!isGuest && ureq.getUserSession().isAuthenticated()) { olatFootervc.contextPut("loggedIn", Boolean.TRUE); if(isInvitee) { - olatFootervc.contextPut("username", translate("invitee")); + olatFootervc.contextPut("username", translate("logged.in.invitee")); } else { String fullName = CoreSpringFactory.getImpl(UserManager.class).getUserDisplayName(ureq.getIdentity()); olatFootervc.contextPut("username", StringHelper.escapeHtml(fullName)); diff --git a/src/main/java/org/olat/gui/control/OlatTopNavController.java b/src/main/java/org/olat/gui/control/OlatTopNavController.java index 6208c97dee62cbefaf51fe5deb4dc0bb6e9fc926..b1e5c9c2c4bbf8a60773931cf308e2a9a2ce6649 100644 --- a/src/main/java/org/olat/gui/control/OlatTopNavController.java +++ b/src/main/java/org/olat/gui/control/OlatTopNavController.java @@ -111,6 +111,8 @@ public class OlatTopNavController extends BasicController implements GenericEven boolean isGuest = ureq.getUserSession().getRoles().isGuestOnly(); boolean isInvitee = ureq.getUserSession().getRoles().isInvitee(); + topNavVC.contextPut("isGuest", new Boolean(isGuest)); + topNavVC.contextPut("isInvitee", new Boolean(isInvitee)); // instant messaging area, only when enabled and user is not a guest user if (CoreSpringFactory.getImpl(InstantMessagingModule.class).isEnabled() && !isGuest && !isInvitee) { @@ -129,7 +131,6 @@ public class OlatTopNavController extends BasicController implements GenericEven // login link if (ureq.getIdentity() == null) { - topNavVC.contextPut("isGuest", Boolean.TRUE); loginLink = LinkFactory.createLink("topnav.login", topNavVC, this); loginLink.setIconLeftCSS("o_icon o_icon_login o_icon-lg"); loginLink.setTooltip("topnav.login.alt"); diff --git a/src/main/java/org/olat/gui/control/_content/topnav.html b/src/main/java/org/olat/gui/control/_content/topnav.html index f3df184bcc52d5a93719863fc91e1cc79d81f6f3..7ba647f149cfbc7c128b2584042d58be4f8a7056 100644 --- a/src/main/java/org/olat/gui/control/_content/topnav.html +++ b/src/main/java/org/olat/gui/control/_content/topnav.html @@ -3,7 +3,7 @@ #foreach($personalTool in $toolSet) <li class="o_navbar_tool">$r.render($personalTool)</li> #end - #if (!$isGuest) + #if (!$isGuest && !$isInvitee) <li id="o_navbar_my_menu" class="dropdown o_portrait"> <a id="o_sel_navbar_my_menu_caret" href="#" class="dropdown-toggle" data-toggle="dropdown"> $r.render("portrait") @@ -12,7 +12,7 @@ </a> $r.render("myMenu") </li> - #else + #elseif(!$isInvitee) <li id="o_navbar_login"> $r.render("topnav.login") </li> diff --git a/src/main/java/org/olat/portfolio/EPMapOnInvitationExtension.java b/src/main/java/org/olat/portfolio/EPMapOnInvitationExtension.java index 75c921bb70ad09a16af63f7db167aab1e727985a..ba697361c5cc1b32e5540f8c4484e363d68813b2 100644 --- a/src/main/java/org/olat/portfolio/EPMapOnInvitationExtension.java +++ b/src/main/java/org/olat/portfolio/EPMapOnInvitationExtension.java @@ -51,9 +51,11 @@ public class EPMapOnInvitationExtension { private static class MapOnInvitationContextEntryControllerCreator extends DefaultContextEntryControllerCreator { + private PortfolioStructureMap map; + @Override public ContextEntryControllerCreator clone() { - return this; + return new MapOnInvitationContextEntryControllerCreator(); } @Override @@ -74,7 +76,10 @@ public class EPMapOnInvitationExtension { @Override public String getTabName(ContextEntry ce, UserRequest ureq) { PortfolioStructureMap map = getMapFromContext(ce); - return map.getTitle(); + if(map != null) { + return map.getTitle(); + } + return null; } @Override @@ -83,9 +88,11 @@ public class EPMapOnInvitationExtension { return false; } - final EPFrontendManager ePFMgr = (EPFrontendManager) CoreSpringFactory.getBean("epFrontendManager"); + final EPFrontendManager ePFMgr = CoreSpringFactory.getImpl(EPFrontendManager.class); PortfolioStructureMap map = getMapFromContext(ce); - if (map == null) return false; + if (map == null) { + return false; + } boolean visible = ePFMgr.isMapVisible(ureq.getIdentity(), map.getOlatResource()); return visible; } @@ -95,11 +102,12 @@ public class EPMapOnInvitationExtension { * @return the loaded map or null if not found */ private PortfolioStructureMap getMapFromContext(final ContextEntry ce) { - final Long mapKey = ce.getOLATResourceable().getResourceableId(); - final EPFrontendManager ePFMgr = (EPFrontendManager) CoreSpringFactory.getBean("epFrontendManager"); - final PortfolioStructureMap map = (PortfolioStructureMap) ePFMgr.loadPortfolioStructureByKey(mapKey); + if(map == null) { + Long mapKey = ce.getOLATResourceable().getResourceableId(); + EPFrontendManager ePFMgr = CoreSpringFactory.getImpl(EPFrontendManager.class); + map = (PortfolioStructureMap)ePFMgr.loadPortfolioStructureByKey(mapKey); + } return map; } - } -} +} \ No newline at end of file diff --git a/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml b/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml index 344bcacab37c220ea4f1fc752ade20fa56553669..458ef955a35e7dc93edbb70c4d1dd2dfc71926fc 100644 --- a/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml +++ b/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml @@ -144,6 +144,36 @@ <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> + <bean id="invitationCleanupTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <property name="jobDetail" ref="invitationCleanupJob.${cluster.singleton.services}" /> + <!-- adjust cron style syntax for your notification needs + "0 10 0 * *" e.g. 10 minutes after midnight + + A "Cron-Expression" is a string comprised of 6 or 7 fields separated by white space. The 6 mandatory and 1 optional fields are as follows: + Field Name Allowed Values Allowed Special Characters + Seconds 0-59 , - * / + Minutes 0-59 , - * / + Hours 0-23 , - * / + Day-of-month 1-31 , - * ? / L W C + Month 1-12 or JAN-DEC , - * / + Day-of-Week 1-7 or SUN-SAT , - * ? / L C # + Year (Optional) empty, 1970-2099 , - * / + + As of OLAT 6.3 it's best to let the cronjob run every two hours since users can now choose how often + they will get notified. The shortest interval is set to two hours. + --> + <property name="cronExpression" value="0 2 */12 * * ?" /> + <property name="startDelay" value="150000" /> + </bean> + + <bean id="invitationCleanupJob.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <property name="jobClass" value="org.olat.portfolio.manager.InvitationCleanupJob" /> + </bean> + <!-- dummy bean --> + <bean id="invitationCleanupJob.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> + </bean> + <!-- hook to the personal menu --> <bean class="org.olat.core.extensions.action.GenericActionExtension" name="personal.tool.ep" init-method="initExtensionPoints" > <property name="order" value="301" /> diff --git a/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java b/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java index 8c28a576e9b722e2e23409ea3c565a63218952f7..1b409e973c0b64f18954554993efe87fe4d0eedb 100755 --- a/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java +++ b/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java @@ -28,9 +28,7 @@ import java.util.Map; import java.util.Set; import org.olat.basesecurity.BaseSecurity; -import org.olat.basesecurity.Constants; -import org.olat.basesecurity.GroupRoles; -import org.olat.basesecurity.Policy; +import org.olat.basesecurity.IdentityRef; import org.olat.basesecurity.manager.GroupDAO; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.tagging.manager.TaggingManager; @@ -713,7 +711,8 @@ public class EPFrontendManager extends BasicManager { * @param type Limit maps to this or these types * @return */ - public List<PortfolioStructure> getStructureElementsFromOthersWithoutPublic(Identity ident, Identity choosenOwner, ElementType... types){ + public List<PortfolioStructure> getStructureElementsFromOthersWithoutPublic(IdentityRef ident, IdentityRef choosenOwner, + ElementType... types){ return structureManager.getStructureElementsFromOthersWithoutPublic(ident, choosenOwner, types); } @@ -1054,23 +1053,16 @@ public class EPFrontendManager extends BasicManager { * @param ores * @return */ - public boolean isMapVisible(Identity identity, OLATResourceable ores) { + public boolean isMapVisible(IdentityRef identity, OLATResourceable ores) { return structureManager.isMapVisible(identity, ores); } public boolean isMapShared(PortfolioStructureMap map) { - OLATResource resource = map.getOlatResource(); - return isMapShared(resource); + return isMapShared(map.getOlatResource()); } public boolean isMapShared(OLATResource resource) { - List<Policy> policies = securityManager.getPoliciesOfResource(resource, null); - for(Policy policy:policies) { - if(policy.getPermission().contains(Constants.PERMISSION_READ)) { - return true; - } - } - return false; + return policyManager.isMapShared(resource); } /** @@ -1086,8 +1078,8 @@ public class EPFrontendManager extends BasicManager { * @param map * @param policyWrappers */ - public void updateMapPolicies(PortfolioStructureMap map, List<EPMapPolicy> policyWrappers) { - policyManager.updateMapPolicies(map, policyWrappers); + public PortfolioStructureMap updateMapPolicies(PortfolioStructureMap map, List<EPMapPolicy> policyWrappers) { + return policyManager.updateMapPolicies(map, policyWrappers); } /** @@ -1110,7 +1102,7 @@ public class EPFrontendManager extends BasicManager { AssessmentManager am = course.getCourseEnvironment().getAssessmentManager(); CourseNode courseNode = course.getRunStructure().getNode(resource.getSubPath()); - List<Identity> owners = groupDao.getMembers(submittedMap.getGroup(), GroupRoles.coach.name()); + List<Identity> owners = policyManager.getOwners(submittedMap); for(Identity owner:owners) { if (courseNode != null) { // courseNode might have been deleted meanwhile IdentityEnvironment ienv = new IdentityEnvironment(); @@ -1204,10 +1196,10 @@ public class EPFrontendManager extends BasicManager { * @return */ public String getAllOwnersAsString(PortfolioStructureMap map){ - if(map.getGroup() == null) { + if(map.getGroups() == null) { return null; } - List<Identity> ownerIdents = groupDao.getMembers(map.getGroup(), GroupRoles.coach.name()); + List<Identity> ownerIdents = policyManager.getOwners(map); List<String> identNames = new ArrayList<String>(); for (Identity identity : ownerIdents) { String fullName = userManager.getUserDisplayName(identity); @@ -1225,10 +1217,10 @@ public class EPFrontendManager extends BasicManager { * @return */ public String getFirstOwnerAsString(PortfolioStructureMap map){ - if(map.getGroup() == null) { + if(map.getGroups() == null) { return "n/a"; } - List<Identity> ownerIdents = groupDao.getMembers(map.getGroup(), GroupRoles.coach.name()); + List<Identity> ownerIdents = policyManager.getOwners(map); if(ownerIdents.size() > 0){ Identity id = ownerIdents.get(0); return userManager.getUserDisplayName(id); @@ -1237,10 +1229,10 @@ public class EPFrontendManager extends BasicManager { } public String getFirstOwnerAsString(EPMapShort map){ - if(map.getGroup() == null) { + if(map.getGroups() == null) { return "n/a"; } - List<Identity> ownerIdents = groupDao.getMembers(map.getGroup(), GroupRoles.coach.name()); + List<Identity> ownerIdents = policyManager.getOwners(map); if(ownerIdents.size() > 0){ Identity id = ownerIdents.get(0); return userManager.getUserDisplayName(id); @@ -1255,10 +1247,10 @@ public class EPFrontendManager extends BasicManager { * @return */ public Identity getFirstOwnerIdentity(PortfolioStructureMap map){ - if(map.getGroup() == null) { + if(map.getGroups() == null) { return null; } - List<Identity> ownerIdents = groupDao.getMembers(map.getGroup(), GroupRoles.coach.name()); + List<Identity> ownerIdents = policyManager.getOwners(map); if (ownerIdents.size() > 0) { Identity id = ownerIdents.get(0); return id; diff --git a/src/main/java/org/olat/portfolio/manager/EPMapPolicy.java b/src/main/java/org/olat/portfolio/manager/EPMapPolicy.java index f3765e5bc7d998bb46cd3681e41a763174f5309b..0ea90843f3b757303280a06e36c06f6b80534b97 100644 --- a/src/main/java/org/olat/portfolio/manager/EPMapPolicy.java +++ b/src/main/java/org/olat/portfolio/manager/EPMapPolicy.java @@ -27,10 +27,10 @@ import java.util.List; import java.util.Map; import org.olat.basesecurity.Invitation; -import org.olat.basesecurity.Policy; import org.olat.core.id.Identity; import org.olat.core.id.UserConstants; import org.olat.group.BusinessGroup; +import org.olat.portfolio.model.structel.EPStructureElementToGroupRelation; /** * @@ -49,9 +49,9 @@ public class EPMapPolicy { private Type type = Type.user; private Invitation invitation; - private List<Policy> policies; - private List<Identity> identities = new ArrayList<Identity>(); - private List<BusinessGroup> groups = new ArrayList<BusinessGroup>(); + private List<Identity> identities = new ArrayList<>(); + private List<BusinessGroup> groups = new ArrayList<>(); + private final List<EPStructureElementToGroupRelation> relations = new ArrayList<>(); public Invitation getInvitation() { return invitation; @@ -61,22 +61,12 @@ public class EPMapPolicy { this.invitation = invitation; } - public List<Policy> getPolicies() { - if(policies == null) { - policies = new ArrayList<Policy>(); - } - return policies; + public List<EPStructureElementToGroupRelation> getRelations() { + return relations; } - public void setPolicies(List<Policy> policies) { - this.policies = policies; - } - - public void addPolicy(Policy policy) { - if(policies == null) { - policies = new ArrayList<Policy>(); - } - policies.add(policy); + public void addRelation(EPStructureElementToGroupRelation relation) { + relations.add(relation); } public Date getTo() { @@ -150,11 +140,8 @@ public class EPMapPolicy { } public void addGroup(BusinessGroup group) { - if(groups == null) { - groups = new ArrayList<BusinessGroup>(); - } for(BusinessGroup g:groups) { - if(g.equalsByPersistableKey(group)) { + if(g.equals(group)) { return; } } diff --git a/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java b/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java index b5bfe3ec304c8592e0bf055767a3f1d9224c6b7f..0f323bc75f6d6b998ed344b450ba84e99bc37d70 100644 --- a/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java +++ b/src/main/java/org/olat/portfolio/manager/EPPolicyManager.java @@ -20,19 +20,26 @@ package org.olat.portfolio.manager; import java.util.ArrayList; +import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.Set; import org.olat.basesecurity.BaseSecurity; -import org.olat.basesecurity.Constants; +import org.olat.basesecurity.Group; +import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.Invitation; -import org.olat.basesecurity.Policy; -import org.olat.basesecurity.SecurityGroup; +import org.olat.basesecurity.manager.GroupDAO; +import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; import org.olat.core.manager.BasicManager; import org.olat.group.BusinessGroup; -import org.olat.group.BusinessGroupService; +import org.olat.group.manager.BusinessGroupDAO; +import org.olat.portfolio.model.structel.EPMapShort; +import org.olat.portfolio.model.structel.EPStructureElement; +import org.olat.portfolio.model.structel.EPStructureElementToGroupRelation; import org.olat.portfolio.model.structel.PortfolioStructureMap; +import org.olat.portfolio.model.structel.PortfolioStructureMapRef; import org.olat.resource.OLATResource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -48,72 +55,105 @@ import org.springframework.stereotype.Service; @Service("epPolicyManager") public class EPPolicyManager extends BasicManager { + @Autowired + private DB dbInstance; + @Autowired + private GroupDAO groupDao; + @Autowired + private InvitationDAO invitationDao; @Autowired private BaseSecurity securityManager; @Autowired - private BusinessGroupService businessGroupService; + private BusinessGroupDAO businessGroupDao; + + public List<Identity> getOwners(PortfolioStructureMapRef map) { + StringBuilder sb = new StringBuilder(); + sb.append("select ident from ").append(EPMapShort.class.getName()).append(" as map") + .append(" inner join map.groups as relGroup on relGroup.defaultGroup=true") + .append(" inner join relGroup.group as baseGroup ") + .append(" inner join baseGroup.members as members on members.role='").append(GroupRoles.owner.name()).append("'") + .append(" inner join members.identity as ident") + .append(" where map.key=:mapKey"); + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Identity.class) + .setParameter("mapKey", map.getKey()).getResultList(); + } + + public boolean isMapShared(OLATResource resource) { + StringBuilder sb = new StringBuilder(); + sb.append("select count(relGroup) from ").append(EPMapShort.class.getName()).append(" as map") + .append(" inner join map.groups as relGroup on relGroup.defaultGroup=false") + .append(" where map.olatResource=:resource"); + + Number count = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Number.class) + .setParameter("resource", resource) + .getSingleResult(); + return count == null ? false : count.intValue() > 0; + } /** * Return a list of wrapper containing the read policies of the map * @param map */ - public List<EPMapPolicy> getMapPolicies(PortfolioStructureMap map) { - OLATResource resource = map.getOlatResource(); - List<EPMapPolicy> policyWrappers = new ArrayList<EPMapPolicy>(); - List<Policy> policies = securityManager.getPoliciesOfResource(resource, null); - for(Policy policy:policies) { - if(!policy.getPermission().contains(Constants.PERMISSION_READ)) { + public List<EPMapPolicy> getMapPolicies(PortfolioStructureMapRef mapRef) { + EPMapShort map = dbInstance.getCurrentEntityManager().find(EPMapShort.class, mapRef.getKey()); + + List<EPMapPolicy> policies = new ArrayList<EPMapPolicy>(); + Set<EPStructureElementToGroupRelation> relations = map.getGroups(); + for(EPStructureElementToGroupRelation relation:relations) { + if(relation.isDefaultGroup()) { continue; } - EPMapPolicy wrapper = getWrapperWithSamePolicy(policy, policyWrappers); - if(wrapper == null) { - wrapper = new EPMapPolicy(); - wrapper.setTo(policy.getTo()); - wrapper.setFrom(policy.getFrom()); - policyWrappers.add(wrapper); + EPMapPolicy policy = getEquivalentWrapper(relation, policies); + if(policy == null) { + policy = new EPMapPolicy(); + policy.setTo(relation.getValidTo()); + policy.setFrom(relation.getValidFrom()); + policies.add(policy); } - String permission = policy.getPermission(); - SecurityGroup secGroup = policy.getSecurityGroup(); - if(permission.startsWith(EPMapPolicy.Type.user.name())) { - List<Identity> identities = securityManager.getIdentitiesOfSecurityGroup(secGroup); - wrapper.addPolicy(policy); - wrapper.setType(EPMapPolicy.Type.user); - wrapper.addIdentities(identities); - } else if (permission.startsWith(EPMapPolicy.Type.group.name())) { - wrapper.addPolicy(policy); - BusinessGroup group = null;//TODO group businessGroupService.findBusinessGroup(policy.getSecurityGroup()); - wrapper.addGroup(group); - wrapper.setType(EPMapPolicy.Type.group); - } else if (permission.startsWith(EPMapPolicy.Type.invitation.name())) { - wrapper.addPolicy(policy); - Invitation invitation = securityManager.findInvitation(policy.getSecurityGroup()); - wrapper.setInvitation(invitation); - wrapper.setType(EPMapPolicy.Type.invitation); - } else if (permission.startsWith(EPMapPolicy.Type.allusers.name())) { - wrapper.addPolicy(policy); - wrapper.setType(EPMapPolicy.Type.allusers); + String role = relation.getRole(); + if(role.startsWith(EPMapPolicy.Type.user.name())) { + List<Identity> identities = groupDao.getMembers(relation.getGroup(), GroupRoles.participant.name()); + + policy.addRelation(relation); + policy.setType(EPMapPolicy.Type.user); + policy.addIdentities(identities); + } else if (role.startsWith(EPMapPolicy.Type.group.name())) { + policy.addRelation(relation); + BusinessGroup group = businessGroupDao.findBusinessGroup(relation.getGroup()); + policy.addGroup(group); + policy.setType(EPMapPolicy.Type.group); + } else if (role.startsWith(EPMapPolicy.Type.invitation.name())) { + policy.addRelation(relation); + Invitation invitation = invitationDao.findInvitation(relation.getGroup()); + policy.setInvitation(invitation); + policy.setType(EPMapPolicy.Type.invitation); + } else if (role.startsWith(EPMapPolicy.Type.allusers.name())) { + policy.addRelation(relation); + policy.setType(EPMapPolicy.Type.allusers); } } - return policyWrappers; + return policies; } - private EPMapPolicy getWrapperWithSamePolicy(Policy policy, List<EPMapPolicy> policyWrappers) { - Date to = policy.getTo(); - Date from = policy.getFrom(); - String permission = policy.getPermission(); + private EPMapPolicy getEquivalentWrapper(EPStructureElementToGroupRelation relation, List<EPMapPolicy> policies) { + Date to = relation.getValidTo(); + Date from = relation.getValidFrom(); + String role = relation.getRole(); a_a: - for(EPMapPolicy wrapper:policyWrappers) { - for(Policy p:wrapper.getPolicies()) { - if(!permission.equals(p.getPermission())) { + for(EPMapPolicy policy:policies) { + for(EPStructureElementToGroupRelation p:policy.getRelations()) { + if(!role.equals(p.getRole())) { continue a_a; } - if(from == null && p.getFrom() == null || (from != null && p.getFrom() != null && from.equals(p.getFrom()))) { - if(to == null && p.getTo() == null || (to != null && p.getTo() != null && to.equals(p.getTo()))) { - return wrapper; + if(from == null && p.getValidFrom() == null || (from != null && p.getValidFrom() != null && from.equals(p.getValidFrom()))) { + if(to == null && p.getValidTo() == null || (to != null && p.getValidTo() != null && to.equals(p.getValidTo()))) { + return policy; } } } @@ -124,114 +164,109 @@ public class EPPolicyManager extends BasicManager { /** * Update the map policies of a map. The missing policies are deleted! * @param map - * @param policyWrappers + * @param policies */ - public void updateMapPolicies(PortfolioStructureMap map, List<EPMapPolicy> policyWrappers) { - List<Policy> currentPolicies = securityManager.getPoliciesOfResource(map.getOlatResource(), null); - List<Policy> savedPolicies = new ArrayList<Policy>(); - for(EPMapPolicy wrapper:policyWrappers) { - savedPolicies.addAll(applyPolicy(wrapper, map, currentPolicies)); + public PortfolioStructureMap updateMapPolicies(PortfolioStructureMap map, List<EPMapPolicy> policies) { + map = dbInstance.getCurrentEntityManager().merge(map); + + List<EPStructureElementToGroupRelation> savedPolicies = new ArrayList<EPStructureElementToGroupRelation>(); + for(EPMapPolicy wrapper:policies) { + savedPolicies.addAll(applyPolicy(wrapper, map)); } - for(Policy currentPolicy:currentPolicies) { - boolean inUse = false; - for(Policy savedPolicy:savedPolicies) { - if(currentPolicy.equalsByPersistableKey(savedPolicy)) { - inUse = true; - break; - } + Collection<EPStructureElementToGroupRelation> currentRelations = new ArrayList<>(map.getGroups()); + for(EPStructureElementToGroupRelation currentRelation:currentRelations) { + if(currentRelation.isDefaultGroup()) { + continue; } - if(!inUse && currentPolicy.getPermission().contains(Constants.PERMISSION_READ)) { - deletePolicy(currentPolicy); + boolean inUse = savedPolicies.contains(currentRelation); + if(!inUse) { + map.getGroups().remove(currentRelation); } } + return dbInstance.getCurrentEntityManager().merge(map); } - private void deletePolicy(Policy policy) { - if(policy.getPermission().contains(Constants.PERMISSION_READ)) { - String permission = policy.getPermission(); - securityManager.deletePolicy(policy.getSecurityGroup(), permission, policy.getOlatResource()); - if("invitation_read".equals(permission)) { - Invitation invitation = securityManager.findInvitation(policy.getSecurityGroup()); - securityManager.deleteInvitation(invitation); - } - } - } - - private List<Policy> applyPolicy(EPMapPolicy wrapper, PortfolioStructureMap map, List<Policy> currentPolicies) { - List<Policy> policies = wrapper.getPolicies(); - List<Policy> savedPolicies = new ArrayList<Policy>(); - switch(wrapper.getType()) { + private List<EPStructureElementToGroupRelation> applyPolicy(EPMapPolicy policy, PortfolioStructureMap map) { + List<EPStructureElementToGroupRelation> savedPolicies = new ArrayList<EPStructureElementToGroupRelation>(); + switch(policy.getType()) { case user: - Policy policy = (policies == null || policies.isEmpty()) ? null : policies.get(0); - if(policy == null) { - SecurityGroup secGroup = securityManager.createAndPersistSecurityGroup(); - policy = securityManager.createAndPersistPolicy(secGroup, wrapper.getType() + "_" + Constants.PERMISSION_READ, wrapper.getFrom(), wrapper.getTo(), map.getOlatResource()); - } else { - Policy currentPolicy = reusePolicyInSession(policy, currentPolicies); - securityManager.updatePolicy(currentPolicy, wrapper.getFrom(), wrapper.getTo()); - } - SecurityGroup secGroup = policy.getSecurityGroup(); - List<Object[]> allIdents = securityManager.getIdentitiesAndDateOfSecurityGroup(secGroup); - for (Object[] objects : allIdents) { - Identity identity = (Identity) objects[0]; - securityManager.removeIdentityFromSecurityGroup(identity, secGroup); - } - for(Identity identity:wrapper.getIdentities()) { - if(!securityManager.isIdentityInSecurityGroup(identity, secGroup)) { - securityManager.addIdentityToSecurityGroup(identity, secGroup); - } - } - savedPolicies.add(policy); + savedPolicies.add(applyPolicyToUsers(policy, map)); break; case group: - for(BusinessGroup group:wrapper.getGroups()) { - //TODO group savedPolicies.add(applyPolicyTo(group.getPartipiciantGroup(), wrapper, map)); - //TODO group savedPolicies.add(applyPolicyTo(group.getOwnerGroup(), wrapper, map)); + for(BusinessGroup group:policy.getGroups()) { + savedPolicies.add(applyPolicyToGroup(group.getBaseGroup(), policy, map)); } break; case invitation: - Invitation invitation = wrapper.getInvitation(); - Policy invitationPolicy = applyPolicyTo(invitation, wrapper, map); + Invitation invitation = policy.getInvitation(); + EPStructureElementToGroupRelation invitationPolicy = applyPolicyToInvitation(invitation, policy, map); savedPolicies.add(invitationPolicy); break; case allusers: - Policy allUsersPolicy = applyPolicyToAllUsers(wrapper, map); + EPStructureElementToGroupRelation allUsersPolicy = applyPolicyToAllUsers(policy, map); savedPolicies.add(allUsersPolicy); break; } return savedPolicies; } - private Policy applyPolicyToAllUsers(EPMapPolicy wrapper, PortfolioStructureMap map) { - SecurityGroup allUsers = securityManager.findSecurityGroupByName(Constants.GROUP_OLATUSERS); - List<Policy> currentPolicies = securityManager.getPoliciesOfResource(map.getOlatResource(), allUsers); - if(!currentPolicies.isEmpty()) { - Policy currentPolicy = currentPolicies.get(0); - securityManager.updatePolicy(currentPolicy, wrapper.getFrom(), wrapper.getTo()); - return currentPolicy; + private EPStructureElementToGroupRelation applyPolicyToAllUsers(EPMapPolicy wrapper, PortfolioStructureMap map) { + List<EPStructureElementToGroupRelation> currentRelations = wrapper.getRelations(); + if(!currentRelations.isEmpty()) { + EPStructureElementToGroupRelation currentRelation = currentRelations.get(0); + updatePolicy(currentRelation, wrapper.getFrom(), wrapper.getTo()); + return currentRelation; } - - Policy policy = securityManager.createAndPersistPolicy(allUsers, wrapper.getType() + "_" + Constants.PERMISSION_READ, wrapper.getFrom(), wrapper.getTo(), map.getOlatResource()); - return policy; + return createBaseRelation(map, null, EPMapPolicy.Type.allusers.name(), wrapper.getFrom(), wrapper.getTo()); } - private Policy applyPolicyTo(Invitation invitation, EPMapPolicy wrapper, PortfolioStructureMap map) { - List<Policy> currentPolicies = securityManager.getPoliciesOfSecurityGroup(invitation.getSecurityGroup()); - for(Policy currentPolicy:currentPolicies) { - if(currentPolicy.getOlatResource().equalsByPersistableKey(map.getOlatResource())) { - currentPolicy = reusePolicyInSession(currentPolicy, currentPolicies); - securityManager.updatePolicy(currentPolicy, wrapper.getFrom(), wrapper.getTo()); - securityManager.updateInvitation(invitation); - return currentPolicy; + private EPStructureElementToGroupRelation applyPolicyToUsers(EPMapPolicy policy, PortfolioStructureMap map) { + List<EPStructureElementToGroupRelation> currentRelations = policy.getRelations(); + EPStructureElementToGroupRelation relation = (currentRelations == null || currentRelations.isEmpty()) ? null : currentRelations.get(0); + if(relation == null) { + Group secGroup = groupDao.createGroup(); + relation = createBaseRelation(map, secGroup, EPMapPolicy.Type.user.name(), policy.getFrom(), policy.getTo()); + for(Identity identity:policy.getIdentities()) { + groupDao.addMembership(secGroup, identity, GroupRoles.participant.name()); + } + } else { + EPStructureElementToGroupRelation currentPolicy = reusePolicyInSession(relation, map); + updatePolicy(currentPolicy, policy.getFrom(), policy.getTo()); + + Group secGroup = relation.getGroup(); + List<Identity> currentMembers = groupDao.getMembers(secGroup, GroupRoles.participant.name()); + List<Identity> newMembers = new ArrayList<>(policy.getIdentities()); + for (Identity newMember:policy.getIdentities()) { + if(currentMembers.contains(newMember)) { + newMembers.remove(newMember); + currentMembers.remove(newMember); + } + } + + for(Identity currentMember:currentMembers) { + groupDao.removeMembership(secGroup, currentMember); + } + for(Identity newMember:newMembers) { + groupDao.addMembership(secGroup, newMember, GroupRoles.participant.name()); + } + } + return relation; + } + + private EPStructureElementToGroupRelation applyPolicyToInvitation(Invitation invitation, EPMapPolicy policy, PortfolioStructureMap map) { + invitation = dbInstance.getCurrentEntityManager().merge(invitation); + Group secGroup = invitation.getBaseGroup(); + Collection<EPStructureElementToGroupRelation> currentRelations = map.getGroups(); + for(EPStructureElementToGroupRelation currentRelation:currentRelations) { + if(secGroup.equals(currentRelation.getGroup())) { + updatePolicy(currentRelation, policy.getFrom(), policy.getTo()); + return currentRelation; } } - SecurityGroup secGroup = invitation.getSecurityGroup(); - Policy policy = securityManager.createAndPersistPolicy(secGroup, wrapper.getType() + "_" + Constants.PERMISSION_READ, wrapper.getFrom(), wrapper.getTo(), map.getOlatResource()); - securityManager.updateInvitation(invitation); - return policy; + return createBaseRelation(map, secGroup, EPMapPolicy.Type.invitation.name(), policy.getFrom(), policy.getTo()); } /** @@ -241,27 +276,43 @@ public class EPPolicyManager extends BasicManager { * @param currentPolicies * @return */ - private Policy reusePolicyInSession(Policy policy, List<Policy> currentPolicies) { - for(Policy currentPolicy:currentPolicies) { - if(policy.equalsByPersistableKey(currentPolicy)) { - return currentPolicy; + private EPStructureElementToGroupRelation reusePolicyInSession(EPStructureElementToGroupRelation relation, PortfolioStructureMap map) { + Collection<EPStructureElementToGroupRelation> currentRelations = map.getGroups(); + for(EPStructureElementToGroupRelation currentRelation:currentRelations) { + if(relation.equalsByPersistableKey(currentRelation)) { + return currentRelation; } } - return policy; + return relation; } - private Policy applyPolicyTo(SecurityGroup secGroup, EPMapPolicy wrapper, PortfolioStructureMap map) { - List<Policy> currentPolicies = securityManager.getPoliciesOfSecurityGroup(secGroup); - for(Policy currentPolicy:currentPolicies) { - if(currentPolicy.getOlatResource().equalsByPersistableKey(map.getOlatResource())) { - currentPolicy = reusePolicyInSession(currentPolicy, currentPolicies); - securityManager.updatePolicy(currentPolicy, wrapper.getFrom(), wrapper.getTo()); - return currentPolicy; + private EPStructureElementToGroupRelation applyPolicyToGroup(Group group, EPMapPolicy policy, PortfolioStructureMap map) { + Collection<EPStructureElementToGroupRelation> currentRelations = map.getGroups(); + for(EPStructureElementToGroupRelation currentRelation:currentRelations) { + if(currentRelation.getGroup().equals(group)) { + updatePolicy(currentRelation, policy.getFrom(), policy.getTo()); + return currentRelation; } } - - Policy policy = securityManager.createAndPersistPolicy(secGroup, wrapper.getType() + "_read", wrapper.getFrom(), wrapper.getTo(), map.getOlatResource()); - return policy; + return createBaseRelation(map, group, EPMapPolicy.Type.group.name(), policy.getFrom(), policy.getTo()); + } + + private void updatePolicy(EPStructureElementToGroupRelation relation, Date from, Date to) { + relation.setValidFrom(from); + relation.setValidTo(to); } -} + private EPStructureElementToGroupRelation createBaseRelation(PortfolioStructureMap map, Group group, String role, Date from, Date to) { + //create security group + EPStructureElementToGroupRelation relation = new EPStructureElementToGroupRelation(); + relation.setDefaultGroup(false); + relation.setCreationDate(new Date()); + relation.setGroup(group); + relation.setStructureElement((EPStructureElement)map); + relation.setRole(role); + relation.setValidFrom(from); + relation.setValidTo(to); + map.getGroups().add(relation); + return relation; + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/portfolio/manager/EPStructureManager.java b/src/main/java/org/olat/portfolio/manager/EPStructureManager.java index fc17aa6c5017fa65240e670636a5285b354e594a..7fad716dd5018310ae1843e49907953cc1bb7f1f 100755 --- a/src/main/java/org/olat/portfolio/manager/EPStructureManager.java +++ b/src/main/java/org/olat/portfolio/manager/EPStructureManager.java @@ -24,17 +24,17 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import javax.persistence.TypedQuery; import org.hibernate.ObjectNotFoundException; -import org.olat.basesecurity.Constants; import org.olat.basesecurity.Group; import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.IdentityRef; -import org.olat.basesecurity.NamedGroupImpl; import org.olat.basesecurity.PolicyImpl; import org.olat.basesecurity.SecurityGroupImpl; import org.olat.basesecurity.SecurityGroupMembershipImpl; @@ -60,6 +60,7 @@ import org.olat.portfolio.model.structel.EPDefaultMap; import org.olat.portfolio.model.structel.EPMapShort; import org.olat.portfolio.model.structel.EPPage; import org.olat.portfolio.model.structel.EPStructureElement; +import org.olat.portfolio.model.structel.EPStructureElementToGroupRelation; import org.olat.portfolio.model.structel.EPStructureToArtefactLink; import org.olat.portfolio.model.structel.EPStructureToStructureLink; import org.olat.portfolio.model.structel.EPStructuredMap; @@ -182,7 +183,8 @@ public class EPStructureManager extends BasicManager { protected List<PortfolioStructure> getStructureElementsForUser(IdentityRef ident, ElementType... types){ StringBuilder sb = new StringBuilder(); sb.append("select stEl from ").append(EPStructureElement.class.getName()).append(" as stEl") - .append(" inner join fetch stEl.group as baseGroup") + .append(" inner join stEl.groups as relGroup on relGroup.defaultGroup=true") + .append(" inner join relGroup.group as baseGroup") .append(" where exists (select membership from bgroupmember as membership " ) .append(" where baseGroup=membership.group and membership.identity.key=:identityKey and membership.role='").append(GroupRoles.owner.name()).append("'") .append(" )"); @@ -212,10 +214,12 @@ public class EPStructureManager extends BasicManager { protected boolean isMapOwner(IdentityRef identity, OLATResourceable ores) { StringBuilder sb = new StringBuilder(); sb.append("select count(stEl) from ").append(EPStructureElement.class.getName()).append(" stEl ") + .append(" inner join stEl.groups as relGroup on relGroup.defaultGroup=true") + .append(" inner join relGroup.group as baseGroup") .append(" where stEl.olatResource.resId=:resourceableId") .append(" and stEl.olatResource.resName=:resourceableTypeName") .append(" and exists (select membership from bgroupmember as membership " ) - .append(" where stEl.group=membership.group and membership.identity.key=:identityKey and membership.role='").append(GroupRoles.owner.name()).append("'") + .append(" where baseGroup=membership.group and membership.identity.key=:identityKey and membership.role='").append(GroupRoles.owner.name()).append("'") .append(" )"); Number count = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Number.class) @@ -232,34 +236,28 @@ public class EPStructureManager extends BasicManager { * @param ores * @return */ - protected boolean isMapVisible(Identity identity, OLATResourceable ores) { + protected boolean isMapVisible(IdentityRef identity, OLATResourceable ores) { StringBuilder sb = new StringBuilder(); - sb.append("select count(stEl) from ").append(EPStructureElement.class.getName()).append(" stEl ") - .append(" inner join stEl.olatResource as oRes ") - .append(" inner join stEl.group as baseGroup ") + sb.append("select count(stEl) from ").append(EPStructureElement.class.getName()).append(" stEl") + .append(" inner join stEl.olatResource as oRes") + .append(" inner join stEl.groups as relGroup") .append(" where oRes.resId=:resourceableId and oRes.resName=:resourceableTypeName") - .append(" and ( oRes in ( " ) - .append(" select policy.olatResource from") - .append(" ").append(PolicyImpl.class.getName()).append(" as policy, ") - .append(" ").append(SecurityGroupImpl.class.getName()).append(" as sgi,") - .append(" ").append(SecurityGroupMembershipImpl.class.getName()).append(" as sgmsi ") - .append(" where sgi = policy.securityGroup")//implicit inner join - .append(" and (sgmsi.securityGroup = sgi and sgmsi.identity =:identity) ")//member of the security group - .append(" and (policy.from is null or policy.from<=:date)") - .append(" and (policy.to is null or policy.to>=:date)") - .append(" )") - .append(" or exists (select membership from bgroupmember as membership " ) - .append(" where membership.group=baseGroup and membership.identity.key=:identity") - .append(" ))"); + .append(" and (relGroup.validFrom is null or relGroup.validFrom<=:date)") + .append(" and (relGroup.validTo is null or relGroup.validTo>=:date)") + .append(" and (relGroup.role='").append(EPMapPolicy.Type.allusers.name()).append("'") + .append(" or exists (select membership from bgroupmember as membership " ) + .append(" where membership.group=relGroup.group and membership.identity.key=:identityKey") + .append(" )") + .append(" )"); - DBQuery query = dbInstance.createQuery(sb.toString()); - query.setEntity("identity", identity); - query.setLong("resourceableId", ores.getResourceableId()); - query.setString("resourceableTypeName", ores.getResourceableTypeName()); - query.setDate("date", new Date()); - - Number count = (Number)query.uniqueResult(); - return count.intValue() == 1; + Number count = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Number.class) + .setParameter("identityKey", identity.getKey()) + .setParameter("resourceableId", ores.getResourceableId()) + .setParameter("resourceableTypeName", ores.getResourceableTypeName()) + .setParameter("date", new Date()) + .getSingleResult(); + return count == null ? false : count.intValue() > 0; } /** @@ -278,9 +276,10 @@ public class EPStructureManager extends BasicManager { .append(" inner join stEl.olatResource as oRes "); } else { sb.append("select stEl from ").append(EPStructureElement.class.getName()).append(" stEl ") - .append(" inner join fetch stEl.olatResource as oRes ") - .append(" inner join fetch stEl.group as baseGroup "); + .append(" inner join fetch stEl.olatResource as oRes "); } + sb.append(" inner join stEl.groups as relGroup on relGroup.defaultGroup=true") + .append(" inner join relGroup.group as baseGroup"); sb.append(" where oRes in ( ").append(" select policy.olatResource from").append(" ").append(PolicyImpl.class.getName()).append(" as policy, ").append(" ") .append(SecurityGroupImpl.class.getName()).append(" as sgi,").append(" ").append(SecurityGroupMembershipImpl.class.getName()).append(" as sgmsi ") @@ -288,8 +287,8 @@ public class EPStructureManager extends BasicManager { .append(" and (sgmsi.securityGroup = sgi and sgmsi.identity =:ident) ")// member of the security group .append(" and (policy.from is null or policy.from<=:date)").append(" and (policy.to is null or policy.to>=:date)").append(" )"); // remove owner - sb.append(" and stEl.group not in ( ").append("select sgi2 from bgroup as sgi2, bgroupmember as sgmsi2 ") - .append(" where sgmsi2.group=sgi2 and sgmsi2.identity=:ident") + sb.append(" and not exists ( ").append("select sgi2 from bgroup as sgi2, bgroupmember as sgmsi2 ") + .append(" where baseGroup=sgi2 and sgmsi2.group=sgi2 and sgmsi2.identity=:ident") .append(" )"); if (choosenOwner != null) { @@ -342,35 +341,20 @@ public class EPStructureManager extends BasicManager { return query.getResultList(); } - protected List<PortfolioStructure> getStructureElementsFromOthersWithoutPublic(Identity ident, Identity choosenOwner, ElementType... types){ + protected List<PortfolioStructure> getStructureElementsFromOthersWithoutPublic(IdentityRef ident, IdentityRef choosenOwner, ElementType... types){ StringBuilder sb = new StringBuilder(); - sb.append("select stEl from ").append(EPStructureElement.class.getName()).append(" stEl "); - sb.append(" inner join stEl.olatResource as oRes "); - sb.append(" where oRes in ( " ) - .append(" select policy.olatResource from") - .append(" ").append(PolicyImpl.class.getName()).append(" as policy, ") - .append(" ").append(SecurityGroupImpl.class.getName()).append(" as sgi,") - .append(" ").append(SecurityGroupMembershipImpl.class.getName()).append(" as sgmsi ") - .append(" where sgi = policy.securityGroup ") //implicit inner join - .append(" and sgi = policy.securityGroup ") - .append(" and (sgmsi.securityGroup = sgi and sgmsi.identity =:ident) ") //member of the security group - .append(" and (policy.from is null or policy.from<=:date)") - .append(" and (policy.to is null or policy.to>=:date)") - .append(" and sgi not in (") - .append(" select ngroup.securityGroup from ") - .append(" ").append(NamedGroupImpl.class.getName()).append(" as ngroup ") - .append(" where ngroup.groupName =:usersGroup") - .append(" )") - .append(" )"); - - //remove owner - sb.append(" and stEl.group not in (select sgi2 from bgroup as sgi2, bgroupmember as sgmsi2 ") - .append(" where sgmsi2.group=sgi2 and sgmsi2.identity=:ident") - .append(" )"); + sb.append("select stEl from ").append(EPStructureElement.class.getName()).append(" stEl ") + .append(" inner join fetch stEl.olatResource as oRes ") + .append(" inner join stEl.groups as relGroup on relGroup.defaultGroup=false") + .append(" inner join relGroup.group as baseGroup") + .append(" inner join baseGroup.members as members") + .append(" where members.identity.key=:identityKey") + .append(" and (relGroup.validFrom is null or relGroup.validFrom<=:date)") + .append(" and (relGroup.validTo is null or relGroup.validTo>=:date)"); if(choosenOwner != null) { - sb.append(" and stEl.group in (select sgi from bgroup as sgi, bgroupmember as sgmsi ") - .append(" where sgmsi.group=sgi and sgmsi.identity=:owner") + sb.append(" and exists (select sgi from bgroupmember as sgmsi ") + .append(" where sgmsi.group=baseGroup and sgmsi.identity.key=:ownerKey") .append(" )"); } if(types != null && types.length > 0) { @@ -384,20 +368,17 @@ public class EPStructureManager extends BasicManager { sb.append(")"); } - DBQuery query = dbInstance.createQuery(sb.toString()); - query.setEntity("ident", ident); - query.setString("usersGroup", Constants.GROUP_OLATUSERS); - query.setDate("date", new Date()); + TypedQuery<PortfolioStructure> query =dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), PortfolioStructure.class) + .setParameter("identityKey", ident.getKey()) + .setParameter("date", new Date()); if(choosenOwner != null) { - query.setEntity("owner", choosenOwner); + query.setParameter("ownerKey", choosenOwner.getKey()); } - @SuppressWarnings("unchecked") - List<PortfolioStructure> pStructs = query.list(); - return pStructs; + return query.getResultList(); } - private Class<?> getImplementation(ElementType type) { switch(type) { case DEFAULT_MAP: return EPDefaultMap.class; @@ -1035,16 +1016,23 @@ public class EPStructureManager extends BasicManager { struct = (EPStructureElement) dbInstance.loadObject((EPStructureElement)struct); dbInstance.deleteObject(struct); if (struct instanceof EPAbstractMap){ - EPAbstractMap esmap = (EPAbstractMap)struct; - Group group = esmap.getGroup(); - if (group != null) { - groupDao.removeGroup(group); - } + removeBaseGroup((EPAbstractMap)struct); } resourceManager.deleteOLATResourceable(struct); } + private void removeBaseGroup(EPAbstractMap map) { + Set<EPStructureElementToGroupRelation> relations = map.getGroups(); + if (relations != null) { + for(EPStructureElementToGroupRelation relation:relations) { + if(relation.isDefaultGroup()) { + groupDao.removeGroup(relation.getGroup()); + } + dbInstance.getCurrentEntityManager().remove(relation); + } + } + } /** * Move a structure element up in the list @@ -1381,17 +1369,19 @@ public class EPStructureManager extends BasicManager { StringBuilder sb = new StringBuilder(); sb.append("select map from ").append(EPStructuredMap.class.getName()).append(" map") - .append(" inner join fetch map.group as baseGroup") + .append(" left join fetch map.targetResource as targetResource") + .append(" inner join map.groups as relGroup on relGroup.defaultGroup=true") + .append(" inner join relGroup.group as baseGroup") .append(" where map.structuredMapSource=:template"); if (targetOres != null) { - sb.append(" and map.targetResource.resourceableId=:resourceId") - .append(" and map.targetResource.resourceableTypeName=:resourceType"); + sb.append(" and targetResource.resourceableId=:resourceId") + .append(" and targetResource.resourceableTypeName=:resourceType"); } if (targetSubPath != null) { - sb.append(" and map.targetResource.subPath=:subPath"); + sb.append(" and targetResource.subPath=:subPath"); } if (targetBusinessPath != null) { - sb.append(" and map.targetResource.businessPath=:businessPath"); + sb.append(" and targetResource.businessPath=:businessPath"); } sb.append(" and exists (select membership from bgroupmember as membership " ) .append(" where baseGroup=membership.group and membership.identity.key=:identityKey and membership.role='").append(GroupRoles.owner.name()).append("'") @@ -1430,7 +1420,8 @@ public class EPStructureManager extends BasicManager { StringBuilder sb = new StringBuilder(); sb.append("select map from ").append(EPStructuredMap.class.getName()).append(" map") - .append(" inner join fetch map.group as baseGroup") + .append(" inner join map.groups as relGroup on relGroup.defaultGroup=true") + .append(" inner join relGroup.group as baseGroup") .append(" inner join fetch map.targetResource as targetResource") .append(" where targetResource.resourceableId=:resourceId and targetResource.resourceableTypeName=:resourceType"); @@ -1539,7 +1530,6 @@ public class EPStructureManager extends BasicManager { StringBuilder sb = new StringBuilder(); sb.append("select element from ").append(EPStructureElement.class.getName()).append(" element") .append(" left join fetch element.olatResource as oRes") - .append(" left join fetch element.group as baseGroup") .append(" where element.key=:key");; List<PortfolioStructure> resources = dbInstance.getCurrentEntityManager() @@ -1641,8 +1631,11 @@ public class EPStructureManager extends BasicManager { fillStructureElement(el, title, description); //create security group - Group ownerGroup = createBaseGroup(identity); - el.setGroup(ownerGroup); + EPStructureElementToGroupRelation ownerGroup = createBaseGroup(el, identity); + Set<EPStructureElementToGroupRelation> relations = new HashSet<>(); + relations.add(ownerGroup); + el.setGroups(relations); + return el; } @@ -1652,8 +1645,10 @@ public class EPStructureManager extends BasicManager { fillStructureElement(el, title, description); //create security group - Group ownerGroup = createBaseGroup(identity); - el.setGroup(ownerGroup); + EPStructureElementToGroupRelation ownerGroup = createBaseGroup(el, identity); + Set<EPStructureElementToGroupRelation> relations = new HashSet<>(); + relations.add(ownerGroup); + el.setGroups(relations); return el; } @@ -1699,7 +1694,11 @@ public class EPStructureManager extends BasicManager { dbInstance.commit(); Group ownerGroup = repositoryService.getDefaultGroup(re); - el.setGroup(ownerGroup); + + EPStructureElementToGroupRelation relation = createBaseRelation(el, ownerGroup); + Set<EPStructureElementToGroupRelation> relations = new HashSet<>(); + relations.add(relation); + el.setGroups(relations); return el; } @@ -1719,8 +1718,12 @@ public class EPStructureManager extends BasicManager { el.setStyle(((EPStructureElement)root).getStyle()); importEPStructureElementRecursively((EPStructureElement)root, el); - //create an empty security group - el.setGroup(groupDao.createGroup()); + //create an empty group + Group ownerGroup = groupDao.createGroup(); + EPStructureElementToGroupRelation relation = createBaseRelation(el, ownerGroup); + Set<EPStructureElementToGroupRelation> relations = new HashSet<>(); + relations.add(relation); + el.setGroups(relations); return el; } @@ -1770,7 +1773,11 @@ public class EPStructureManager extends BasicManager { group = groupDao.createGroup(); groupDao.addMembership(group, identity, GroupRoles.owner.name()); } - el.setGroup(group); + + EPStructureElementToGroupRelation relation = createBaseRelation(el, group); + Set<EPStructureElementToGroupRelation> relations = new HashSet<>(); + relations.add(relation); + el.setGroups(relations); dbInstance.saveObject(el); return el; } @@ -1812,11 +1819,26 @@ public class EPStructureManager extends BasicManager { return addedEntry; } - private Group createBaseGroup(Identity author) { + private EPStructureElementToGroupRelation createBaseGroup(EPStructureElement element, Identity author) { //create security group Group ownerGroup = groupDao.createGroup(); + EPStructureElementToGroupRelation relation = new EPStructureElementToGroupRelation(); + relation.setDefaultGroup(true); + relation.setCreationDate(new Date()); + relation.setGroup(ownerGroup); + relation.setStructureElement(element); groupDao.addMembership(ownerGroup, author, GroupRoles.owner.name()); - return ownerGroup; + return relation; + } + + private EPStructureElementToGroupRelation createBaseRelation(EPStructureElement element, Group ownerGroup) { + //create security group + EPStructureElementToGroupRelation relation = new EPStructureElementToGroupRelation(); + relation.setDefaultGroup(true); + relation.setCreationDate(new Date()); + relation.setGroup(ownerGroup); + relation.setStructureElement(element); + return relation; } /** diff --git a/src/main/java/org/olat/portfolio/manager/EPXStreamHandler.java b/src/main/java/org/olat/portfolio/manager/EPXStreamHandler.java index d82a06176a12c0f796b62cd8a1399c22478c0d0b..2e9b149319566c91bcc3b6db615b23c52b1bc0d0 100644 --- a/src/main/java/org/olat/portfolio/manager/EPXStreamHandler.java +++ b/src/main/java/org/olat/portfolio/manager/EPXStreamHandler.java @@ -116,7 +116,7 @@ public class EPXStreamHandler { PortfolioStructure struct = (PortfolioStructure) myStream.fromXML(buffer.toString()); // OLAT-6344: reset ownerGroup from earlier exports. A new group is created by import in ePFMgr.importPortfolioMapTemplate() later on anyway. - ((EPAbstractMap) struct).setGroup(null); + ((EPAbstractMap) struct).setGroups(null); return struct; } catch (Exception e) { log.error("Cannot export this map: " + fMapXml, e); diff --git a/src/main/java/org/olat/basesecurity/InvitationCleanupJob.java b/src/main/java/org/olat/portfolio/manager/InvitationCleanupJob.java similarity index 90% rename from src/main/java/org/olat/basesecurity/InvitationCleanupJob.java rename to src/main/java/org/olat/portfolio/manager/InvitationCleanupJob.java index fe204a518ab5450d3f8857b63647f34d7e0b455a..bbcc1f0242eab397dc6b9b8cd250aab96f768e4a 100644 --- a/src/main/java/org/olat/basesecurity/InvitationCleanupJob.java +++ b/src/main/java/org/olat/portfolio/manager/InvitationCleanupJob.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.basesecurity; +package org.olat.portfolio.manager; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.scheduler.JobWithDB; @@ -39,8 +39,8 @@ public class InvitationCleanupJob extends JobWithDB { public void executeWithDB(JobExecutionContext context) { try { log.info("Starting invitation clean up job"); - BaseSecurity securityManager = (BaseSecurity)CoreSpringFactory.getBean("baseSecurityManager"); - securityManager.cleanUpInvitations(); + InvitationDAO invitationDao = CoreSpringFactory.getImpl(InvitationDAO.class); + invitationDao.cleanUpInvitations(); } catch (Exception e) { // ups, something went completely wrong! We log this but continue next time log.error("Error while cleaning up invitation", e); diff --git a/src/main/java/org/olat/portfolio/manager/InvitationDAO.java b/src/main/java/org/olat/portfolio/manager/InvitationDAO.java new file mode 100644 index 0000000000000000000000000000000000000000..2ef57eb5e481691e0bcacb74f1eae8dffbb3586d --- /dev/null +++ b/src/main/java/org/olat/portfolio/manager/InvitationDAO.java @@ -0,0 +1,241 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.portfolio.manager; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.UUID; + +import javax.persistence.TypedQuery; + +import org.olat.admin.user.delete.service.UserDeletionManager; +import org.olat.basesecurity.BaseSecurity; +import org.olat.basesecurity.Constants; +import org.olat.basesecurity.Group; +import org.olat.basesecurity.GroupRoles; +import org.olat.basesecurity.IdentityRef; +import org.olat.basesecurity.Invitation; +import org.olat.basesecurity.PolicyImpl; +import org.olat.basesecurity.SecurityGroup; +import org.olat.basesecurity.manager.GroupDAO; +import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; +import org.olat.core.id.User; +import org.olat.portfolio.model.InvitationImpl; +import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * This is only for e-Portfolio. For wider useage, need a refactor of the datamodel + * and of process and workflow. Don't be afraid of reference ot e-Portfolio datamodel + * here. + * + * + * Initial date: 25.06.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Service(value="invitationDao") +public class InvitationDAO { + + @Autowired + private DB dbInstance; + @Autowired + private GroupDAO groupDao; + @Autowired + private UserManager userManager; + @Autowired + private BaseSecurity securityManager; + + /** + * Create and persist an invitation with its security group and security token. + * @return + */ + public Invitation createAndPersistInvitation() { + Group group = groupDao.createGroup(); + + InvitationImpl invitation = new InvitationImpl(); + invitation.setToken(UUID.randomUUID().toString()); + invitation.setBaseGroup(group); + dbInstance.getCurrentEntityManager().persist(invitation); + return invitation; + } + + public Invitation update(Invitation invitation) { + return dbInstance.getCurrentEntityManager().merge(invitation); + } + + public Identity createIdentityFrom(Invitation invitation, Locale locale) { + String tempUsername = UUID.randomUUID().toString(); + User user = userManager.createAndPersistUser(invitation.getFirstName(), invitation.getLastName(), invitation.getMail()); + user.getPreferences().setLanguage(locale.toString()); + Identity invitee = securityManager.createAndPersistIdentity(tempUsername, user, null, null, null); + groupDao.addMembership(invitation.getBaseGroup(), invitee, GroupRoles.invitee.name()); + return invitee; + } + + /** + * Is the invitation linked to any valid policies + * @param token + * @param atDate + * @return + */ + public boolean hasInvitations(String token, Date atDate) { + StringBuilder sb = new StringBuilder(); + sb.append("select count(relation) from structuretogroup as relation ") + .append(" inner join relation.group as baseGroup") + .append(" where exists (select invitation.key from binvitation as invitation where ") + .append(" invitation.baseGroup=baseGroup and invitation.token=:token") + .append(" )"); + + if(atDate != null) { + sb.append(" and (relation.validFrom is null or relation.validFrom<=:date)") + .append(" and (relation.validTo is null or relation.validTo>=:date)"); + } + + TypedQuery<Number> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Number.class) + .setParameter("token", token); + if(atDate != null) { + query.setParameter("date", atDate); + } + + Number counter = query.getSingleResult(); + return counter == null ? false : counter.intValue() > 0; + } + + /** + * Find an invitation by its security group + * @param secGroup + * @return The invitation or null if not found + */ + public Invitation findInvitation(Group group) { + StringBuilder sb = new StringBuilder(); + sb.append("select invitation from binvitation as invitation ") + .append(" where invitation.baseGroup=:group"); + + List<Invitation> invitations = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Invitation.class) + .setParameter("group", group) + .getResultList(); + if(invitations.isEmpty()) return null; + return invitations.get(0); + } + + /** + * Find an invitation by its security token + * @param token + * @return The invitation or null if not found + */ + public Invitation findInvitation(String token) { + StringBuilder sb = new StringBuilder(); + sb.append("select invitation from binvitation as invitation ") + .append(" where invitation.token=:token"); + + List<Invitation> invitations = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Invitation.class) + .setParameter("token", token) + .getResultList(); + return invitations.isEmpty() ? null : invitations.get(0); + } + + /** + * Check if the identity has an invitation, valid or not + * @param identity + * @return + */ + public boolean isInvitee(IdentityRef identity) { + StringBuilder sb = new StringBuilder(); + sb.append("select count(invitation) from binvitation as invitation") + .append(" inner join invitation.baseGroup as baseGroup ") + .append(" inner join baseGroup.members as members") + .append(" inner join members.identity as ident") + .append(" where ident.key=:identityKey"); + + Number invitations = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Number.class) + .setParameter("identityKey", identity.getKey()) + .getSingleResult(); + return invitations == null ? false : invitations.intValue() > 0; + } + + /** + * Delete an invitation + * @param invitation + */ + public void deleteInvitation(Invitation invitation) { + //fxdiff: FXOLAT-251: nothing persisted, nothing to delete + if(invitation == null || invitation.getKey() == null) return; + dbInstance.getCurrentEntityManager().remove(invitation); + } + + /** + * Clean up old invitation and set to deleted temporary users + */ + public void cleanUpInvitations() { + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date()); + Date currentTime = cal.getTime(); + cal.add(Calendar.HOUR, -6); + Date dateLimit = cal.getTime(); + + StringBuilder sb = new StringBuilder(); + sb.append("select invitation from ").append(InvitationImpl.class.getName()).append(" as invitation ") + .append(" inner join invitation.securityGroup secGroup ") + .append(" where invitation.creationDate<:dateLimit")//someone can create an invitation but not add it to a policy within millisecond + .append(" and secGroup not in (") + //select all valid policies from this security group + .append(" select policy.securityGroup from ").append(PolicyImpl.class.getName()).append(" as policy ") + .append(" where (policy.from is null or policy.from<=:currentDate)") + .append(" and (policy.to is null or policy.to>=:currentDate)") + .append(" )"); + + List<Invitation> oldInvitations = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Invitation.class) + .setParameter("currentDate", currentTime) + .setParameter("dateLimit", dateLimit) + .getResultList(); + + if(oldInvitations.isEmpty()) { + return; + } + + SecurityGroup olatUserSecGroup = securityManager.findSecurityGroupByName(Constants.GROUP_OLATUSERS); + for(Invitation invitation:oldInvitations) { + List<Identity> identities = groupDao.getMembers(invitation.getBaseGroup(), GroupRoles.invitee.name()); + //normally only one identity + for(Identity identity:identities) { + if(identity.getStatus().compareTo(Identity.STATUS_VISIBLE_LIMIT) >= 0) { + //already deleted + } else if(securityManager.isIdentityInSecurityGroup(identity, olatUserSecGroup)) { + //out of scope + } else { + //delete user + UserDeletionManager.getInstance().deleteIdentity(identity); + } + } + dbInstance.getCurrentEntityManager().remove(invitation); + dbInstance.commit(); + } + } +} diff --git a/src/main/java/org/olat/portfolio/model/InvitationImpl.java b/src/main/java/org/olat/portfolio/model/InvitationImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..30578fb2b1cf47aebcc356d0111fc4cf73b968d8 --- /dev/null +++ b/src/main/java/org/olat/portfolio/model/InvitationImpl.java @@ -0,0 +1,154 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ + +package org.olat.portfolio.model; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.hibernate.annotations.GenericGenerator; +import org.olat.basesecurity.Group; +import org.olat.basesecurity.Invitation; +import org.olat.basesecurity.model.GroupImpl; +import org.olat.core.id.CreateInfo; +import org.olat.core.id.Persistable; + +/** + * + * Description:<br> + * Implementation of Invitation + * + * <P> + * Initial Date: 10 nov. 2010 <br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +@Entity(name="binvitation") +@Table(name="o_bs_invitation") +public class InvitationImpl implements CreateInfo, Persistable, Invitation { + + private static final long serialVersionUID = -9122616013810215550L; + + @Id + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "hilo") + @Column(name="id", nullable=false, unique=true, insertable=true, updatable=false) + private Long key; + @Temporal(TemporalType.TIMESTAMP) + @Column(name="creationdate", nullable=false, insertable=true, updatable=false) + private Date creationDate; + + @Column(name="token", nullable=true, unique=true, insertable=true, updatable=true) + private String token; + @Column(name="first_name", nullable=true, unique=true, insertable=true, updatable=true) + private String firstName; + @Column(name="last_name", nullable=true, unique=true, insertable=true, updatable=true) + private String lastName; + @Column(name="mail", nullable=true, unique=true, insertable=true, updatable=true) + private String mail; + + @ManyToOne(targetEntity=GroupImpl.class,fetch=FetchType.LAZY,optional=false) + @JoinColumn(name="fk_group_id", nullable=false, insertable=true, updatable=false) + private Group baseGroup; + + @Override + public Long getKey() { + return key; + } + + @Override + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } + + public Group getBaseGroup() { + return baseGroup; + } + + public void setBaseGroup(Group baseGroup) { + this.baseGroup = baseGroup; + } + + @Override + public int hashCode() { + return key == null ? -98260 : key.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } else if (obj instanceof InvitationImpl) { + InvitationImpl invitation = (InvitationImpl)obj; + return getKey() != null && getKey().equals(invitation.getKey()); + } + return false; + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } +} diff --git a/src/main/java/org/olat/portfolio/model/structel/EPAbstractMap.java b/src/main/java/org/olat/portfolio/model/structel/EPAbstractMap.java index f54b776327311afcee7a36a4d4efb505aa2298f2..4931adffb860cd037373725742201c1a65444e12 100755 --- a/src/main/java/org/olat/portfolio/model/structel/EPAbstractMap.java +++ b/src/main/java/org/olat/portfolio/model/structel/EPAbstractMap.java @@ -19,7 +19,7 @@ */ package org.olat.portfolio.model.structel; -import org.olat.basesecurity.Group; +import java.util.Set; /** * @@ -34,14 +34,15 @@ public abstract class EPAbstractMap extends EPStructureElement implements Portfo private static final long serialVersionUID = 3295737167134638317L; - private Group group; + private Set<EPStructureElementToGroupRelation> groups; - public Group getGroup() { - return group; + @Override + public Set<EPStructureElementToGroupRelation> getGroups() { + return groups; } - public void setGroup(Group group) { - this.group = group; + public void setGroups(Set<EPStructureElementToGroupRelation> groups) { + this.groups = groups; } @Override diff --git a/src/main/java/org/olat/portfolio/model/structel/EPMapShort.java b/src/main/java/org/olat/portfolio/model/structel/EPMapShort.java index 1851578092e4666b6993f2e298e28266b483895d..046d043eae52abecac71e127fb4e801024f649e3 100644 --- a/src/main/java/org/olat/portfolio/model/structel/EPMapShort.java +++ b/src/main/java/org/olat/portfolio/model/structel/EPMapShort.java @@ -19,7 +19,8 @@ */ package org.olat.portfolio.model.structel; -import org.olat.basesecurity.Group; +import java.util.Set; + import org.olat.core.commons.persistence.PersistentObject; import org.olat.resource.OLATResource; @@ -29,19 +30,15 @@ import org.olat.resource.OLATResource; * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class EPMapShort extends PersistentObject { +public class EPMapShort extends PersistentObject implements PortfolioStructureMapRef { private static final long serialVersionUID = 3093838342982364478L; private String title; private Long sourceMapKey; private OLATResource olatResource; - private Group group; + private Set<EPStructureElementToGroupRelation> groups; - public EPMapShort() { - // - } - public Long getSourceMapKey() { return sourceMapKey; @@ -67,12 +64,12 @@ public class EPMapShort extends PersistentObject { this.olatResource = olatResource; } - public Group getGroup() { - return group; + public Set<EPStructureElementToGroupRelation> getGroups() { + return groups; } - public void setGroup(Group group) { - this.group = group; + public void setGroups(Set<EPStructureElementToGroupRelation> groups) { + this.groups = groups; } @Override diff --git a/src/main/java/org/olat/portfolio/model/structel/EPStructureElementToGroupRelation.java b/src/main/java/org/olat/portfolio/model/structel/EPStructureElementToGroupRelation.java new file mode 100644 index 0000000000000000000000000000000000000000..9dd0f3632b56da8fc6c166bf618ceb0ab26613bc --- /dev/null +++ b/src/main/java/org/olat/portfolio/model/structel/EPStructureElementToGroupRelation.java @@ -0,0 +1,179 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.portfolio.model.structel; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.hibernate.annotations.GenericGenerator; +import org.olat.basesecurity.Group; +import org.olat.basesecurity.model.GroupImpl; +import org.olat.core.id.Persistable; + +/** + * + * Initial date: 24.06.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Entity(name="structuretogroup") +@Table(name="o_ep_struct_to_group") +public class EPStructureElementToGroupRelation implements Persistable { + + private static final long serialVersionUID = 2215547264646107606L; + + @Id + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "hilo") + @Column(name="id", nullable=false, unique=true, insertable=true, updatable=false) + private Long key; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="creationdate", nullable=false, insertable=true, updatable=false) + private Date creationDate; + + @Column(name="r_defgroup", nullable=false, insertable=true, updatable=false) + private boolean defaultGroup = false; + + @Column(name="r_role", nullable=true, insertable=true, updatable=true) + private String role; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="r_valid_from", nullable=true, insertable=true, updatable=true) + private Date validFrom; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="r_valid_to", nullable=true, insertable=true, updatable=true) + private Date validTo; + + @ManyToOne(targetEntity=GroupImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_group_id", nullable=true, insertable=true, updatable=false) + private Group group; + + @ManyToOne(targetEntity=EPStructureElement.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_struct_id", nullable=true, insertable=true, updatable=true)//updatable need for deletion + private EPStructureElement structureElement; + + public Long getKey() { + return key; + } + + public void setKey(Long key) { + this.key = key; + } + + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public boolean isDefaultGroup() { + return defaultGroup; + } + + public void setDefaultGroup(boolean defaultGroup) { + this.defaultGroup = defaultGroup; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public Date getValidFrom() { + return validFrom; + } + + public void setValidFrom(Date validFrom) { + this.validFrom = validFrom; + } + + public Date getValidTo() { + return validTo; + } + + public void setValidTo(Date validTo) { + this.validTo = validTo; + } + + public Group getGroup() { + return group; + } + + public void setGroup(Group group) { + this.group = group; + } + + public EPStructureElement getStructureElement() { + return structureElement; + } + + public void setStructureElement(EPStructureElement entry) { + this.structureElement = entry; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("reToGroup[resource=") + .append(structureElement.getKey()).append(":") + .append("group=").append(group.getKey()) + .append("]"); + return sb.toString(); + } + + @Override + public int hashCode() { + return getKey() == null ? 29061 : getKey().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if(obj instanceof EPStructureElementToGroupRelation) { + EPStructureElementToGroupRelation rel = (EPStructureElementToGroupRelation)obj; + return getKey() != null && getKey().equals(rel.getKey()); + } + return false; + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/portfolio/model/structel/PortfolioStructureMap.java b/src/main/java/org/olat/portfolio/model/structel/PortfolioStructureMap.java index cc3f1c65d6a2e85fa014a96eea0f3326e9491d23..787a1e201434e9c596d031f73e9154895f40b708 100755 --- a/src/main/java/org/olat/portfolio/model/structel/PortfolioStructureMap.java +++ b/src/main/java/org/olat/portfolio/model/structel/PortfolioStructureMap.java @@ -19,7 +19,7 @@ */ package org.olat.portfolio.model.structel; -import org.olat.basesecurity.Group; +import java.util.Set; /** * Description:<br> @@ -28,10 +28,10 @@ import org.olat.basesecurity.Group; * Initial Date: 08.06.2010 <br> * @author rhaag */ -public interface PortfolioStructureMap extends PortfolioStructure { +public interface PortfolioStructureMap extends PortfolioStructure, PortfolioStructureMapRef { //marker interface - public Group getGroup(); + public Set<EPStructureElementToGroupRelation> getGroups(); public String getStatus(); } diff --git a/src/main/java/org/olat/portfolio/model/structel/PortfolioStructureMapRef.java b/src/main/java/org/olat/portfolio/model/structel/PortfolioStructureMapRef.java new file mode 100644 index 0000000000000000000000000000000000000000..a2f0ec30372d4ee831b13b7eb48a9e30d0b772d1 --- /dev/null +++ b/src/main/java/org/olat/portfolio/model/structel/PortfolioStructureMapRef.java @@ -0,0 +1,32 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.portfolio.model.structel; + +/** + * + * Initial date: 24.06.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface PortfolioStructureMapRef { + + public Long getKey(); + +} diff --git a/src/main/java/org/olat/portfolio/model/structel/StructureElement.hbm.xml b/src/main/java/org/olat/portfolio/model/structel/StructureElement.hbm.xml index 59f3d7f2a2ee856c365df71e721fc1d5d921a421..fdb67cbe7ded6cb83c45e6630f0a9253bde9170e 100644 --- a/src/main/java/org/olat/portfolio/model/structel/StructureElement.hbm.xml +++ b/src/main/java/org/olat/portfolio/model/structel/StructureElement.hbm.xml @@ -64,12 +64,11 @@ </subclass> <subclass name="org.olat.portfolio.model.structel.EPDefaultMap" discriminator-value="default-map"> - <many-to-one name="group" - column="fk_group_id" - class="org.olat.basesecurity.model.GroupImpl" - outer-join="true" - unique="true" - cascade="none"/> + + <set name="groups" cascade="all,delete-orphan"> + <key column="fk_struct_id"/> + <one-to-many class="org.olat.portfolio.model.structel.EPStructureElementToGroupRelation"/> + </set> </subclass> @@ -87,12 +86,10 @@ <property name="businessPath" column="target_businesspath" length="2048" type="string" /> </component> - <many-to-one name="group" - column="fk_group_id" - class="org.olat.basesecurity.model.GroupImpl" - outer-join="true" - unique="true" - cascade="none"/> + <set name="groups" cascade="all,delete-orphan"> + <key column="fk_struct_id"/> + <one-to-many class="org.olat.portfolio.model.structel.EPStructureElementToGroupRelation"/> + </set> <many-to-one name="structuredMapSource" column="fk_map_source_id" @@ -105,12 +102,11 @@ <subclass name="org.olat.portfolio.model.structel.EPStructuredMapTemplate" discriminator-value="template-map"> - <many-to-one name="group" - column="fk_group_id" - class="org.olat.basesecurity.model.GroupImpl" - outer-join="true" - unique="true" - cascade="none"/> + <set name="groups" cascade="all,delete-orphan"> + <key column="fk_struct_id"/> + <one-to-many class="org.olat.portfolio.model.structel.EPStructureElementToGroupRelation"/> + </set> + </subclass> </class> @@ -154,12 +150,10 @@ <property name="sourceMapKey" column="fk_map_source_id" type="long"/> <property name="title" column="title" type="string"/> - <many-to-one name="group" - column="fk_group_id" - class="org.olat.basesecurity.model.GroupImpl" - outer-join="true" - unique="true" - cascade="none"/> + <set name="groups"> + <key column="fk_struct_id"/> + <one-to-many class="org.olat.portfolio.model.structel.EPStructureElementToGroupRelation"/> + </set> <many-to-one name="olatResource" column="fk_olatresource" diff --git a/src/main/java/org/olat/portfolio/ui/EPMapRunController.java b/src/main/java/org/olat/portfolio/ui/EPMapRunController.java index 436bee5c19e28792ae7300162b5607d97ae4cced..941f3594adf90ffe2bf9d3c9e1edefacfc9d428d 100755 --- a/src/main/java/org/olat/portfolio/ui/EPMapRunController.java +++ b/src/main/java/org/olat/portfolio/ui/EPMapRunController.java @@ -236,6 +236,7 @@ public class EPMapRunController extends BasicController implements Activateable2 } createMapBox.deactivate(); popDownCreateMapBox(); + toogleHeader(false); } else if (source == searchTemplateCtrl) { if(event == ReferencableEntriesSearchController.EVENT_REPOSITORY_ENTRY_SELECTED) { RepositoryEntry repoEntry = searchTemplateCtrl.getSelectedEntry(); @@ -279,7 +280,7 @@ public class EPMapRunController extends BasicController implements Activateable2 String title = translate("create.map"); createMapCtrl = new EPCreateMapController(ureq, getWindowControl()); listenTo(createMapCtrl); - createMapBox = new CloseableModalController(getWindowControl(), title, createMapCtrl.getInitialComponent()); + createMapBox = new CloseableModalController(getWindowControl(), title, createMapCtrl.getInitialComponent(), true, title); createMapBox.setCustomWindowCSS("o_sel_add_map_window"); listenTo(createMapBox); createMapBox.activate(); @@ -292,7 +293,7 @@ public class EPMapRunController extends BasicController implements Activateable2 searchTemplateCtrl = new ReferencableEntriesSearchController(getWindowControl(), ureq, new String[]{EPTemplateMapResource.TYPE_NAME}, commandLabel, false, false, false, false, false); listenTo(searchTemplateCtrl); - createMapBox = new CloseableModalController(getWindowControl(), title, searchTemplateCtrl.getInitialComponent()); + createMapBox = new CloseableModalController(getWindowControl(), title, searchTemplateCtrl.getInitialComponent(), true, title); createMapBox.setCustomWindowCSS("o_sel_add_map_template_window"); listenTo(createMapBox); createMapBox.activate(); diff --git a/src/main/java/org/olat/portfolio/ui/structel/EPCreateMapController.java b/src/main/java/org/olat/portfolio/ui/structel/EPCreateMapController.java index eea6b0087299f70a3bc73df84414c71ce9df6679..c705184f440c4c43878f353f9002f435691589e4 100644 --- a/src/main/java/org/olat/portfolio/ui/structel/EPCreateMapController.java +++ b/src/main/java/org/olat/portfolio/ui/structel/EPCreateMapController.java @@ -71,7 +71,6 @@ public class EPCreateMapController extends FormBasicController { formLayout, getWindowControl()); descEl.setNotLongerThanCheck(2047, "map.description.too.long"); - uifactory.addSpacerElement("spacer", formLayout, true); uifactory.addFormSubmitButton("save.and.open.map", formLayout); } diff --git a/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java b/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java index 4e65c0b536f66ef498c941290ece9aa08882f34a..cc2c5c29ba540a988cd2ecd23552eaf01fabe324 100644 --- a/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java +++ b/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java @@ -27,14 +27,12 @@ import java.util.concurrent.atomic.AtomicInteger; import org.olat.admin.user.UserSearchController; import org.olat.basesecurity.BaseSecurity; -import org.olat.basesecurity.BaseSecurityManager; import org.olat.basesecurity.Constants; import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.Invitation; import org.olat.basesecurity.SecurityGroup; import org.olat.basesecurity.events.MultiIdentityChosenEvent; import org.olat.basesecurity.events.SingleIdentityChosenEvent; -import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -73,10 +71,12 @@ import org.olat.group.ui.main.SelectBusinessGroupController; import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.manager.EPMapPolicy; import org.olat.portfolio.manager.EPMapPolicy.Type; +import org.olat.portfolio.manager.InvitationDAO; import org.olat.portfolio.model.structel.EPStructuredMap; import org.olat.portfolio.model.structel.PortfolioStructure; import org.olat.portfolio.model.structel.PortfolioStructureMap; import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -90,12 +90,22 @@ import org.olat.user.UserManager; public class EPShareListController extends FormBasicController { private final List<EPSharePolicyWrapper> policyWrappers = new ArrayList<EPSharePolicyWrapper>(); - private final PortfolioStructureMap map; - private final EPFrontendManager ePFMgr; - private final BaseSecurity securityManager; - private final BusinessGroupService businessGroupService; - private final UserManager userManager; - private final MailManager mailManager; + + private PortfolioStructureMap map; + + @Autowired + private EPFrontendManager ePFMgr; + @Autowired + private InvitationDAO invitationDao; + @Autowired + private BaseSecurity securityManager; + @Autowired + private BusinessGroupService businessGroupService; + @Autowired + private UserManager userManager; + @Autowired + private MailManager mailManager; + private final String[] targetKeys = EPMapPolicy.Type.names(); private final String[] targetValues = new String[targetKeys.length]; private final AtomicInteger cmpSuffixGenerator = new AtomicInteger(1); @@ -106,15 +116,12 @@ public class EPShareListController extends FormBasicController { private FormLink addPolicyButton; + + public EPShareListController(UserRequest ureq, WindowControl wControl, PortfolioStructureMap map) { super(ureq, wControl, "shareList"); this.map = map; - ePFMgr = CoreSpringFactory.getImpl(EPFrontendManager.class); - securityManager = BaseSecurityManager.getInstance(); - userManager = UserManager.getInstance(); - mailManager = CoreSpringFactory.getImpl(MailManager.class); - businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class); for(int i=targetKeys.length; i-->0; ) { targetValues[i] = translate("map.share.to." + targetKeys[i]); } @@ -509,7 +516,7 @@ public class EPShareListController extends FormBasicController { case invitation: Invitation invitation = policyWrapper.getInvitation(); if(invitation == null) { - invitation = securityManager.createAndPersistInvitation(); + invitation = invitationDao.createAndPersistInvitation(); policyWrapper.setInvitation(invitation); } diff --git a/src/main/java/org/olat/portfolio/ui/structel/EPSharePolicyWrapper.java b/src/main/java/org/olat/portfolio/ui/structel/EPSharePolicyWrapper.java index ea1a85977e92705cf2422c413d1737c34c30b905..764ddff23ecf2ce05567343d3759af06ab7d27f0 100644 --- a/src/main/java/org/olat/portfolio/ui/structel/EPSharePolicyWrapper.java +++ b/src/main/java/org/olat/portfolio/ui/structel/EPSharePolicyWrapper.java @@ -23,7 +23,6 @@ import java.util.Date; import java.util.List; import org.olat.basesecurity.Invitation; -import org.olat.basesecurity.Policy; import org.olat.core.gui.components.form.flexible.elements.DateChooser; import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; import org.olat.core.gui.components.form.flexible.elements.TextElement; @@ -32,6 +31,7 @@ import org.olat.core.id.Identity; import org.olat.core.util.StringHelper; import org.olat.group.BusinessGroup; import org.olat.portfolio.manager.EPMapPolicy; +import org.olat.portfolio.model.structel.EPStructureElementToGroupRelation; /** * @@ -88,16 +88,12 @@ public class EPSharePolicyWrapper { mapPolicy.setInvitation(invitation); } - public List<Policy> getPolicies() { - return mapPolicy.getPolicies(); + public List<EPStructureElementToGroupRelation> getRelations() { + return mapPolicy.getRelations(); } - public void setPolicies(List<Policy> policies) { - mapPolicy.setPolicies(policies); - } - - public void addPolicy(Policy policy) { - mapPolicy.addPolicy(policy); + public void addRelation(EPStructureElementToGroupRelation relation) { + mapPolicy.addRelation(relation); } public Date getTo() { @@ -123,7 +119,7 @@ public class EPSharePolicyWrapper { public void setType(EPMapPolicy.Type type) { if(!type.equals(mapPolicy.getType())) { mapPolicy.setType(type); - mapPolicy.getPolicies().clear(); + mapPolicy.getRelations().clear(); } } diff --git a/src/main/java/org/olat/repository/handlers/PortfolioHandler.java b/src/main/java/org/olat/repository/handlers/PortfolioHandler.java index 3a2e4cea3474661b7973a723798a001dabf51034..aef07492e8e257d300c38d26ab018287462faabe 100644 --- a/src/main/java/org/olat/repository/handlers/PortfolioHandler.java +++ b/src/main/java/org/olat/repository/handlers/PortfolioHandler.java @@ -192,7 +192,7 @@ public class PortfolioHandler implements RepositoryHandler { PortfolioStructure map = ePFMgr.loadPortfolioStructure(res); if(map != null) { //owner group has its constraints shared beetwen the repository entry and the template - ((EPAbstractMap)map).setGroup(null); + ((EPAbstractMap)map).setGroups(null); } if(map instanceof EPStructuredMapTemplate) { EPStructuredMapTemplate exercise = (EPStructuredMapTemplate)map; diff --git a/src/main/java/org/olat/search/service/document/PortfolioMapDocument.java b/src/main/java/org/olat/search/service/document/PortfolioMapDocument.java index 14f29cd3c62482dee559ee20cab42ec9ab60b518..dc07193ca85ec18e9c5565be8bccee6c118879e4 100644 --- a/src/main/java/org/olat/search/service/document/PortfolioMapDocument.java +++ b/src/main/java/org/olat/search/service/document/PortfolioMapDocument.java @@ -23,8 +23,6 @@ package org.olat.search.service.document; import java.util.List; import org.apache.lucene.document.Document; -import org.olat.basesecurity.GroupRoles; -import org.olat.basesecurity.manager.GroupDAO; import org.olat.core.CoreSpringFactory; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; @@ -39,6 +37,7 @@ import org.olat.core.util.resource.OresHelper; import org.olat.portfolio.EPArtefactHandler; import org.olat.portfolio.PortfolioModule; import org.olat.portfolio.manager.EPFrontendManager; +import org.olat.portfolio.manager.EPPolicyManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; import org.olat.portfolio.model.structel.EPAbstractMap; import org.olat.portfolio.model.structel.PortfolioStructure; @@ -59,14 +58,14 @@ public class PortfolioMapDocument extends OlatDocument { private static final long serialVersionUID = -7960651550499734346L; private static final OLog log = Tracing.createLoggerFor(PortfolioMapDocument.class); - private static GroupDAO groupDao; private static EPFrontendManager ePFMgr; + private static EPPolicyManager policyManager; private static PortfolioModule portfolioModule; public PortfolioMapDocument() { super(); - groupDao = CoreSpringFactory.getImpl(GroupDAO.class); ePFMgr = CoreSpringFactory.getImpl(EPFrontendManager.class); + policyManager = CoreSpringFactory.getImpl(EPPolicyManager.class); portfolioModule = CoreSpringFactory.getImpl(PortfolioModule.class); } @@ -74,8 +73,8 @@ public class PortfolioMapDocument extends OlatDocument { PortfolioMapDocument document = new PortfolioMapDocument(); if(map instanceof EPAbstractMap) { EPAbstractMap abstractMap = (EPAbstractMap)map; - if(abstractMap.getGroup() != null) { - List<Identity> identities = groupDao.getMembers(abstractMap.getGroup(), GroupRoles.owner.name()); + if(abstractMap.getGroups() != null) { + List<Identity> identities = policyManager.getOwners(abstractMap); StringBuilder authors = new StringBuilder(); for(Identity identity:identities) { if(authors.length() > 0) { diff --git a/src/main/java/org/olat/search/service/indexer/PortfolioMapIndexer.java b/src/main/java/org/olat/search/service/indexer/PortfolioMapIndexer.java index bba6056d9a7e7e0bb0b71b3e317addad319569e5..fde584c1ea674a97b44e45380e21dade8a43f409 100644 --- a/src/main/java/org/olat/search/service/indexer/PortfolioMapIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/PortfolioMapIndexer.java @@ -55,6 +55,6 @@ public class PortfolioMapIndexer extends AbstractPortfolioMapIndexer { @Override protected boolean accept(PortfolioStructureMap map) { - return map instanceof EPDefaultMap && ((EPDefaultMap)map).getGroup() != null; + return map instanceof EPDefaultMap && ((EPDefaultMap)map).getGroups() != null; } } \ No newline at end of file diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_10_0_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_10_0_0.java index 5e2df8a51b056a83b1e7cb2022674073b5331585..22630162e45c5d3942ff39856a121d417fb75e72 100644 --- a/src/main/java/org/olat/upgrade/OLATUpgrade_10_0_0.java +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_10_0_0.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Set; import org.olat.basesecurity.BaseSecurity; +import org.olat.basesecurity.Constants; import org.olat.basesecurity.Group; import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.Policy; @@ -33,15 +34,19 @@ import org.olat.basesecurity.SecurityGroup; import org.olat.basesecurity.manager.GroupDAO; import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; +import org.olat.group.BusinessGroupService; import org.olat.group.manager.BusinessGroupRelationDAO; import org.olat.group.right.BGRightManager; import org.olat.group.right.BGRightsRole; +import org.olat.portfolio.manager.EPMapPolicy; import org.olat.repository.RepositoryManager; import org.olat.repository.manager.RepositoryEntryRelationDAO; import org.olat.resource.OLATResource; import org.olat.upgrade.model.BGResourceRelation; import org.olat.upgrade.model.BusinessGroupUpgrade; import org.olat.upgrade.model.EPMapUpgrade; +import org.olat.upgrade.model.EPMapUpgradeToGroupRelation; +import org.olat.upgrade.model.InvitationUpgrade; import org.olat.upgrade.model.RepositoryEntryUpgrade; import org.olat.upgrade.model.RepositoryEntryUpgradeToGroupRelation; import org.springframework.beans.factory.annotation.Autowired; @@ -58,7 +63,8 @@ public class OLATUpgrade_10_0_0 extends OLATUpgrade { private static final String TASK_BUSINESS_GROUPS = "Upgrade business groups"; private static final String TASK_REPOENTRIES = "Upgrade repository entries"; private static final String TASK_REPOENTRY_TO_BUSINESSGROUP = "Upgrade relation business groups to repository entries"; - private static final String TASK_UPGRADE_MAP = "Upgrade maps"; + private static final String TASK_INVITATION = "Upgrade invitations"; + private static final String TASK_UPGRADE_MAP = "Upgrade e-portfolio maps"; private static final String VERSION = "OLAT_10.0.0"; @Autowired @@ -75,6 +81,8 @@ public class OLATUpgrade_10_0_0 extends OLATUpgrade { private BusinessGroupRelationDAO businessGroupRelationDao; @Autowired private RepositoryEntryRelationDAO repositoryEntryToGroupDAO; + @Autowired + private BusinessGroupService businessGroupService; public OLATUpgrade_10_0_0() { super(); @@ -104,6 +112,7 @@ public class OLATUpgrade_10_0_0 extends OLATUpgrade { allOk &= upgradeBusinessGroups(upgradeManager, uhd); allOk &= upgradeRepositoryEntries(upgradeManager, uhd); allOk &= upgradeRelationsRepoToBusinessGroups(upgradeManager, uhd); + allOk &= upgradeInvitation(upgradeManager, uhd); allOk &= upgradeEPMap(upgradeManager, uhd); uhd.setInstallationComplete(allOk); @@ -311,6 +320,44 @@ public class OLATUpgrade_10_0_0 extends OLATUpgrade { .getResultList(); } + private boolean upgradeInvitation(UpgradeManager upgradeManager, UpgradeHistoryData uhd) { + if (!uhd.getBooleanDataValue(TASK_INVITATION)) { + int counter = 0; + List<InvitationUpgrade> invitations; + do { + invitations = findInvitations(counter, BATCH_SIZE); + for(InvitationUpgrade invitation:invitations) { + if(invitation.getBaseGroup() == null) { + processInvitation(invitation); + } + } + counter += invitations.size(); + log.audit("Invitations processed: " + invitations.size() + ", total processed (" + counter + ")"); + dbInstance.commitAndCloseSession(); + } while(invitations.size() == BATCH_SIZE); + uhd.setBooleanDataValue(TASK_INVITATION, true); + upgradeManager.setUpgradesHistory(uhd, VERSION); + } + return true; + } + + private List<InvitationUpgrade> findInvitations(int firstResult, int maxResult) { + String sb = "select invitation from invitationupgrade as invitation order by invitation.key"; + return dbInstance.getCurrentEntityManager() + .createQuery(sb, InvitationUpgrade.class) + .setFirstResult(firstResult) + .setMaxResults(maxResult) + .getResultList(); + } + + private void processInvitation(InvitationUpgrade invitation) { + if(invitation.getBaseGroup() == null) { + Group invitationGroup = groupDao.createGroup(); + invitation.setBaseGroup(invitationGroup); + dbInstance.getCurrentEntityManager().merge(invitation); + } + } + private boolean upgradeEPMap(UpgradeManager upgradeManager, UpgradeHistoryData uhd) { if (!uhd.getBooleanDataValue(TASK_UPGRADE_MAP)) { int counter = 0; @@ -331,26 +378,113 @@ public class OLATUpgrade_10_0_0 extends OLATUpgrade { } private void processMap(EPMapUpgrade map) { - if(map.getGroup() != null) return; + if(map.getGroups() != null && map.getGroups().size() > 0) { + return; + } SecurityGroup ownerGroup = map.getOwnerGroup(); if(ownerGroup != null) { + //create default group RepositoryEntryUpgrade re = findMapRepoEntry(ownerGroup); + Set<EPMapUpgradeToGroupRelation> relations = map.getGroups(); if(re != null) { Group reGroup = repositoryEntryToGroupDAO.getDefaultGroup(re); if(reGroup != null) { - map.setGroup(reGroup); + relations.add(createDefaultGroup(map, reGroup)); } } - if(map.getGroup() == null) { + if(relations.isEmpty()) { Group group = groupDao.createGroup(); - map.setGroup(group); + relations.add(createDefaultGroup(map, group)); processSecurityGroup(group, GroupRoles.owner.name(), ownerGroup); } + + //create policy -> relation + + List<Policy> policies = securityManager.getPoliciesOfResource(map.getOlatResource(), null); + for(Policy policy:policies) { + if(policy.getPermission().contains(Constants.PERMISSION_READ)) { + EPMapUpgradeToGroupRelation politeRelation = processMapPolicy(policy, map); + if(politeRelation != null) { + relations.add(politeRelation); + } + } + } dbInstance.getCurrentEntityManager().merge(map); } } + private EPMapUpgradeToGroupRelation processMapPolicy(Policy policy, EPMapUpgrade element) { + String permission = policy.getPermission(); + SecurityGroup secGroup = policy.getSecurityGroup(); + Group group; + String role; + if(permission.startsWith(EPMapPolicy.Type.user.name())) { + group = groupDao.createGroup(); + processSecurityGroup(group, GroupRoles.participant.name(), secGroup); + role = EPMapPolicy.Type.user.name(); + } else if (permission.startsWith(EPMapPolicy.Type.group.name())) { + group = findGroupOfBusinessGroup(secGroup); + role = EPMapPolicy.Type.group.name(); + } else if (permission.startsWith(EPMapPolicy.Type.invitation.name())) { + InvitationUpgrade invitation = findInvitation(policy.getSecurityGroup()); + group = invitation.getBaseGroup(); + role = EPMapPolicy.Type.invitation.name(); + } else if (permission.startsWith(EPMapPolicy.Type.allusers.name())) { + group = groupDao.createGroup(EPMapPolicy.Type.allusers.name()); + role = EPMapPolicy.Type.allusers.name(); + } else { + return null; + } + + if(group == null) { + log.error("Group not resolve for policy of map: " + element.getKey() + " and policy: " + policy.getKey()); + return null; + } + + EPMapUpgradeToGroupRelation relation = new EPMapUpgradeToGroupRelation(); + relation.setDefaultGroup(false); + relation.setCreationDate(new Date()); + relation.setEntry(element); + relation.setValidTo(policy.getTo()); + relation.setValidFrom(policy.getFrom()); + relation.setGroup(group); + relation.setRole(role); + return relation; + } + + private InvitationUpgrade findInvitation(SecurityGroup secGroup) { + String sb = "select invitation from invitationupgrade as invitation where invitation.securityGroup=:secGroup"; + List<InvitationUpgrade> invitations = dbInstance.getCurrentEntityManager() + .createQuery(sb, InvitationUpgrade.class) + .setParameter("secGroup", secGroup) + .getResultList(); + return invitations.isEmpty() ? null : invitations.get(0); + } + + private EPMapUpgradeToGroupRelation createDefaultGroup(EPMapUpgrade element, Group group) { + EPMapUpgradeToGroupRelation relation = new EPMapUpgradeToGroupRelation(); + relation.setDefaultGroup(true); + relation.setCreationDate(new Date()); + relation.setGroup(group); + relation.setEntry(element); + return relation; + } + + private Group findGroupOfBusinessGroup(SecurityGroup secGroup) { + StringBuilder sb = new StringBuilder(); + sb.append("select bgi.baseGroup from ").append(BusinessGroupUpgrade.class.getName()).append(" as bgi ") + .append(" where (bgi.partipiciantGroup=:secGroup or bgi.ownerGroup=:secGroup or bgi.waitingGroup=:secGroup)"); + + List<Group> res = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Group.class) + .setParameter("secGroup", secGroup) + .getResultList(); + + if(res.isEmpty()) return null; + return res.get(0); + } + private RepositoryEntryUpgrade findMapRepoEntry(SecurityGroup ownerGroup) { StringBuilder sb = new StringBuilder(); sb.append("select v from ").append(RepositoryEntryUpgrade.class.getName()).append(" as v") @@ -368,9 +502,7 @@ public class OLATUpgrade_10_0_0 extends OLATUpgrade { private List<EPMapUpgrade> findMaps(int firstResult, int maxResults) { StringBuilder sb = new StringBuilder(); sb.append("select map from ").append(EPMapUpgrade.class.getName()).append(" map") - .append(" left join fetch map.group as baseGroup") - .append(" left join fetch map.ownerGroup as ownerGroup") - .append(" where map.group is null and map.ownerGroup is not null") + .append(" where map.ownerGroup is not null") .append(" order by map.key"); return dbInstance.getCurrentEntityManager().createQuery(sb.toString(), EPMapUpgrade.class) .setFirstResult(firstResult) diff --git a/src/main/java/org/olat/upgrade/model/EPMapUpgrade.hbm.xml b/src/main/java/org/olat/upgrade/model/EPMapUpgrade.hbm.xml index 748d7caa4ddfc22e6ddbe55be863c5e4b82e7d79..f1503d828d8460b9ee521c4c163a59fb756a0916 100644 --- a/src/main/java/org/olat/upgrade/model/EPMapUpgrade.hbm.xml +++ b/src/main/java/org/olat/upgrade/model/EPMapUpgrade.hbm.xml @@ -13,13 +13,19 @@ outer-join="true" unique="true" not-found="ignore" cascade="none"/> + + <many-to-one name="olatResource" + column="fk_olatresource" + class="org.olat.resource.OLATResourceImpl" + outer-join="true" + unique="true" + cascade="none"/> + + <set name="groups" cascade="all,delete-orphan"> + <key column="fk_struct_id"/> + <one-to-many class="org.olat.upgrade.model.EPMapUpgradeToGroupRelation"/> + </set> - <many-to-one name="group" - column="fk_group_id" - class="org.olat.basesecurity.model.GroupImpl" - outer-join="true" - unique="true" not-found="ignore" - cascade="none"/> </class> </hibernate-mapping> \ No newline at end of file diff --git a/src/main/java/org/olat/upgrade/model/EPMapUpgrade.java b/src/main/java/org/olat/upgrade/model/EPMapUpgrade.java index 903b9384728d36b6567a8a93cd7222772805c9c3..46959123911f32bb992baa68e571a73f784e37f5 100644 --- a/src/main/java/org/olat/upgrade/model/EPMapUpgrade.java +++ b/src/main/java/org/olat/upgrade/model/EPMapUpgrade.java @@ -19,9 +19,11 @@ */ package org.olat.upgrade.model; -import org.olat.basesecurity.Group; +import java.util.Set; + import org.olat.basesecurity.SecurityGroup; import org.olat.core.commons.persistence.PersistentObject; +import org.olat.resource.OLATResource; /** * Needed to upgrade the maps @@ -33,16 +35,25 @@ import org.olat.core.commons.persistence.PersistentObject; public class EPMapUpgrade extends PersistentObject { private static final long serialVersionUID = 9041327840189041360L; - - private Group group; + private SecurityGroup ownerGroup; + private OLATResource olatResource; + private Set<EPMapUpgradeToGroupRelation> groups; - public Group getGroup() { - return group; + public OLATResource getOlatResource() { + return olatResource; + } + + public void setOlatResource(OLATResource olatResource) { + this.olatResource = olatResource; + } + + public Set<EPMapUpgradeToGroupRelation> getGroups() { + return groups; } - public void setGroup(Group group) { - this.group = group; + public void setGroups(Set<EPMapUpgradeToGroupRelation> groups) { + this.groups = groups; } public SecurityGroup getOwnerGroup() { diff --git a/src/main/java/org/olat/upgrade/model/EPMapUpgradeToGroupRelation.java b/src/main/java/org/olat/upgrade/model/EPMapUpgradeToGroupRelation.java new file mode 100644 index 0000000000000000000000000000000000000000..20ae7ca3c56b41ddf58ce6ad3a4084486da73bf4 --- /dev/null +++ b/src/main/java/org/olat/upgrade/model/EPMapUpgradeToGroupRelation.java @@ -0,0 +1,180 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.upgrade.model; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.hibernate.annotations.GenericGenerator; +import org.olat.basesecurity.Group; +import org.olat.basesecurity.model.GroupImpl; +import org.olat.core.id.Persistable; +import org.olat.portfolio.model.structel.EPStructureElement; + +/** + * + * Initial date: 20.02.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Entity(name="structureuptogroup") +@Table(name="o_ep_struct_to_group") +public class EPMapUpgradeToGroupRelation implements Persistable { + + private static final long serialVersionUID = 2215547264646107606L; + + @Id + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "hilo") + @Column(name="id", nullable=false, unique=true, insertable=true, updatable=false) + private Long key; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="creationdate", nullable=false, insertable=true, updatable=false) + private Date creationDate; + + @Column(name="r_defgroup", nullable=false, insertable=true, updatable=false) + private boolean defaultGroup = false; + + @Column(name="r_role", nullable=true, insertable=true, updatable=true) + private String role; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="r_valid_from", nullable=true, insertable=true, updatable=true) + private Date validFrom; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="r_valid_to", nullable=true, insertable=true, updatable=true) + private Date validTo; + + @ManyToOne(targetEntity=GroupImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_group_id", nullable=true, insertable=true, updatable=true) + private Group group; + + @ManyToOne(targetEntity=EPStructureElement.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_struct_id", nullable=false, insertable=true, updatable=true) + private EPMapUpgrade entry; + + public Long getKey() { + return key; + } + + public void setKey(Long key) { + this.key = key; + } + + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public boolean isDefaultGroup() { + return defaultGroup; + } + + public void setDefaultGroup(boolean defaultGroup) { + this.defaultGroup = defaultGroup; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public Date getValidFrom() { + return validFrom; + } + + public void setValidFrom(Date validFrom) { + this.validFrom = validFrom; + } + + public Date getValidTo() { + return validTo; + } + + public void setValidTo(Date validTo) { + this.validTo = validTo; + } + + public Group getGroup() { + return group; + } + + public void setGroup(Group group) { + this.group = group; + } + + public EPMapUpgrade getEntry() { + return entry; + } + + public void setEntry(EPMapUpgrade entry) { + this.entry = entry; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("mapToGroup[resource=") + .append(entry.getKey()).append(":") + .append("group=").append(group.getKey()) + .append("]"); + return sb.toString(); + } + + @Override + public int hashCode() { + return getKey() == null ? 29061 : getKey().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if(obj instanceof EPMapUpgradeToGroupRelation) { + EPMapUpgradeToGroupRelation rel = (EPMapUpgradeToGroupRelation)obj; + return getKey() != null && getKey().equals(rel.getKey()); + } + return false; + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/upgrade/model/InvitationUpgrade.java b/src/main/java/org/olat/upgrade/model/InvitationUpgrade.java new file mode 100644 index 0000000000000000000000000000000000000000..fd493a09dbda979a6c57026f832db383c35cd514 --- /dev/null +++ b/src/main/java/org/olat/upgrade/model/InvitationUpgrade.java @@ -0,0 +1,109 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ + +package org.olat.upgrade.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import org.hibernate.annotations.GenericGenerator; +import org.olat.basesecurity.Group; +import org.olat.basesecurity.SecurityGroup; +import org.olat.basesecurity.SecurityGroupImpl; +import org.olat.basesecurity.model.GroupImpl; +import org.olat.core.id.Persistable; + +/** + * + * Description:<br> + * Implementation of Invitation + * + * <P> + * Initial Date: 10 nov. 2010 <br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +@Entity(name="invitationupgrade") +@Table(name="o_bs_invitation") +public class InvitationUpgrade implements Persistable { + + private static final long serialVersionUID = -9122616013810215550L; + + @Id + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "hilo") + @Column(name="id", nullable=false, unique=true, insertable=true, updatable=false) + private Long key; + + @ManyToOne(targetEntity=GroupImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_group_id", nullable=false, insertable=true, updatable=true) + private Group baseGroup; + + @ManyToOne(targetEntity=SecurityGroupImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_secgroup", nullable=true, insertable=true, updatable=true) + private SecurityGroup securityGroup; + + @Override + public Long getKey() { + return key; + } + + public Group getBaseGroup() { + return baseGroup; + } + + public void setBaseGroup(Group baseGroup) { + this.baseGroup = baseGroup; + } + + public SecurityGroup getSecurityGroup() { + return securityGroup; + } + + public void setSecurityGroup(SecurityGroup securityGroup) { + this.securityGroup = securityGroup; + } + + @Override + public int hashCode() { + return key == null ? -98260 : key.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } else if (obj instanceof InvitationUpgrade) { + InvitationUpgrade invitation = (InvitationUpgrade)obj; + return getKey() != null && getKey().equals(invitation.getKey()); + } + return false; + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } +} diff --git a/src/main/java/org/olat/user/UserInfoMainController.java b/src/main/java/org/olat/user/UserInfoMainController.java index ee23f4979ade861e785afddaee51f15c9d285985..a4da52472002acf3968f52f95ade437f1a6ab5b9 100644 --- a/src/main/java/org/olat/user/UserInfoMainController.java +++ b/src/main/java/org/olat/user/UserInfoMainController.java @@ -31,7 +31,6 @@ package org.olat.user; import java.util.ArrayList; import java.util.List; -import org.olat.basesecurity.BaseSecurityManager; import org.olat.commons.calendar.CalendarManager; import org.olat.commons.calendar.CalendarManagerFactory; import org.olat.commons.calendar.model.KalendarConfig; @@ -70,6 +69,8 @@ import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; import org.olat.modules.co.ContactFormController; import org.olat.portfolio.EPUIFactory; import org.olat.portfolio.PortfolioModule; +import org.olat.portfolio.manager.InvitationDAO; +import org.springframework.beans.factory.annotation.Autowired; /** * Initial Date: July 26, 2005 @@ -109,6 +110,9 @@ public class UserInfoMainController extends MainLayoutBasicController implements private GenericTreeNode folderNode; private GenericTreeNode contactNode; + + @Autowired + private InvitationDAO invitationDao; /** * @param ureq @@ -209,7 +213,7 @@ public class UserInfoMainController extends MainLayoutBasicController implements // following user info elements are only shown for undeleted and real // users (not invited // eportfolio users) - boolean isInvitee = BaseSecurityManager.getInstance().isIdentityInvited(chosenIdentity); + boolean isInvitee = invitationDao.isInvitee(chosenIdentity); boolean isDeleted = chosenIdentity.getStatus().equals(Identity.STATUS_DELETED); if ( !isDeleted && ! isInvitee) { diff --git a/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql b/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql index 5fa27179833ed44110c272a3f2de5f40fecd1d93..eaacd7e0595d371e030db2f3ab2654a73f180f12 100644 --- a/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql +++ b/src/main/resources/database/mysql/alter_9_4_0_to_10_0_0.sql @@ -5,9 +5,6 @@ alter table o_repositoryentry modify softkey varchar(36) not null unique; alter table o_repositoryentry modify launchcounter bigint null default 0; alter table o_repositoryentry modify downloadcounter bigint null default 0; -alter table o_ep_struct_el add column fk_group_id bigint; - - -- repository entry statistics table create table o_repositoryentry_stats ( id bigint not null, @@ -89,6 +86,29 @@ alter table o_re_to_group add constraint re_to_group_re_ctx foreign key (fk_entr -- alter table o_gp_business add constraint gp_to_group_business_ctx foreign key (fk_group_id) references o_bs_group (id); +-- portfolio +alter table o_bs_invitation modify fk_secgroup bigint null default null; +alter table o_bs_invitation modify version bigint null default null; + +alter table o_bs_invitation add column fk_group_id bigint; +alter table o_bs_invitation add constraint inv_to_group_group_ctx foreign key (fk_group_id) references o_bs_group (id); + +create table o_ep_struct_to_group ( + id bigint not null, + creationdate datetime not null, + r_defgroup boolean not null, + r_role varchar(64), + r_valid_from datetime, + r_valid_to datetime, + fk_group_id bigint, + fk_struct_id bigint, + primary key (id) +); +alter table o_ep_struct_to_group ENGINE = InnoDB; +alter table o_ep_struct_to_group add constraint struct_to_group_group_ctx foreign key (fk_group_id) references o_bs_group (id); +alter table o_ep_struct_to_group add constraint struct_to_group_re_ctx foreign key (fk_struct_id) references o_ep_struct_el (structure_id); + + -- managed groups create or replace view o_gp_business_v as ( select @@ -313,6 +333,9 @@ alter table o_repositoryentry drop foreign key repo_parti_sec_group_ctx; alter table o_repositorymetadata drop foreign key FKDB97A6493F14E3EE; +alter table o_bs_policy drop foreign key FK9A1C5109F9C3F1D; + + alter table o_bookmark drop foreign key FK68C4E30663219E27; alter table o_gp_business_to_resource drop foreign key idx_bgp_to_rsrc_rsrc; @@ -324,4 +347,6 @@ alter table o_gp_bgcontextresource_rel drop foreign key FK9903BEACDF6BCD14; alter table o_gp_bgarea drop foreign key FK9EFAF698DF6BCD14; -alter table o_ep_struct_el drop foreign key FKF26C8375236F29X; \ No newline at end of file +alter table o_ep_struct_el drop foreign key FKF26C8375236F29X; + +alter table o_bs_invitation drop foreign key FKF26C8375236F27X; diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index df380e4277a184b07b73a80f7eeed0cb5e858ac7..c9efaf968bbc48f1c94539ec7c6c2228c733df39 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -712,13 +712,12 @@ create table if not exists o_tag ( create table if not exists o_bs_invitation ( id bigint not null, - version mediumint unsigned not null, creationdate datetime, token varchar(64) not null, first_name varchar(64), last_name varchar(64), mail varchar(128), - fk_secgroup bigint, + fk_group_id bigint, primary key (id) ); @@ -799,6 +798,17 @@ create table if not exists o_ep_struct_artefact_link ( fk_artefact_id bigint not null, primary key (link_id) ); +create table o_ep_struct_to_group ( + id bigint not null, + creationdate datetime not null, + r_defgroup boolean not null, + r_role varchar(64), + r_valid_from datetime, + r_valid_to datetime, + fk_group_id bigint, + fk_struct_id bigint, + primary key (id) +); -- mail system @@ -1815,6 +1825,7 @@ alter table o_ep_collect_restriction ENGINE = InnoDB; alter table o_ep_struct_el ENGINE = InnoDB; alter table o_ep_struct_struct_link ENGINE = InnoDB; alter table o_ep_struct_artefact_link ENGINE = InnoDB; +alter table o_ep_struct_to_group ENGINE = InnoDB; alter table o_co_db_entry ENGINE = InnoDB; alter table o_mail ENGINE = InnoDB; alter table o_mail_to_recipient ENGINE = InnoDB; @@ -1924,14 +1935,13 @@ create index identstatus_idx on o_bs_identity (status); create index idx_ident_creationdate_idx on o_bs_identity (creationdate); create index idx_id_lastlogin_idx on o_bs_identity (lastlogin); -alter table o_bs_policy add constraint FK9A1C5109F9C3F1D foreign key (oresource_id) references o_olatresource (resource_id); alter table o_bs_policy add constraint FK9A1C5101E2E76DB foreign key (group_id) references o_bs_secgroup (id); create index idx_policy_grp_rsrc_idx on o_bs_policy (oresource_id, group_id); alter table o_bs_membership add constraint FK7B6288B45259603C foreign key (identity_id) references o_bs_identity (id); alter table o_bs_membership add constraint FK7B6288B4B85B522C foreign key (secgroup_id) references o_bs_secgroup (id); -alter table o_bs_invitation add constraint FKF26C8375236F27X foreign key (fk_secgroup) references o_bs_secgroup (id); +alter table o_bs_invitation add constraint inv_to_group_group_ctx foreign key (fk_group_id) references o_bs_group (id); -- user create index usr_notification_interval_idx on o_user (notification_interval); @@ -2091,6 +2101,9 @@ alter table o_ep_struct_artefact_link add constraint FKF26C8375236F24X foreign k alter table o_ep_struct_artefact_link add constraint FKF26C8375236F25X foreign key (fk_artefact_id) references o_ep_artefact (artefact_id); alter table o_ep_struct_artefact_link add constraint FKF26C8375236F26Y foreign key (fk_auth_id) references o_bs_identity (id); +alter table o_ep_struct_to_group add constraint struct_to_group_group_ctx foreign key (fk_group_id) references o_bs_group (id); +alter table o_ep_struct_to_group add constraint struct_to_group_re_ctx foreign key (fk_struct_id) references o_ep_struct_el (structure_id); + -- tag alter table o_tag add constraint FK6491FCA5A4FA5DC foreign key (fk_author_id) references o_bs_identity (id); diff --git a/src/main/resources/database/postgresql/drop_after_10_0_0.sql b/src/main/resources/database/postgresql/drop_after_10_0_0.sql index e92bb71f6fad1673c11caf82c0cff019f6a25fe8..7fcedd4df1ad17afceeb14d6dff9c19b26fbcce4 100644 --- a/src/main/resources/database/postgresql/drop_after_10_0_0.sql +++ b/src/main/resources/database/postgresql/drop_after_10_0_0.sql @@ -14,6 +14,11 @@ alter table o_gp_business drop column businessgrouptype; alter table o_area drop groupcontext_fk; +alter table o_bs_invitation drop column fk_secgroup; +alter table o_bs_invitation drop column version; + +alter table o_ep_struct_el drop column fk_ownergroup + -- drop tables drop table o_gp_bgcontext; drop table o_gp_business_to_resource; diff --git a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java index 054a84d83f14b575ba9390bbd2890369188c37bc..ec33ae018d922ef9c4b6ba8b47fb2fa953118ca1 100644 --- a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java +++ b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java @@ -574,49 +574,6 @@ public class BaseSecurityManagerTest extends OlatTestCase { Assert.assertTrue(policies.contains(policy_1)); Assert.assertTrue(policies.contains(policy_2)); } - - /** - * Test this method - * @see getPoliciesOfSecurityGroup(List<SecurityGroup> secGroups, resource1) - */ - @Test - public void testGetPoliciesOfSecurityGroups() { - //create 2 security groups and 2 resources - SecurityGroup secGroup_1 = securityManager.createAndPersistSecurityGroup(); - SecurityGroup secGroup_2 = securityManager.createAndPersistSecurityGroup(); - OLATResource resource_1 = JunitTestHelper.createRandomResource(); - OLATResource resource_2 = JunitTestHelper.createRandomResource(); - Policy policy_1 = securityManager.createAndPersistPolicy(secGroup_1, "test.right1_1", resource_1); - Policy policy_2 = securityManager.createAndPersistPolicy(secGroup_1, "test.right1_2", resource_2); - Policy policy_3 = securityManager.createAndPersistPolicy(secGroup_2, "test.right2_1", resource_1); - Policy policy_4 = securityManager.createAndPersistPolicy(secGroup_2, "test.right2_2", resource_2); - dbInstance.commitAndCloseSession(); - - //test group_1 and resource_1 - List<Policy> policies1_1 = securityManager.getPoliciesOfSecurityGroup(Collections.singletonList(secGroup_1), resource_1); - Assert.assertNotNull(policies1_1); - Assert.assertEquals(1, policies1_1.size()); - Assert.assertEquals(policy_1, policies1_1.get(0)); - - //test group_1 + resource_1 and 2 - List<Policy> policies1 = securityManager.getPoliciesOfSecurityGroup(Collections.singletonList(secGroup_1), resource_1, resource_2); - Assert.assertNotNull(policies1); - Assert.assertEquals(2, policies1.size()); - Assert.assertTrue(policies1.contains(policy_1)); - Assert.assertTrue(policies1.contains(policy_2)); - - //test group 2 - List<Policy> policies2 = securityManager.getPoliciesOfSecurityGroup(Collections.singletonList(secGroup_2)); - Assert.assertNotNull(policies2); - Assert.assertEquals(2, policies2.size()); - Assert.assertTrue(policies2.contains(policy_3)); - Assert.assertTrue(policies2.contains(policy_4)); - - //test dummy - List<Policy> policiesEmpty = securityManager.getPoliciesOfSecurityGroup(Collections.<SecurityGroup>emptyList()); - Assert.assertNotNull(policiesEmpty); - Assert.assertTrue(policiesEmpty.isEmpty()); - } /** * Test the method @@ -704,101 +661,6 @@ public class BaseSecurityManagerTest extends OlatTestCase { assertTrue("Does not found policy", foundPolicy); } - /** - * @see public void deletePolicy(SecurityGroup secGroup, String permission, OLATResource resource); - */ - @Test - public void testDeletePolicy() { - //create 3 rights - SecurityGroup secGroup1 = securityManager.createAndPersistSecurityGroup(); - SecurityGroup secGroup2 = securityManager.createAndPersistSecurityGroup(); - OLATResource resource1 = JunitTestHelper.createRandomResource(); - OLATResource resource2 = JunitTestHelper.createRandomResource(); - Policy policy_1_1 = securityManager.createAndPersistPolicy(secGroup1, "test.r1-1_1", resource1); - Policy policy_1_1b = securityManager.createAndPersistPolicy(secGroup1, "test.r2-1_1", resource1); - Policy policy_1_2 = securityManager.createAndPersistPolicy(secGroup1, "test.r3_1-2", resource2); - Policy policy_2_2 = securityManager.createAndPersistPolicy(secGroup2, "test.r3_2-2", resource2); - dbInstance.commitAndCloseSession(); - - //delete policy 1_1b - securityManager.deletePolicy(secGroup1, "test.r2-1_1", resource1); - - //test the method - List<Policy> policies_1_1 = securityManager.getPoliciesOfResource(resource1, secGroup1); - Assert.assertNotNull(policies_1_1); - Assert.assertEquals(1, policies_1_1.size()); - Assert.assertTrue(policies_1_1.contains(policy_1_1)); - Assert.assertFalse(policies_1_1.contains(policy_1_1b)); - - //too much deleted in resource 1? - List<Policy> policies_x_1 = securityManager.getPoliciesOfResource(resource1, null); - Assert.assertNotNull(policies_x_1); - Assert.assertEquals(1, policies_x_1.size()); - Assert.assertTrue(policies_x_1.contains(policy_1_1)); - Assert.assertFalse(policies_x_1.contains(policy_1_1b)); - - //too much deleted in resource 2? - List<Policy> policies_x_2 = securityManager.getPoliciesOfResource(resource2, null); - Assert.assertNotNull(policies_x_2); - Assert.assertEquals(2, policies_x_2.size()); - Assert.assertTrue(policies_x_2.contains(policy_1_2)); - Assert.assertTrue(policies_x_2.contains(policy_2_2)); - } - - /** - * @see public boolean deletePolicies(Collection<SecurityGroup> secGroups, Collection<OLATResource> resources) - */ - @Test - public void testDeletePolicies() { - //prepare enough rights - SecurityGroup secGroup1 = securityManager.createAndPersistSecurityGroup(); - SecurityGroup secGroup2 = securityManager.createAndPersistSecurityGroup(); - SecurityGroup secGroup3 = securityManager.createAndPersistSecurityGroup(); - OLATResource resource1 = JunitTestHelper.createRandomResource(); - OLATResource resource2 = JunitTestHelper.createRandomResource(); - OLATResource resource3 = JunitTestHelper.createRandomResource(); - Policy policy_1_1 = securityManager.createAndPersistPolicy(secGroup1, "test.r1-1_1", resource1); - Policy policy_1_b = securityManager.createAndPersistPolicy(secGroup1, "test.r2-1_1", resource1); - Policy policy_1_2 = securityManager.createAndPersistPolicy(secGroup1, "test.r3_1-2", resource2); - Policy policy_1_3 = securityManager.createAndPersistPolicy(secGroup1, "test.r4_1-3", resource3); - Policy policy_2_2 = securityManager.createAndPersistPolicy(secGroup2, "test.r5_2-2", resource2); - Policy policy_3_1 = securityManager.createAndPersistPolicy(secGroup3, "test.r6_3-1", resource1); - Policy policy_3_2 = securityManager.createAndPersistPolicy(secGroup3, "test.r7_3-2", resource2); - Policy policy_3_3 = securityManager.createAndPersistPolicy(secGroup3, "test.r8_3-3", resource3); - dbInstance.commitAndCloseSession(); - - //delete group 1 and 2, delete resource 1 and 3 - List<SecurityGroup> secGroups = new ArrayList<SecurityGroup>(2); - secGroups.add(secGroup1); - secGroups.add(secGroup2); - List<OLATResource> resources = new ArrayList<OLATResource>(2); - resources.add(resource1); - resources.add(resource3); - boolean deleted = securityManager.deletePolicies(secGroups, resources); - Assert.assertTrue(deleted); - - //check resource 1 -> only policy_3_1 survives - List<Policy> policies_1 = securityManager.getPoliciesOfResource(resource1, null); - Assert.assertNotNull(policies_1); - Assert.assertEquals(1, policies_1.size()); - Assert.assertTrue(policies_1.contains(policy_3_1)); - Assert.assertFalse(policies_1.contains(policy_1_1)); - Assert.assertFalse(policies_1.contains(policy_1_b)); - //check resource 2 -> all its policies survive - List<Policy> policies_2 = securityManager.getPoliciesOfResource(resource2, null); - Assert.assertNotNull(policies_2); - Assert.assertEquals(3, policies_2.size()); - Assert.assertTrue(policies_2.contains(policy_1_2)); - Assert.assertTrue(policies_2.contains(policy_2_2)); - Assert.assertTrue(policies_2.contains(policy_3_2)); - //check resource 3 - List<Policy> policies_3 = securityManager.getPoliciesOfResource(resource3, null); - Assert.assertNotNull(policies_3); - Assert.assertEquals(1, policies_3.size()); - Assert.assertTrue(policies_3.contains(policy_3_3)); - Assert.assertFalse(policies_3.contains(policy_1_3)); - } - @Test public void isIdentityPermittedOnResourceable_checkType() { //create an identity, a security group, a resource and give the identity some @@ -863,28 +725,6 @@ public class BaseSecurityManagerTest extends OlatTestCase { //check that null doesn't return an exception but false boolean hasIpor = securityManager.isIdentityPermittedOnResourceable(null, "test.ipornc-null", resource, false); Assert.assertFalse(hasIpor); - - } - - @Test - public void getIdentityPermissionsOnResourceable() { - //create an identity, a security group, a resource and give the identity some - //permissions on the resource - SecurityGroup secGroup = securityManager.createAndPersistSecurityGroup(); - OLATResource resource = JunitTestHelper.createRandomResource(); - Identity id = JunitTestHelper.createAndPersistIdentityAsUser("test-gpor-1-" + UUID.randomUUID().toString()); - securityManager.addIdentityToSecurityGroup(id, secGroup); - securityManager.createAndPersistPolicy(secGroup, "test.gpor-1_1", resource); - securityManager.createAndPersistPolicy(secGroup, "test.gpor-1_2", resource); - dbInstance.commitAndCloseSession(); - - //check - List<String> permissions = securityManager.getIdentityPermissionOnresourceable(id, resource); - Assert.assertNotNull(permissions); - Assert.assertTrue(permissions.size() >= 2); - Assert.assertTrue(permissions.contains("test.gpor-1_1")); - Assert.assertTrue(permissions.contains("test.gpor-1_2")); - Assert.assertFalse(permissions.contains("test.gpor-1_3")); } /** diff --git a/src/test/java/org/olat/portfolio/EPFrontendManagerTest.java b/src/test/java/org/olat/portfolio/EPFrontendManagerTest.java index 799d0f7a918213d1319247c3be6edeea21c0bf07..7ca021872078365a1acdcf9ddcb1d8171e1eff72 100644 --- a/src/test/java/org/olat/portfolio/EPFrontendManagerTest.java +++ b/src/test/java/org/olat/portfolio/EPFrontendManagerTest.java @@ -39,6 +39,7 @@ import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.manager.EPMapPolicy; import org.olat.portfolio.manager.EPMapPolicy.Type; import org.olat.portfolio.manager.EPStructureManager; +import org.olat.portfolio.manager.InvitationDAO; import org.olat.portfolio.model.artefacts.AbstractArtefact; import org.olat.portfolio.model.structel.EPDefaultMap; import org.olat.portfolio.model.structel.EPPage; @@ -89,6 +90,8 @@ public class EPFrontendManagerTest extends OlatTestCase { @Autowired private BaseSecurity securityManager; + @Autowired + private InvitationDAO invitationDao; @Autowired private RepositoryManager repositoryManager; @@ -593,7 +596,7 @@ public class EPFrontendManagerTest extends OlatTestCase { policies.add(userPolicy); //invitation - Invitation invitation = securityManager.createAndPersistInvitation(); + Invitation invitation = invitationDao.createAndPersistInvitation(); invitation.setFirstName("John"); invitation.setLastName("Doe"); invitation.setMail("john@doe.ch"); @@ -628,7 +631,7 @@ public class EPFrontendManagerTest extends OlatTestCase { //save a list of policies List<EPMapPolicy> policies = new ArrayList<EPMapPolicy>(); //invitation - Invitation invitation = securityManager.createAndPersistInvitation(); + Invitation invitation = invitationDao.createAndPersistInvitation(); invitation.setFirstName("John"); invitation.setLastName("Doe"); invitation.setMail("john2@doe.ch"); @@ -636,7 +639,7 @@ public class EPFrontendManagerTest extends OlatTestCase { invitationPolicy.setType(Type.invitation); invitationPolicy.setInvitation(invitation); policies.add(invitationPolicy); - epFrontendManager.updateMapPolicies(map, policies); + map = epFrontendManager.updateMapPolicies(map, policies); dbInstance.commitAndCloseSession(); //remove the policy diff --git a/src/test/java/org/olat/portfolio/EPPerformanceTest.java b/src/test/java/org/olat/portfolio/EPPerformanceTest.java index 8b4ec39e2f37602682afcaa8d9de2c070c7242f3..87d7b23e92bc16d8b6fd39bf396be8cecb81c418 100644 --- a/src/test/java/org/olat/portfolio/EPPerformanceTest.java +++ b/src/test/java/org/olat/portfolio/EPPerformanceTest.java @@ -177,21 +177,9 @@ public class EPPerformanceTest extends OlatTestCase { return epFrontendManager.updateArtefact(artefact); } - - - @Test - public void testMaps300(){ - internalTestCreateManyMaps(300); - } - - @Test - public void testMaps1000(){ - internalTestCreateManyMaps(1000); - } - @Test - public void testMaps3000(){ - internalTestCreateManyMaps(3000); + public void testMaps500(){ + internalTestCreateManyMaps(500); } private void deleteMaps(){ diff --git a/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java b/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java index c24e402b80560452f2ccd86e6b4f043e49379455..afaae7609712a93662df11ab68ba656472ef5762 100644 --- a/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java +++ b/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java @@ -196,11 +196,11 @@ public class FunctionalArtefactTest { String pageName, String pageDescription, String structureName, String structureDescription, Class<?> artefactClass, String artefactName, String artefactDescription, String[] artefactTags, String[] artefactContent){ - Binder binder = findBinderByName(this.map, binderName); + Binder binder = findBinderByName(map, binderName); if(binder == null){ binder = new Binder(binderName, binderDescription); - this.map.add(binder); + map.add(binder); } Binder.Page page = findPageByName(binder.page, pageName); diff --git a/src/test/java/org/olat/portfolio/manager/EPPolicyManagerTest.java b/src/test/java/org/olat/portfolio/manager/EPPolicyManagerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..cdd7d9f9d16c239977ae29d3b4e685b204b911f4 --- /dev/null +++ b/src/test/java/org/olat/portfolio/manager/EPPolicyManagerTest.java @@ -0,0 +1,120 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.portfolio.manager; + +import static org.junit.Assert.assertNotNull; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import org.junit.Assert; +import org.junit.Test; +import org.olat.basesecurity.Invitation; +import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; +import org.olat.portfolio.model.structel.PortfolioStructure; +import org.olat.portfolio.model.structel.PortfolioStructureMap; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 24.06.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class EPPolicyManagerTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private InvitationDAO invitationDao; + @Autowired + private EPPolicyManager policyManager; + @Autowired + private EPFrontendManager epFrontendManager; + + @Test + public void getOwners() { + //create a map + Identity user = JunitTestHelper.createAndPersistIdentityAsRndUser("Policy-User-1-"); + PortfolioStructureMap originalMap = epFrontendManager.createAndPersistPortfolioDefaultMap(user, "Title", "Description"); + PortfolioStructure page1 = epFrontendManager.createAndPersistPortfolioPage(originalMap, "Page title", "Page description"); + assertNotNull(page1); + dbInstance.commitAndCloseSession(); + + List<Identity> owners = policyManager.getOwners(originalMap); + Assert.assertNotNull(owners); + Assert.assertEquals(1, owners.size()); + Assert.assertEquals(user, owners.get(0)); + } + + @Test + public void isMapShared_HQL() { + Identity user = JunitTestHelper.createAndPersistIdentityAsRndUser("Policy-User-2-"); + PortfolioStructureMap map = epFrontendManager.createAndPersistPortfolioDefaultMap(user, "Title", "Description"); + dbInstance.commitAndCloseSession(); + + boolean shared = policyManager.isMapShared(map.getOlatResource()); + Assert.assertFalse(shared); + } + + @Test + public void createPolicy_invitation() { + Identity user = JunitTestHelper.createAndPersistIdentityAsRndUser("Policy-User-2-"); + PortfolioStructureMap map = epFrontendManager.createAndPersistPortfolioDefaultMap(user, "Title", "Description"); + Invitation invitation = invitationDao.createAndPersistInvitation(); + dbInstance.commit(); + + invitation.setFirstName("John"); + invitation.setLastName("Smith Portfolio"); + EPMapPolicy policy = new EPMapPolicy(); + policy.setType(EPMapPolicy.Type.invitation); + policy.setInvitation(invitation); + + policyManager.updateMapPolicies(map, Collections.singletonList(policy)); + dbInstance.commitAndCloseSession(); + + //check that the policy is saved + List<EPMapPolicy> policies = policyManager.getMapPolicies(map); + Assert.assertNotNull(policies); + Assert.assertEquals(1, policies.size()); + EPMapPolicy invitationPolicy = policies.get(0); + Assert.assertEquals(EPMapPolicy.Type.invitation, invitationPolicy.getType()); + + //convert invitation to identity + Identity invitee = invitationDao.createIdentityFrom(invitation, Locale.ENGLISH); + dbInstance.commitAndCloseSession(); + + //check is shared + boolean shared = policyManager.isMapShared(map.getOlatResource()); + Assert.assertTrue(shared); + + boolean visible = epFrontendManager.isMapVisible(invitee, map.getOlatResource()); + Assert.assertTrue(visible); + } + + + + + +} diff --git a/src/test/java/org/olat/portfolio/EPStructureManagerTest.java b/src/test/java/org/olat/portfolio/manager/EPStructureManagerTest.java similarity index 97% rename from src/test/java/org/olat/portfolio/EPStructureManagerTest.java rename to src/test/java/org/olat/portfolio/manager/EPStructureManagerTest.java index e67c7a9629388d3d2d0040240f2e156171d3ac5a..a9b29f4f890e1cded03feabe6af28f7d5f32f894 100644 --- a/src/test/java/org/olat/portfolio/EPStructureManagerTest.java +++ b/src/test/java/org/olat/portfolio/manager/EPStructureManagerTest.java @@ -18,7 +18,7 @@ * <p> */ -package org.olat.portfolio; +package org.olat.portfolio.manager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -103,24 +103,26 @@ public class EPStructureManagerTest extends OlatTestCase { @Test public void testGetStructureElementsForUser(){ - PortfolioStructure el = epFrontendManager.createAndPersistPortfolioDefaultMap(ident1, "users-test-map", "a-map-to-test-get-afterwards"); + Identity user = JunitTestHelper.createAndPersistIdentityAsRndUser("EP-1-"); + + PortfolioStructure el = epFrontendManager.createAndPersistPortfolioDefaultMap(user, "users-test-map", "a-map-to-test-get-afterwards"); assertNotNull(el); dbInstance.commitAndCloseSession(); - List<SecurityGroup> secGroups = securityManager.getSecurityGroupsForIdentity(ident1); + List<SecurityGroup> secGroups = securityManager.getSecurityGroupsForIdentity(user); assertNotNull(secGroups); assertTrue(secGroups.size() >= 1); - List<PortfolioStructure> elRes = epFrontendManager.getStructureElementsForUser(ident1); + List<PortfolioStructure> elRes = epFrontendManager.getStructureElementsForUser(user); assertNotNull(elRes); assertTrue(elRes.size() == 1); assertEquals( ((EPStructureElement)elRes.get(0)).getTitle(), "users-test-map"); // get another map - PortfolioStructure el2 = epFrontendManager.createAndPersistPortfolioDefaultMap(ident1, "users-test-map-2", "2-a-map-to-test-get-afterwards"); + PortfolioStructure el2 = epFrontendManager.createAndPersistPortfolioDefaultMap(user, "users-test-map-2", "2-a-map-to-test-get-afterwards"); assertNotNull(el2); dbInstance.commitAndCloseSession(); - List<PortfolioStructure> elRes2 = epFrontendManager.getStructureElementsForUser(ident1); + List<PortfolioStructure> elRes2 = epFrontendManager.getStructureElementsForUser(user); assertNotNull(elRes2); assertTrue(elRes2.size() == 2); } @@ -423,7 +425,7 @@ public class EPStructureManagerTest extends OlatTestCase { } @Test - public void testLoadPortfolioStructuredMaps(){ + public void testLoadPortfolioStructuredMaps() { Identity user = JunitTestHelper.createAndPersistIdentityAsRndUser("EP-tmp-"); //a template PortfolioStructureMap template = epStructureManager.createPortfolioMapTemplate(user, "paged-parent-structure-el", "parent-structure-element"); @@ -449,6 +451,20 @@ public class EPStructureManagerTest extends OlatTestCase { Assert.assertEquals(map, myCloneAlt.get(0)); } + @Test + public void testCountStructureElementsFromOthers() { + Identity user = JunitTestHelper.createAndPersistIdentityAsRndUser("EP-tmp-"); + + PortfolioStructureMap map = epStructureManager.createPortfolioDefaultMap("map-el", "map-element"); + epStructureManager.savePortfolioStructure(map); + dbInstance.commitAndCloseSession(); + + //clone the template + int count = epStructureManager.countStructureElementsFromOthers(user, null); + Assert.assertEquals(0, count); + } + + @Test public void testMoveUp() { diff --git a/src/test/java/org/olat/portfolio/manager/InvitationDAOTest.java b/src/test/java/org/olat/portfolio/manager/InvitationDAOTest.java new file mode 100644 index 0000000000000000000000000000000000000000..50fd1383186b7c35f27de4c05b16416a53675cb1 --- /dev/null +++ b/src/test/java/org/olat/portfolio/manager/InvitationDAOTest.java @@ -0,0 +1,105 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.portfolio.manager; + +import java.util.Date; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Test; +import org.olat.basesecurity.Invitation; +import org.olat.core.commons.persistence.DB; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 25.06.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class InvitationDAOTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private InvitationDAO invitationDao; + @Autowired + private EPPolicyManager policyManager; + + + @Test + public void createAndPersistInvitation() { + Invitation invitation = invitationDao.createAndPersistInvitation(); + Assert.assertNotNull(invitation); + dbInstance.commit(); + + Assert.assertNotNull(invitation); + Assert.assertNotNull(invitation.getKey()); + Assert.assertNotNull(invitation.getBaseGroup()); + Assert.assertNotNull(invitation.getToken()); + } + + @Test + public void findInvitation_token() { + Invitation invitation = invitationDao.createAndPersistInvitation(); + Assert.assertNotNull(invitation); + dbInstance.commitAndCloseSession(); + + Invitation reloadedInvitation = invitationDao.findInvitation(invitation.getToken()); + Assert.assertNotNull(reloadedInvitation); + Assert.assertNotNull(reloadedInvitation.getKey()); + Assert.assertNotNull(reloadedInvitation.getBaseGroup()); + Assert.assertEquals(invitation, reloadedInvitation); + Assert.assertEquals(invitation.getToken(), reloadedInvitation.getToken()); + } + + @Test + public void hasInvitationPolicies_testHQL() { + String token = UUID.randomUUID().toString(); + Date atDate = new Date(); + boolean hasInvitation = invitationDao.hasInvitations(token, atDate); + Assert.assertFalse(hasInvitation); + } + + @Test + public void createAndUpdateInvitation() { + Invitation invitation = invitationDao.createAndPersistInvitation(); + dbInstance.commit(); + + invitation.setFirstName("Kanu"); + invitation.setLastName("Unchou"); + invitation.setMail("kanu.unchou@frentix.com"); + Invitation updatedInvitation = invitationDao.update(invitation); + dbInstance.commit(); + + Assert.assertEquals("Kanu", updatedInvitation.getFirstName()); + Assert.assertEquals("Unchou", updatedInvitation.getLastName()); + Assert.assertEquals("kanu.unchou@frentix.com", updatedInvitation.getMail()); + + Invitation reloadedInvitation = invitationDao.findInvitation(invitation.getToken()); + Assert.assertEquals("Kanu", reloadedInvitation.getFirstName()); + Assert.assertEquals("Unchou", reloadedInvitation.getLastName()); + Assert.assertEquals("kanu.unchou@frentix.com", reloadedInvitation.getMail()); + } + + + +} diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index 67680537d45e4ced47986b5ee846b28e20ea65a2..8ea0619c5ec5fff2ada072f53390434196b7d4c5 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -169,7 +169,9 @@ import org.junit.runners.Suite; org.olat.portfolio.PortfolioModuleTest.class, org.olat.portfolio.EPArtefactManagerTest.class, org.olat.portfolio.EPFrontendManagerTest.class, - org.olat.portfolio.EPStructureManagerTest.class, + org.olat.portfolio.manager.EPStructureManagerTest.class, + org.olat.portfolio.manager.EPPolicyManagerTest.class, + org.olat.portfolio.manager.InvitationDAOTest.class, org.olat.portfolio.EPStructureToArtefactTest.class, org.olat.portfolio.EPImportTest.class, org.olat.modules.openmeetings.OpenMeetingsTest.class,