You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2016/08/21 17:20:42 UTC

svn commit: r1757068 [1/2] - in /openmeetings/application: branches/3.1.x/ branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/ branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/label/ branches/3.1.x/openmeeti...

Author: solomax
Date: Sun Aug 21 17:20:41 2016
New Revision: 1757068

URL: http://svn.apache.org/viewvc?rev=1757068&view=rev
Log:
[OPENMEETINGS-1138] invitation dialog is added to the recordings

Added:
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/IUpdatable.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.html
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/IUpdatable.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/IUpdatable.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
Modified:
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/label/LabelDao.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
    openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
    openmeetings/application/branches/3.1.x/openmeetings-web/pom.xml
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BaseInitedPage.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.html
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingInvitationForm.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingResourceReference.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java
    openmeetings/application/branches/3.1.x/openmeetings-webservice/pom.xml
    openmeetings/application/branches/3.1.x/pom.xml
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
    openmeetings/application/branches/3.2.x/openmeetings-web/pom.xml
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BaseInitedPage.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.html
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingInvitationForm.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingResourceReference.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java
    openmeetings/application/branches/3.2.x/pom.xml
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
    openmeetings/application/trunk/openmeetings-web/pom.xml
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BaseInitedPage.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.html
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingInvitationForm.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingResourceReference.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java
    openmeetings/application/trunk/openmeetings-webservice/pom.xml
    openmeetings/application/trunk/pom.xml

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java Sun Aug 21 17:20:41 2016
@@ -35,7 +35,7 @@ public interface IApplication {
 	String getOmString(long id, long languageId);
 	String getOmString(String key, long languageId);
 	String getOmContactsLink();
-	String getOmInvitationLink(String baseUrl, Invitation i);
+	String getOmInvitationLink(Invitation i);
 	String urlForActivatePage(PageParameters pp);
 	void invalidateClient(Long userId, String sessionId);
 }

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/label/LabelDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/label/LabelDao.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/label/LabelDao.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/label/LabelDao.java Sun Aug 21 17:20:41 2016
@@ -120,7 +120,7 @@ public class LabelDao implements IDataPr
 		return new File(OmFileHelper.getLanguagesDir(), OmFileHelper.nameOfLanguageFile);
 	}
 	
-	public static Class<?> getAppClass() throws ClassNotFoundException {
+	public static synchronized Class<?> getAppClass() throws ClassNotFoundException {
 		if (APP == null) {
 			//FIXME HACK to resolve package dependencies
 			APP = Class.forName("org.apache.openmeetings.web.app.Application");

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java Sun Aug 21 17:20:41 2016
@@ -18,9 +18,11 @@
  */
 package org.apache.openmeetings.db.dao.room;
 
+import static org.apache.openmeetings.util.CalendarHelper.getZoneId;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 
 import java.util.Date;
+import java.util.List;
 
 import javax.persistence.EntityManager;
 import javax.persistence.NoResultException;
@@ -28,9 +30,12 @@ import javax.persistence.PersistenceCont
 import javax.persistence.TypedQuery;
 
 import org.apache.openmeetings.db.entity.room.Invitation;
+import org.apache.openmeetings.util.CalendarHelper;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.transaction.annotation.Transactional;
+import org.threeten.bp.LocalDateTime;
+import org.threeten.bp.ZonedDateTime;
 
 @Transactional
 public class InvitationDao {
@@ -67,20 +72,35 @@ public class InvitationDao {
 		return null;
 	}
 	
-	public Invitation getInvitationByHashCode(String hashCode, boolean hidePass) {
-		try {
-			
-			TypedQuery<Invitation> query = em.createNamedQuery("getInvitationByHashCode", Invitation.class);
-			query.setParameter("hashCode", hashCode);
-			
-			try {
-				return query.getSingleResult();
-			} catch (NoResultException ex) {
+	public Invitation getByHash(String hash, boolean hidePass, boolean markUsed) {
+		List<Invitation> list = em.createNamedQuery("getInvitationByHashCode", Invitation.class)
+				.setParameter("hashCode", hash).getResultList();
+		Invitation i = list != null && list.size() == 1 ? list.get(0) : null;
+		if (i != null) {
+			switch (i.getValid()) {
+				case OneTime:
+					// one-time invitation
+					i.setAllowEntry(!i.isUsed());
+					if (markUsed) {
+						i.setUsed(true);
+						update(i);
+					}
+					break;
+				case Period:
+					LocalDateTime now = ZonedDateTime.now(getZoneId(i.getInvitee().getTimeZoneId())).toLocalDateTime();
+					LocalDateTime from = CalendarHelper.getDateTime(i.getValidFrom(), i.getInvitee().getTimeZoneId());
+					LocalDateTime to = CalendarHelper.getDateTime(i.getValidTo(), i.getInvitee().getTimeZoneId());
+					i.setAllowEntry(now.isAfter(from) && now.isBefore(to));
+					break;
+				case Endless:
+				default:
+					i.setAllowEntry(true);
+					break;
+			}
+			if (hidePass) {
+				i.setPassword(null);
 			}
-			
-		} catch (Exception e) {
-			log.error("getInvitationByHashCode : ", e);
 		}
-		return null;
+		return i;
 	}
 }

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java Sun Aug 21 17:20:41 2016
@@ -39,6 +39,7 @@ import javax.persistence.Transient;
 import org.apache.openjpa.persistence.jdbc.ForeignKey;
 import org.apache.openmeetings.db.entity.IDataProviderEntity;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
+import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.db.entity.user.User;
 
 @Entity
@@ -91,6 +92,11 @@ public class Invitation implements IData
 	@ForeignKey(enabled = true)
 	private Room room;
 
+	@ManyToOne(fetch = FetchType.EAGER)
+	@JoinColumn(name = "recording_id", nullable = true)
+	@ForeignKey(enabled = true)
+	private Recording recording;
+
 	// the hash for the link
 	@Column(name = "hash")
 	private String hash;
@@ -139,6 +145,7 @@ public class Invitation implements IData
 		updated = i.updated;
 		deleted = i.deleted;
 		room = i.room;
+		recording = i.recording;
 		hash = i.hash;
 		invitee = i.invitee;
 		passwordProtected = i.passwordProtected;
@@ -168,6 +175,14 @@ public class Invitation implements IData
 		this.room = room;
 	}
 
+	public Recording getRecording() {
+		return recording;
+	}
+
+	public void setRecording(Recording recording) {
+		this.recording = recording;
+	}
+
 	public User getInvitedBy() {
 		return invitedBy;
 	}

Modified: openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java Sun Aug 21 17:20:41 2016
@@ -18,9 +18,9 @@
  */
 package org.apache.openmeetings.service.room;
 
+import static org.apache.openmeetings.db.util.ApplicationHelper.ensureApplication;
 import static org.apache.openmeetings.util.CalendarHelper.getZoneId;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.wicketApplicationName;
 
 import java.util.Date;
 import java.util.Map;
@@ -31,7 +31,6 @@ import java.util.Vector;
 import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.mail.MailHandler;
 import org.apache.openmeetings.core.mail.SMSHandler;
-import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.room.IInvitationManager;
 import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.entity.basic.MailMessage;
@@ -53,7 +52,6 @@ import org.apache.openmeetings.service.m
 import org.apache.openmeetings.util.CalendarHelper;
 import org.apache.openmeetings.util.crypt.CryptProvider;
 import org.apache.openmeetings.util.mail.IcalHandler;
-import org.apache.wicket.Application;
 import org.apache.wicket.util.string.Strings;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -77,8 +75,6 @@ public class InvitationManager implement
 	private SMSHandler smsHandler;
 	@Autowired
 	private TimezoneUtil timezoneUtil;
-	@Autowired
-	private ConfigurationDao configDao;
 
 	/**
 	 * @author vasya
@@ -113,7 +109,11 @@ public class InvitationManager implement
 	
 	@Override
 	public void sendInvitationLink(Invitation i, MessageType type, String subject, String message, boolean ical) throws Exception {
-		String invitation_link = type == MessageType.Cancel ? null : ((IApplication)Application.get(wicketApplicationName)).getOmInvitationLink(configDao.getBaseUrl(), i); //TODO check for exceptions
+		String invitation_link = null;
+		if (type != MessageType.Cancel) {
+			IApplication app = ensureApplication(1L);
+			invitation_link = app.getOmInvitationLink(i);
+		}
 		User owner = i.getInvitedBy();
 		
 		String invitorName = owner.getFirstname() + " " + owner.getLastname();
@@ -183,7 +183,7 @@ public class InvitationManager implement
 	public Object getInvitationByHashCode(String hashCode, boolean hidePass) {
 		try {
 			log.debug("Invitation was requested by hashcode: " + hashCode);
-			Invitation i = invitationDao.getInvitationByHashCode(hashCode, hidePass);
+			Invitation i = invitationDao.getByHash(hashCode, hidePass, true);
 
 			if (i == null) {
 				// already deleted or does not exist
@@ -193,48 +193,15 @@ public class InvitationManager implement
 					case OneTime:
 						// do this only if the user tries to get the Invitation, not
 						// while checking the PWD
-						if (hidePass) {
-							// one-time invitation
-							if (i.isUsed()) {
-								// Invitation is of type *only-one-time* and was
-								// already used
-								return new Long(-32);
-							} else {
-								// set to true if this is the first time / a normal
-								// getInvitation-Query
-								i.setUsed(true);
-								invitationDao.update(i);
-								// invitation.setInvitationpass(null);
-								i.setAllowEntry(true);
-							}
-						} else {
-							i.setAllowEntry(true);
+						if (!i.isAllowEntry()) {
+							// Invitation is of type *only-one-time* and was
+							// already used
+							return new Long(-32);
 						}
 						break;
 					case Period:
-						LocalDateTime now = ZonedDateTime.now(getZoneId(i.getInvitee().getTimeZoneId())).toLocalDateTime();
-						LocalDateTime from = CalendarHelper.getDateTime(i.getValidFrom(), i.getInvitee().getTimeZoneId());
-						LocalDateTime to = CalendarHelper.getDateTime(i.getValidTo(), i.getInvitee().getTimeZoneId());
-						if (now.isAfter(from) && now.isBefore(to)) {
-							invitationDao.update(i);
-							// invitation.setInvitationpass(null);
-							i.setAllowEntry(true);
-						} else {
-
-							// Invitation is of type *period* and is not valid
-							// anymore, this is an extra hook to display the time
-							// correctly
-							// in the method where it shows that the hash code does
-							// not work anymore
-							i.setAllowEntry(false);
-						}
-						break;
 					case Endless:
 					default:
-						invitationDao.update(i);
-
-						i.setAllowEntry(true);
-						// invitation.setInvitationpass(null);
 						break;
 				}
 				return i;

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/pom.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/pom.xml?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/pom.xml (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/pom.xml Sun Aug 21 17:20:41 2016
@@ -656,6 +656,10 @@
 				</exclusion>
 			</exclusions>
 		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+		</dependency>
 		<!-- Test dependencies -->
 		<dependency>
 			<groupId>org.seleniumhq.selenium</groupId>

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java Sun Aug 21 17:20:41 2016
@@ -40,6 +40,7 @@ import org.apache.wicket.model.Model;
 import org.apache.wicket.util.time.Duration;
 import org.apache.wicket.validation.IValidatable;
 import org.apache.wicket.validation.IValidator;
+import org.apache.wicket.validation.ValidationError;
 
 /**
  * Handle {@link Configuration} items as list and form
@@ -67,7 +68,7 @@ public class ConfigForm extends AdminBas
 			public void validate(IValidatable<String> validatable) {
 				Configuration c = getBean(ConfigurationDao.class).forceGet(validatable.getValue());
 				if (c != null && !c.isDeleted() && !c.getId().equals(ConfigForm.this.getModelObject().getId())) {
-					error(Application.getString(1544L));
+					validatable.error(new ValidationError(Application.getString(1544L)));
 				}
 			}
 		}));

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Sun Aug 21 17:20:41 2016
@@ -24,6 +24,7 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.util.OmUrlFragment.PROFILE_MESSAGES;
 import static org.red5.logging.Red5LoggerFactory.getLogger;
 import static org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext;
+import static org.apache.openmeetings.web.app.WebSession.INVITATION_HASH;
 
 import java.text.MessageFormat;
 import java.util.ArrayList;
@@ -45,6 +46,7 @@ import org.apache.openmeetings.core.remo
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.user.User;
@@ -147,12 +149,13 @@ public class Application extends Authent
 		mountPage("activate", ActivatePage.class);
 		mountPage("reset", ResetPage.class);
 		mountPage("/recording/${hash}", RecordingPage.class);
+		mountPage("/recording", RecordingPage.class);
 		mountResource("/recordings/avi/${id}", new AviRecordingResourceReference());
 		mountResource("/recordings/flv/${id}", new FlvRecordingResourceReference());
 		mountResource("/recordings/mp4/${id}", new Mp4RecordingResourceReference());
 		mountResource("/recordings/ogg/${id}", new OggRecordingResourceReference());
 		mountResource("/recordings/jpg/${id}", new JpgRecordingResourceReference()); //should be in sync with VideoPlayer
-		mountResource("/profile/${id}", new ProfileImageResourceReference()); //should be in sync with VideoPlayer
+		mountResource("/profile/${id}", new ProfileImageResourceReference());
 	}
 
 	private static class NoVersionMapper extends MountedMapper {
@@ -437,11 +440,8 @@ public class Application extends Authent
 		return getContactsLink();
 	}
 
-	public static String getInvitationLink(String baseUrl, Invitation i) {
-		String link = baseUrl;
-		if (link == null) {
-			return null;
-		}
+	public static String getInvitationLink(Invitation i) {
+		String link = "";
 		Room r = i.getRoom();
 		User u = i.getInvitee();
 		if (r != null) {
@@ -450,21 +450,26 @@ public class Application extends Authent
 				allowed = getBean(MainService.class).isRoomAllowedToUser(r, u);
 			}
 			if (!allowed) {
-				link += "?invitationHash=" + i.getHash();
-		
+				PageParameters pp = new PageParameters();
+				pp.add(INVITATION_HASH, i.getHash());
 				if (u.getLanguageId() > 0) {
-					link += "&language=" + u.getLanguageId();
+					pp.add("language", u.getLanguageId());
 				}
+				link = urlForPage(MainPage.class, pp);
 			} else {
 				link = getRoomUrlFragment(r.getId()).getLink();
 			}
 		}
+		Recording rec = i.getRecording();
+		if (rec != null) {
+			link = urlForPage(RecordingPage.class, new PageParameters().add(INVITATION_HASH, i.getHash()));
+		}
 		return link;
 	}
 	
 	@Override
-	public String getOmInvitationLink(String baseUrl, Invitation i) { //FIXME hack for email templates support (should be in separate module for now
-		return getInvitationLink(baseUrl, i);
+	public String getOmInvitationLink(Invitation i) { //FIXME hack for email templates support (should be in separate module for now
+		return getInvitationLink(i);
 	}
 	
 	public static String urlForPage(Class<? extends Page> clazz, PageParameters pp) {

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java Sun Aug 21 17:20:41 2016
@@ -30,8 +30,6 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.app.Application.removeInvalidSession;
 import static org.apache.openmeetings.web.app.Application.removeOnlineUser;
 
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collections;
@@ -44,14 +42,17 @@ import java.util.Locale;
 import java.util.Set;
 import java.util.TimeZone;
 
+import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.openmeetings.IWebSession;
 import org.apache.openmeetings.core.ldap.LdapLoginManagement;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
+import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.dao.server.SOAPLoginDao;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;
 import org.apache.openmeetings.db.dao.user.IUserManager;
 import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.server.RemoteSessionObject;
 import org.apache.openmeetings.db.entity.server.SOAPLogin;
 import org.apache.openmeetings.db.entity.server.Sessiondata;
@@ -60,6 +61,7 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.db.util.TimezoneUtil;
 import org.apache.openmeetings.util.OmException;
+import org.apache.openmeetings.web.pages.RecordingPage;
 import org.apache.openmeetings.web.pages.SwfPage;
 import org.apache.openmeetings.web.user.dashboard.MyRoomsWidget;
 import org.apache.openmeetings.web.user.dashboard.MyRoomsWidgetDescriptor;
@@ -89,11 +91,12 @@ import org.wicketstuff.dashboard.web.Das
 public class WebSession extends AbstractAuthenticatedWebSession implements IWebSession {
 	private static final long serialVersionUID = 1L;
 	public static final int MILLIS_IN_MINUTE = 60000;
-	public static final String SECURE_HASH = "secureHash";
-	public static final String INVITATION_HASH = "invitationHash";
 	public static final String ISO8601_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssZ";
 	public static final List<String> AVAILABLE_TIMEZONES = Arrays.asList(TimeZone.getAvailableIDs());
 	public static final Set<String> AVAILABLE_TIMEZONE_SET = new LinkedHashSet<String>(AVAILABLE_TIMEZONES);
+	public static final String WICKET_ROOM_ID = "wicketroomid";
+	static final String SECURE_HASH = "secureHash";
+	static final String INVITATION_HASH = "invitationHash";
 	private Long userId = null;
 	private Set<Right> rights = new HashSet<User.Right>(); //TODO renew somehow on user edit !!!!
 	private long languageId = -1; //TODO renew somehow on user edit !!!!
@@ -101,15 +104,17 @@ public class WebSession extends Abstract
 	private OmUrlFragment area = null;
 	private TimeZone tz;
 	private TimeZone browserTz;
-	private DateFormat ISO8601FORMAT = new SimpleDateFormat(ISO8601_FORMAT_STRING); //FIXME not thread safe
-	private DateFormat sdf;
+	private FastDateFormat ISO8601FORMAT = null;
+	private FastDateFormat  sdf = null;
 	private UserDashboard dashboard;
 	private Locale browserLocale = null;
-	private Long recordingId;
+	private Invitation i = null;
+	private Long roomId = null;
+	private Long recordingId = null;
 	private Long loginError = null;
 	private String externalType;
 	private boolean kickedByAdmin = false;
-	
+
 	public WebSession(Request request) {
 		super(request);
 		browserLocale = getLocale();
@@ -122,7 +127,10 @@ public class WebSession extends Abstract
 		userId = null;
 		rights = new HashSet<User.Right>();
 		SID = null;
+		ISO8601FORMAT = null;
 		sdf = null;
+		i = null;
+		roomId = null;
 		recordingId = null;
 		externalType = null;
 		tz = null;
@@ -130,36 +138,23 @@ public class WebSession extends Abstract
 		loginError = null;
 		browserLocale = null;
 	}
-	
-	@Override
-	public Roles getRoles() {
-		//first of all will check hashes
-		try {
-			IRequestParameters params = RequestCycle.get().getRequest().getRequestParameters();
-			StringValue secureHash = params.getParameterValue(SECURE_HASH);
-			StringValue invitationHash = params.getParameterValue(INVITATION_HASH);
-			if (!secureHash.isEmpty() || !invitationHash.isEmpty()) {
-				PageParameters pp = new PageParameters();
-				for (String p : params.getParameterNames()) {
-					List<StringValue> vals = params.getParameterValues(p);
-					if (vals != null) {
-						for (StringValue sv : vals) {
-							if (!sv.isEmpty()) {
-								pp.add(p, sv.toString());
-							}
-						}
+
+	private PageParameters getParams(IRequestParameters params, PageParameters pp) {
+		for (String p : params.getParameterNames()) {
+			List<StringValue> vals = params.getParameterValues(p);
+			if (vals != null) {
+				for (StringValue sv : vals) {
+					if (!sv.isEmpty()) {
+						pp.add(p, sv.toString());
 					}
 				}
-				if (isSignedIn()) {
-					invalidate();
-				}
-				throw new RestartResponseAtInterceptPageException(SwfPage.class, pp);
 			}
-		} catch (RestartResponseAtInterceptPageException e) {
-			throw e;
-		} catch (Exception e) {
-			//no-op, will continue to sign-in page
 		}
+		return pp;
+	}
+
+	@Override
+	public Roles getRoles() {
 		if (rights.isEmpty()) {
 			isSignedIn();
 		}
@@ -193,6 +188,56 @@ public class WebSession extends Abstract
 		return userId != null && userId.longValue() > 0;
 	}
 
+	public void checkHashes(boolean redirect) {
+		IRequestParameters params = RequestCycle.get().getRequest().getRequestParameters();
+		StringValue secureHash = params.getParameterValue(SECURE_HASH);
+		StringValue invitationHash = params.getParameterValue(INVITATION_HASH);
+		PageParameters pp = new PageParameters();
+		try {
+			if (!secureHash.isEmpty()) {
+				if (isSignedIn()) {
+					invalidate();
+				}
+				if (signIn(secureHash.toString(), false)) {
+					//TODO markUsed
+				} else {
+					//TODO redirect to error
+				}
+			}
+			if (!invitationHash.isEmpty()) {
+				if (isSignedIn()) {
+					invalidate();
+				}
+				i = getBean(InvitationDao.class).getByHash(invitationHash.toString(), false, false);
+				if (i.isAllowEntry()) {
+					setUser(i.getInvitee());
+					//TODO markUsed
+					if (i.getRoom() != null) {
+						roomId = i.getRoom().getId();
+					} else if (i.getAppointment() != null && i.getAppointment().getRoom() != null) {
+						roomId = i.getAppointment().getRoom().getId();
+					} else if (i.getRecording() != null) {
+						recordingId = i.getRecording().getId();
+					}
+				}
+			}
+			if (!secureHash.isEmpty() || !invitationHash.isEmpty()) {
+				if (roomId != null) {
+					getParams(params, pp).add(WICKET_ROOM_ID, roomId);
+					if (redirect) {
+						throw new RestartResponseAtInterceptPageException(SwfPage.class, pp);
+					}
+				} else if (recordingId != null && redirect){
+					throw new RestartResponseAtInterceptPageException(RecordingPage.class, pp);
+				}
+			}
+		} catch (RestartResponseAtInterceptPageException e) {
+			throw e;
+		} catch (Exception e) {
+			//no-op, will continue to sign-in page
+		}
+	}
+
 	public boolean signIn(String secureHash, boolean markUsed) {
 		//FIXME code is duplicated from MainService, need to be unified
 		SOAPLoginDao soapDao = getBean(SOAPLoginDao.class);
@@ -234,6 +279,7 @@ public class WebSession extends Abstract
 					}
 					sessionDao.updateUser(SID, user.getId());
 					setUser(user);
+					roomId = soapLogin.getRoomId();
 					recordingId = soapLogin.getRecordingId();
 					return true;
 				}
@@ -241,7 +287,7 @@ public class WebSession extends Abstract
 		}
 		return false;
 	}
-	
+
 	private void setUser(User u) {
 		String _sid = SID;
 		Long _recordingId = recordingId;
@@ -257,10 +303,10 @@ public class WebSession extends Abstract
 		languageId = u.getLanguageId();
 		externalType = u.getExternalType();
 		tz = getBean(TimezoneUtil.class).getTimeZone(u);
-		ISO8601FORMAT.setTimeZone(tz);
+		ISO8601FORMAT = FastDateFormat.getInstance(ISO8601_FORMAT_STRING, tz);
 		setLocale(languageId == 3 ? Locale.GERMANY : LabelDao.languages.get(languageId));
 		//FIXMW locale need to be set by User language first
-		sdf = DateFormat.getDateTimeInstance(SHORT, SHORT, getLocale());
+		sdf = FastDateFormat.getDateTimeInstance(SHORT, SHORT, getLocale());
 	}
 	
 	public boolean signIn(String login, String password, Type type, Long domainId) {
@@ -354,15 +400,19 @@ public class WebSession extends Abstract
 		checkIsInvalid();
 		return get().userId;
 	}
-	
+
 	public static Long getRecordingId() {
 		return get().recordingId;
 	}
-	
+
+	public Invitation getInvitation() {
+		return i;
+	}
+
 	public static String getExternalType() {
 		return get().externalType;
 	}
-	
+
 	public static TimeZone getUserTimeZone() {
 		return get().tz;
 	}
@@ -375,11 +425,11 @@ public class WebSession extends Abstract
 		return Calendar.getInstance(getClientTimeZone());
 	}
 
-	public static DateFormat getIsoDateFormat() {
+	public static FastDateFormat getIsoDateFormat() {
 		return get().ISO8601FORMAT;
 	}
 	
-	public static DateFormat getDateFormat() {
+	public static FastDateFormat getDateFormat() {
 		return get().sdf;
 	}
 	

Added: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/IUpdatable.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/IUpdatable.java?rev=1757068&view=auto
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/IUpdatable.java (added)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/IUpdatable.java Sun Aug 21 17:20:41 2016
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.web.common;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+
+public interface IUpdatable {
+	void update(AjaxRequestTarget target);
+}

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/InvitationForm.java Sun Aug 21 17:20:41 2016
@@ -29,7 +29,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.UUID;
 
-import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.room.Invitation;
@@ -156,7 +155,7 @@ public abstract class InvitationForm ext
 		i.setUpdated(null);
 		i.setUsed(false);
 		
-		i.setPassword(CryptProvider.get().hash(i.getPassword())); //FIXME should be hidden
+		i.setPassword(CryptProvider.get().hash(i.getPassword()));
 		i.setValidFrom(getDate(from.getModelObject().minusMinutes(5), timeZoneId.getModelObject()));
 		i.setValidTo(getDate(to.getModelObject(), timeZoneId.getModelObject()));
 		
@@ -209,7 +208,7 @@ public abstract class InvitationForm ext
 		} else if (button.equals(dialog.generate)) {
 			Invitation i = create(recipients.getModelObject().iterator().next());
 			setModelObject(i);
-			url.setModelObject(getInvitationLink(getBean(ConfigurationDao.class).getBaseUrl(), i));
+			url.setModelObject(getInvitationLink(i));
 			target.add(url);
 		} else if (button.equals(dialog.send)) {
 			if (Strings.isEmpty(url.getModelObject())) {

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BaseInitedPage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BaseInitedPage.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BaseInitedPage.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BaseInitedPage.java Sun Aug 21 17:20:41 2016
@@ -27,6 +27,15 @@ import org.apache.openmeetings.web.app.W
 public abstract class BaseInitedPage extends BasePage {
 	private static final long serialVersionUID = 1L;
 
+	public BaseInitedPage() {
+		super();
+		WebSession.get().checkHashes(getHashRedirect());
+	}
+
+	protected boolean getHashRedirect() {
+		return true;
+	}
+
 	@Override
 	protected String getApplicationName() {
 		return getBean(ConfigurationDao.class).getAppName();

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/BasePage.java Sun Aug 21 17:20:41 2016
@@ -62,9 +62,9 @@ public abstract class BasePage extends A
 
 		String code = getLanguageCode();
 		add(new TransparentWebMarkupContainer("html")
-	    	.add(new AttributeModifier("xml:lang", code))
-	    	.add(new AttributeModifier("lang", code))
-	    	.add(new AttributeModifier("dir", isRtl() ? "rtl" : "ltr"))); 
+				.add(new AttributeModifier("xml:lang", code))
+				.add(new AttributeModifier("lang", code))
+				.add(new AttributeModifier("dir", isRtl() ? "rtl" : "ltr"))); 
 		add(new Label("pageTitle", appName));
 		add(header = new HeaderPanel("header", appName));
 	}

Added: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.html
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.html?rev=1757068&view=auto
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.html (added)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.html Sun Aug 21 17:20:41 2016
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+      http://www.apache.org/licenses/LICENSE-2.0
+    	  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+<wicket:panel>
+	<form wicket:id="form">
+		<div wicket:id="feedback"></div>
+		<label wicket:for="password"><wicket:message key="536"/></label>
+		<input wicket:id="password" type="password"/>
+	</form>
+</wicket:panel>
+</html>

Added: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java?rev=1757068&view=auto
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java (added)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/InvitationPasswordDialog.java Sun Aug 21 17:20:41 2016
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.web.pages;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.openmeetings.db.entity.room.Invitation;
+import org.apache.openmeetings.util.crypt.CryptProvider;
+import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.WebSession;
+import org.apache.openmeetings.web.common.IUpdatable;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.PasswordTextField;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.validation.IValidatable;
+import org.apache.wicket.validation.IValidator;
+import org.apache.wicket.validation.ValidationError;
+
+import com.googlecode.wicket.jquery.core.JQueryBehavior;
+import com.googlecode.wicket.jquery.core.Options;
+import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractFormDialog;
+import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
+import com.googlecode.wicket.kendo.ui.panel.KendoFeedbackPanel;
+
+public class InvitationPasswordDialog extends AbstractFormDialog<Invitation> {
+	private static final long serialVersionUID = 1L;
+	private final KendoFeedbackPanel feedback = new KendoFeedbackPanel("feedback", new Options("button", true));
+	private final DialogButton check = new DialogButton("check", Application.getString(537));
+	private final Form<Void> form = new Form<>("form");
+	private final PasswordTextField password = new PasswordTextField("password", Model.of((String)null));
+	private final IUpdatable comp;
+
+	public InvitationPasswordDialog(String id, IUpdatable comp) {
+		super(id, Application.getString(524));
+		this.comp = comp;
+		password.setLabel(Model.of(Application.getString(536))).add(new IValidator<String>(){
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void validate(IValidatable<String> validatable) {
+				if (!CryptProvider.get().verify(validatable.getValue(), WebSession.get().getInvitation().getPassword())) {
+					validatable.error(new ValidationError(Application.getString(538L)));
+				}
+			}
+		});
+		add(form.add(password, feedback.setOutputMarkupId(true)));
+	}
+
+	@Override
+	public void onConfigure(JQueryBehavior behavior) {
+		super.onConfigure(behavior);
+		behavior.setOption("autoOpen", WebSession.get().getInvitation().isPasswordProtected());
+		behavior.setOption("closeOnEscape", false);
+		behavior.setOption("dialogClass", Options.asString("no-close"));
+		behavior.setOption("resizable", false);
+	}
+
+	@Override
+	protected void onOpen(IPartialPageRequestHandler handler) {
+		password.setModelObject(null);
+	}
+
+	@Override
+	public DialogButton getSubmitButton() {
+		return check;
+	}
+
+	@Override
+	protected List<DialogButton> getButtons() {
+		return Arrays.asList(check);
+	}
+
+	@Override
+	public Form<Void> getForm() {
+		return form;
+	}
+
+	@Override
+	protected void onError(AjaxRequestTarget target) {
+		target.add(feedback);
+	}
+
+	@Override
+	protected void onSubmit(AjaxRequestTarget target) {
+		comp.update(target);
+	}
+
+}

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.html
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.html?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.html (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.html Sun Aug 21 17:20:41 2016
@@ -24,6 +24,7 @@
 		<div wicket:id="info"></div>
 		<div wicket:id="player"></div>
 	</div>
+	<div wicket:id="i-pass"></div>
 </wicket:extend>
 </html>
 

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/RecordingPage.java Sun Aug 21 17:20:41 2016
@@ -23,29 +23,55 @@ import static org.apache.openmeetings.we
 
 import org.apache.openmeetings.db.dao.record.RecordingDao;
 import org.apache.openmeetings.db.entity.record.Recording;
+import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.web.app.WebSession;
+import org.apache.openmeetings.web.common.IUpdatable;
 import org.apache.openmeetings.web.user.record.VideoInfo;
 import org.apache.openmeetings.web.user.record.VideoPlayer;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.request.IRequestParameters;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.util.string.StringValue;
 
-public class RecordingPage extends BaseInitedPage {
+public class RecordingPage extends BaseInitedPage implements IUpdatable {
 	private static final long serialVersionUID = 1L;
+	private final VideoInfo vi = new VideoInfo("info", null);
+	private final VideoPlayer vp = new VideoPlayer("player", null);
 
 	public RecordingPage(PageParameters p) {
-		String hash = p.get("hash").toString();
+		StringValue hash = p.get("hash");
 		Recording r = null;
-		if (WebSession.get().signIn(hash, true)) {
+		WebSession ws = WebSession.get();
+		if (!hash.isEmpty()) {
+			ws.signIn(hash.toString(), true);
+		}
+		Invitation i = ws.getInvitation();
+		if (i != null && !i.isPasswordProtected()) {
+			r = i.getRecording();
+		} else if (i == null) {
 			Long recId = getRecordingId();
 			if (recId != null) {
 				r = getBean(RecordingDao.class).get(recId);
 			}
 		}
-		add(new VideoInfo("info", r).setVisible(r != null), new VideoPlayer("player", r).setVisible(r != null));
+		add(vi.setShowShare(false).update(null, r).setOutputMarkupPlaceholderTag(true).setVisible(r != null)
+			, vp.update(null, r).setOutputMarkupPlaceholderTag(true).setVisible(r != null)
+			, new InvitationPasswordDialog("i-pass", this));
+	}
+
+	@Override
+	protected boolean getHashRedirect() {
+		return false;
 	}
 
 	@Override
 	protected void onParameterArrival(IRequestParameters requestParameters, AjaxRequestTarget target) {
 	}
+	
+	@Override
+	public void update(AjaxRequestTarget target) {
+		Invitation i = WebSession.get().getInvitation();
+		target.add(vi.update(target, i.getRecording()).setVisible(true)
+				, vp.update(target, i.getRecording()).setVisible(true));
+	}
 }

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java Sun Aug 21 17:20:41 2016
@@ -21,6 +21,7 @@ package org.apache.openmeetings.web.room
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.getRoomUsers;
+import static org.apache.openmeetings.web.app.WebSession.WICKET_ROOM_ID;
 import static org.apache.openmeetings.web.app.WebSession.getLanguage;
 import static org.apache.openmeetings.web.app.WebSession.getSid;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
@@ -34,14 +35,11 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.openmeetings.core.session.SessionManager;
-import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.dao.room.PollDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
-import org.apache.openmeetings.db.dao.server.SOAPLoginDao;
 import org.apache.openmeetings.db.dao.server.ServerDao;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;
 import org.apache.openmeetings.db.entity.room.Client;
-import org.apache.openmeetings.db.entity.server.SOAPLogin;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
@@ -74,7 +72,6 @@ import org.slf4j.Logger;
 
 public class RoomPanel extends BasePanel {
 	private static final long serialVersionUID = 1L;
-	private static final String WICKET_ROOM_ID = "wicketroomid";
 	public static final String PARAM_PUBLIC_SID = "publicSid";
 	public static final String SWF_TYPE_NETWORK = "network";
 	private static final Logger log = Red5LoggerFactory.getLogger(RoomPanel.class, webAppRootKey);
@@ -85,10 +82,6 @@ public class RoomPanel extends BasePanel
 	private final StartSharingEventBehavior startSharing;
 	private Long roomId = null;
 	
-	public RoomPanel(String id) {
-		this(id, new PageParameters());
-	}
-	
 	private static PageParameters addServer(PageParameters pp, Server s) {
 		return pp.add("protocol", s.getProtocol()).add("host", s.getAddress()).add("port", s.getPort()).add("context", s.getWebapp());
 	}
@@ -134,19 +127,8 @@ public class RoomPanel extends BasePanel
 		//OK let's find the room
 		try {
 			StringValue room = pp.get(WICKET_ROOM_ID);
-			StringValue secureHash = pp.get(WebSession.SECURE_HASH);
-			StringValue invitationHash = pp.get(WebSession.INVITATION_HASH);
 			if (!room.isEmpty()) {
 				roomId = room.toLongObject();
-			} else if (!secureHash.isEmpty()) {
-				if (WebSession.get().signIn(secureHash.toString(), false)) {
-					SOAPLogin soapLogin = getBean(SOAPLoginDao.class).get(secureHash.toString());
-					roomId = soapLogin.getRoomId();
-					pp = pp.mergeWith(RoomPanel.addServer(roomId, false));
-				}
-				//TODO access denied
-			} else if (!invitationHash.isEmpty()) {
-				roomId = getBean(InvitationDao.class).getInvitationByHashCode(invitationHash.toString(), true).getRoom().getId();
 			}
 		} catch (Exception e) {
 			//no-op

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java Sun Aug 21 17:20:41 2016
@@ -33,7 +33,6 @@ import java.util.Date;
 import java.util.List;
 
 import org.apache.openmeetings.core.mail.MailHandler;
-import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
 import org.apache.openmeetings.db.dao.room.IInvitationManager;
 import org.apache.openmeetings.db.dao.room.RoomDao;
@@ -243,7 +242,7 @@ public class MessageDialog extends Abstr
 							, CalendarHelper.getDate(start.getModelObject(), to.getTimeZoneId())
 							, CalendarHelper.getDate(end.getModelObject(), to.getTimeZoneId()), null);
 					
-					invitation_link = getInvitationLink(getBean(ConfigurationDao.class).getBaseUrl(), i);
+					invitation_link = getInvitationLink(i);
 
 					if (invitation_link == null) {
 						invitation_link = "";

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingInvitationForm.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingInvitationForm.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingInvitationForm.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingInvitationForm.java Sun Aug 21 17:20:41 2016
@@ -18,12 +18,13 @@
  */
 package org.apache.openmeetings.web.user.record;
 
+import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.web.common.InvitationForm;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 
 public class RecordingInvitationForm extends InvitationForm {
 	private static final long serialVersionUID = 1L;
-	private Long recordingId;
+	private Recording recording;
 
 	public RecordingInvitationForm(String id) {
 		super(id);
@@ -33,11 +34,10 @@ public class RecordingInvitationForm ext
 	@Override
 	public void updateModel(AjaxRequestTarget target) {
 		super.updateModel(target);
-		//Invitation i = getModelObject();
-		//i.setReco
+		getModelObject().setRecording(recording);
 	}
 
-	public void setRecordingId(Long recordingId) {
-		this.recordingId = recordingId;
+	public void setRecording(Recording recording) {
+		this.recording = recording;
 	}
 }

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingResourceReference.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingResourceReference.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingResourceReference.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/RecordingResourceReference.java Sun Aug 21 17:20:41 2016
@@ -63,14 +63,8 @@ public abstract class RecordingResourceR
 		} catch (Exception e) {
 			//no-op expected
 		}
-		WebSession ws = WebSession.get();
-		if (id != null && ws.isSignedIn()) {
+		if (id != null && WebSession.get().isSignedIn()) {
 			return getRecording(id);
-		} else {
-			ws.invalidate();
-			if (ws.signIn(_id.toString(), true)) {
-				return getRecording(getRecordingId());
-			}
 		}
 		return null;
 	}
@@ -81,6 +75,9 @@ public abstract class RecordingResourceR
 		if (r == null || r.getType() == Type.Folder || r.isDeleted()) {
 			return null;
 		}
+		if (id.equals(getRecordingId())) {
+			return r;
+		}
 		//TODO should we check parentId here
 		if (r.getOwnerId() == null && r.getGroupId() == null) {
 			//public

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/record/VideoInfo.java Sun Aug 21 17:20:41 2016
@@ -89,7 +89,7 @@ public class VideoInfo extends Panel {
 
 		@Override
 		protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
-			rif.setRecordingId(rm.getObject().getId());
+			rif.setRecording(rm.getObject());
 			invite.updateModel(target);
 			invite.open(target);
 		}
@@ -226,4 +226,10 @@ public class VideoInfo extends Panel {
 		});
 		return list;
 	}
+
+	public VideoInfo setShowShare(boolean visible) {
+		reConvert.setVisible(visible);
+		share.setVisible(visible);
+		return this;
+	}
 }

Modified: openmeetings/application/branches/3.1.x/openmeetings-webservice/pom.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-webservice/pom.xml?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-webservice/pom.xml (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-webservice/pom.xml Sun Aug 21 17:20:41 2016
@@ -93,6 +93,10 @@
 			<artifactId>cxf-rt-rs-extension-providers</artifactId>
 		</dependency>
 		<dependency>
+			<groupId>org.apache.cxf</groupId>
+			<artifactId>cxf-rt-rs-service-description</artifactId>
+		</dependency>
+		<dependency>
 			<groupId>org.codehaus.jettison</groupId>
 			<artifactId>jettison</artifactId>
 		</dependency>

Modified: openmeetings/application/branches/3.1.x/pom.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/pom.xml?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/pom.xml (original)
+++ openmeetings/application/branches/3.1.x/pom.xml Sun Aug 21 17:20:41 2016
@@ -599,6 +599,11 @@
 				<version>${cxf.version}</version>
 			</dependency>
 			<dependency>
+				<groupId>org.apache.cxf</groupId>
+				<artifactId>cxf-rt-rs-service-description</artifactId>
+				<version>${cxf.version}</version>
+			</dependency>
+			<dependency>
 				<groupId>org.seleniumhq.selenium</groupId>
 				<artifactId>selenium-java</artifactId>
 				<version>${selenium.version}</version>
@@ -653,6 +658,12 @@
 				<version>${tomcat.version}</version>
 				<scope>provided</scope>
 			</dependency>
+			<dependency>
+				<groupId>org.apache.commons</groupId>
+				<artifactId>commons-lang3</artifactId>
+				<version>3.4</version>
+				<scope>provided</scope>
+			</dependency>
 		</dependencies>
 	</dependencyManagement>
 	<dependencies>

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java Sun Aug 21 17:20:41 2016
@@ -37,7 +37,7 @@ public interface IApplication {
 	String getOmString(String key, long languageId);
 	Client updateClient(Client rcl);
 	String getOmContactsLink();
-	String getOmInvitationLink(String baseUrl, Invitation i);
+	String getOmInvitationLink(Invitation i);
 	String urlForActivatePage(PageParameters pp);
 	void invalidateClient(Long userId, String sessionId);
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/InvitationDao.java Sun Aug 21 17:20:41 2016
@@ -18,9 +18,11 @@
  */
 package org.apache.openmeetings.db.dao.room;
 
+import static org.apache.openmeetings.util.CalendarHelper.getZoneId;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 
 import java.util.Date;
+import java.util.List;
 
 import javax.persistence.EntityManager;
 import javax.persistence.NoResultException;
@@ -28,9 +30,12 @@ import javax.persistence.PersistenceCont
 import javax.persistence.TypedQuery;
 
 import org.apache.openmeetings.db.entity.room.Invitation;
+import org.apache.openmeetings.util.CalendarHelper;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.transaction.annotation.Transactional;
+import org.threeten.bp.LocalDateTime;
+import org.threeten.bp.ZonedDateTime;
 
 @Transactional
 public class InvitationDao {
@@ -67,20 +72,35 @@ public class InvitationDao {
 		return null;
 	}
 	
-	public Invitation getInvitationByHashCode(String hashCode, boolean hidePass) {
-		try {
-			
-			TypedQuery<Invitation> query = em.createNamedQuery("getInvitationByHashCode", Invitation.class);
-			query.setParameter("hashCode", hashCode);
-			
-			try {
-				return query.getSingleResult();
-			} catch (NoResultException ex) {
+	public Invitation getByHash(String hash, boolean hidePass, boolean markUsed) {
+		List<Invitation> list = em.createNamedQuery("getInvitationByHashCode", Invitation.class)
+				.setParameter("hashCode", hash).getResultList();
+		Invitation i = list != null && list.size() == 1 ? list.get(0) : null;
+		if (i != null) {
+			switch (i.getValid()) {
+				case OneTime:
+					// one-time invitation
+					i.setAllowEntry(!i.isUsed());
+					if (markUsed) {
+						i.setUsed(true);
+						update(i);
+					}
+					break;
+				case Period:
+					LocalDateTime now = ZonedDateTime.now(getZoneId(i.getInvitee().getTimeZoneId())).toLocalDateTime();
+					LocalDateTime from = CalendarHelper.getDateTime(i.getValidFrom(), i.getInvitee().getTimeZoneId());
+					LocalDateTime to = CalendarHelper.getDateTime(i.getValidTo(), i.getInvitee().getTimeZoneId());
+					i.setAllowEntry(now.isAfter(from) && now.isBefore(to));
+					break;
+				case Endless:
+				default:
+					i.setAllowEntry(true);
+					break;
+			}
+			if (hidePass) {
+				i.setPassword(null);
 			}
-			
-		} catch (Exception e) {
-			log.error("getInvitationByHashCode : ", e);
 		}
-		return null;
+		return i;
 	}
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Invitation.java Sun Aug 21 17:20:41 2016
@@ -39,6 +39,7 @@ import javax.persistence.Transient;
 import org.apache.openjpa.persistence.jdbc.ForeignKey;
 import org.apache.openmeetings.db.entity.IDataProviderEntity;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
+import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.db.entity.user.User;
 
 @Entity
@@ -91,6 +92,11 @@ public class Invitation implements IData
 	@ForeignKey(enabled = true)
 	private Room room;
 
+	@ManyToOne(fetch = FetchType.EAGER)
+	@JoinColumn(name = "recording_id", nullable = true)
+	@ForeignKey(enabled = true)
+	private Recording recording;
+
 	// the hash for the link
 	@Column(name = "hash")
 	private String hash;
@@ -139,6 +145,7 @@ public class Invitation implements IData
 		updated = i.updated;
 		deleted = i.deleted;
 		room = i.room;
+		recording = i.recording;
 		hash = i.hash;
 		invitee = i.invitee;
 		passwordProtected = i.passwordProtected;
@@ -168,6 +175,14 @@ public class Invitation implements IData
 		this.room = room;
 	}
 
+	public Recording getRecording() {
+		return recording;
+	}
+
+	public void setRecording(Recording recording) {
+		this.recording = recording;
+	}
+
 	public User getInvitedBy() {
 		return invitedBy;
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java Sun Aug 21 17:20:41 2016
@@ -31,7 +31,6 @@ import java.util.Vector;
 import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.mail.MailHandler;
 import org.apache.openmeetings.core.mail.SMSHandler;
-import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.room.IInvitationManager;
 import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.entity.basic.MailMessage;
@@ -76,8 +75,6 @@ public class InvitationManager implement
 	private SMSHandler smsHandler;
 	@Autowired
 	private TimezoneUtil timezoneUtil;
-	@Autowired
-	private ConfigurationDao configDao;
 
 	/**
 	 * @author vasya
@@ -115,7 +112,7 @@ public class InvitationManager implement
 		String invitation_link = null;
 		if (type != MessageType.Cancel) {
 			IApplication app = ensureApplication(1L);
-			invitation_link = app.getOmInvitationLink(configDao.getBaseUrl(), i);
+			invitation_link = app.getOmInvitationLink(i);
 		}
 		User owner = i.getInvitedBy();
 		
@@ -186,7 +183,7 @@ public class InvitationManager implement
 	public Object getInvitationByHashCode(String hashCode, boolean hidePass) {
 		try {
 			log.debug("Invitation was requested by hashcode: " + hashCode);
-			Invitation i = invitationDao.getInvitationByHashCode(hashCode, hidePass);
+			Invitation i = invitationDao.getByHash(hashCode, hidePass, true);
 
 			if (i == null) {
 				// already deleted or does not exist
@@ -196,48 +193,15 @@ public class InvitationManager implement
 					case OneTime:
 						// do this only if the user tries to get the Invitation, not
 						// while checking the PWD
-						if (hidePass) {
-							// one-time invitation
-							if (i.isUsed()) {
-								// Invitation is of type *only-one-time* and was
-								// already used
-								return new Long(-32);
-							} else {
-								// set to true if this is the first time / a normal
-								// getInvitation-Query
-								i.setUsed(true);
-								invitationDao.update(i);
-								// invitation.setInvitationpass(null);
-								i.setAllowEntry(true);
-							}
-						} else {
-							i.setAllowEntry(true);
+						if (!i.isAllowEntry()) {
+							// Invitation is of type *only-one-time* and was
+							// already used
+							return new Long(-32);
 						}
 						break;
 					case Period:
-						LocalDateTime now = ZonedDateTime.now(getZoneId(i.getInvitee().getTimeZoneId())).toLocalDateTime();
-						LocalDateTime from = CalendarHelper.getDateTime(i.getValidFrom(), i.getInvitee().getTimeZoneId());
-						LocalDateTime to = CalendarHelper.getDateTime(i.getValidTo(), i.getInvitee().getTimeZoneId());
-						if (now.isAfter(from) && now.isBefore(to)) {
-							invitationDao.update(i);
-							// invitation.setInvitationpass(null);
-							i.setAllowEntry(true);
-						} else {
-
-							// Invitation is of type *period* and is not valid
-							// anymore, this is an extra hook to display the time
-							// correctly
-							// in the method where it shows that the hash code does
-							// not work anymore
-							i.setAllowEntry(false);
-						}
-						break;
 					case Endless:
 					default:
-						invitationDao.update(i);
-
-						i.setAllowEntry(true);
-						// invitation.setInvitationpass(null);
 						break;
 				}
 				return i;

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/pom.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/pom.xml?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/pom.xml (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/pom.xml Sun Aug 21 17:20:41 2016
@@ -656,6 +656,10 @@
 				</exclusion>
 			</exclusions>
 		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+		</dependency>
 		<!-- Test dependencies -->
 		<dependency>
 			<groupId>org.seleniumhq.selenium</groupId>

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java Sun Aug 21 17:20:41 2016
@@ -40,6 +40,7 @@ import org.apache.wicket.model.Model;
 import org.apache.wicket.util.time.Duration;
 import org.apache.wicket.validation.IValidatable;
 import org.apache.wicket.validation.IValidator;
+import org.apache.wicket.validation.ValidationError;
 
 /**
  * Handle {@link Configuration} items as list and form
@@ -67,7 +68,7 @@ public class ConfigForm extends AdminBas
 			public void validate(IValidatable<String> validatable) {
 				Configuration c = getBean(ConfigurationDao.class).forceGet(validatable.getValue());
 				if (c != null && !c.isDeleted() && !c.getId().equals(ConfigForm.this.getModelObject().getId())) {
-					error(Application.getString(1544L));
+					validatable.error(new ValidationError(Application.getString(1544L)));
 				}
 			}
 		}));

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1757068&r1=1757067&r2=1757068&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Sun Aug 21 17:20:41 2016
@@ -24,6 +24,7 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.util.OmUrlFragment.PROFILE_MESSAGES;
 import static org.red5.logging.Red5LoggerFactory.getLogger;
 import static org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext;
+import static org.apache.openmeetings.web.app.WebSession.INVITATION_HASH;
 
 import java.text.MessageFormat;
 import java.util.ArrayList;
@@ -145,6 +146,7 @@ public class Application extends Authent
 		mountPage("activate", ActivatePage.class);
 		mountPage("reset", ResetPage.class);
 		mountPage("/recording/${hash}", RecordingPage.class);
+		mountPage("/recording", RecordingPage.class);
 		mountResource("/recordings/avi/${id}", new AviRecordingResourceReference());
 		mountResource("/recordings/flv/${id}", new FlvRecordingResourceReference());
 		mountResource("/recordings/mp4/${id}", new Mp4RecordingResourceReference());
@@ -451,11 +453,8 @@ public class Application extends Authent
 		return getContactsLink();
 	}
 
-	public static String getInvitationLink(String baseUrl, Invitation i) {
-		String link = baseUrl;
-		if (link == null) {
-			return null;
-		}
+	public static String getInvitationLink(Invitation i) {
+		String link = "";
 		Room r = i.getRoom();
 		User u = i.getInvitee();
 		if (r != null) {
@@ -464,21 +463,26 @@ public class Application extends Authent
 				allowed = getBean(MainService.class).isRoomAllowedToUser(r, u);
 			}
 			if (!allowed) {
-				link += "?invitationHash=" + i.getHash();
-		
+				PageParameters pp = new PageParameters();
+				pp.add(INVITATION_HASH, i.getHash());
 				if (u.getLanguageId() > 0) {
-					link += "&language=" + u.getLanguageId();
+					pp.add("language", u.getLanguageId());
 				}
+				link = urlForPage(MainPage.class, pp);
 			} else {
 				link = getRoomUrlFragment(r.getId()).getLink();
 			}
 		}
+		Recording rec = i.getRecording();
+		if (rec != null) {
+			link = urlForPage(RecordingPage.class, new PageParameters().add(INVITATION_HASH, i.getHash()));
+		}
 		return link;
 	}
 	
 	@Override
-	public String getOmInvitationLink(String baseUrl, Invitation i) { //FIXME hack for email templates support (should be in separate module for now
-		return getInvitationLink(baseUrl, i);
+	public String getOmInvitationLink(Invitation i) { //FIXME hack for email templates support (should be in separate module for now
+		return getInvitationLink(i);
 	}
 	
 	public static String urlForPage(Class<? extends Page> clazz, PageParameters pp) {