Skip to content
Snippets Groups Projects
Commit 84908f97 authored by srosse's avatar srosse
Browse files

OO-2452: implement reset of password with SMS confirmation / authentication

parent b4ed2c86
No related branches found
No related tags found
No related merge requests found
Showing
with 1666 additions and 4 deletions
......@@ -34,7 +34,7 @@ import org.olat.core.id.Identity;
import org.olat.core.id.User;
import org.olat.core.util.Util;
import org.olat.registration.RegistrationManager;
import org.olat.registration.TemporaryKeyImpl;
import org.olat.registration.TemporaryKey;
import org.olat.user.ProfileAndHomePageEditController;
import org.olat.user.UserManager;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -56,7 +56,7 @@ public class ChangeEMailController extends DefaultController {
protected Translator pT;
protected String emKey;
protected TemporaryKeyImpl tempKey;
protected TemporaryKey tempKey;
protected UserRequest userRequest;
@Autowired
......
......@@ -65,7 +65,7 @@ import org.olat.core.util.mail.MailerResult;
import org.olat.properties.Property;
import org.olat.properties.PropertyManager;
import org.olat.registration.RegistrationManager;
import org.olat.registration.TemporaryKeyImpl;
import org.olat.registration.TemporaryKey;
import org.olat.repository.RepositoryDeletionModule;
import org.olat.user.UserDataDeletable;
import org.olat.user.UserManager;
......@@ -294,7 +294,7 @@ public class UserDeletionManager extends BasicManager {
groupDao.removeMemberships(identity);
String key = identity.getUser().getProperty("emchangeKey", null);
TemporaryKeyImpl tempKey = registrationManager.loadTemporaryKeyByRegistrationKey(key);
TemporaryKey tempKey = registrationManager.loadTemporaryKeyByRegistrationKey(key);
if (tempKey != null) {
registrationManager.deleteTemporaryKey(tempKey);
}
......
......@@ -12,6 +12,7 @@
<import resource="classpath:/org/olat/core/commons/services/scheduler/_spring/schedulerContext.xml"/>
<import resource="classpath:/org/olat/core/commons/services/taskexecutor/_spring/taskExecutorCorecontext.xml"/>
<import resource="classpath:/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml"/>
<import resource="classpath:/org/olat/core/commons/services/sms/_spring/smsCorecontext.xml"/>
<bean id="imageHelper" class="org.olat.core.commons.services.image.ImageHelperBean">
<property name="imageHelperServiceProvider" ref="imageHelperServiceProvider_${thumbnail.provider}"/>
......@@ -34,4 +35,5 @@
</list>
</property>
</bean>
</beans>
\ No newline at end of file
/**
* <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.core.commons.services.sms;
import java.util.Date;
import org.olat.core.id.Identity;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public interface MessageLog {
public Long getKey();
public Date getCreationDate();
/**
* The unique identifier of this message.
*
* @return The uuid
*/
public String getMessageUuid();
/**
* The ID of the service provider.
*
* @return The Id of the service provider
*/
public String getServiceId();
public void setServiceId(String serviceId);
/**
* Informations about the status of the message sent.
*
* @return A string
*/
public String getServerResponse();
public void setServerResponse(String response);
/**
* The recipient of the message.
*
* @return
*/
public Identity getRecipient();
}
/**
* <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.core.commons.services.sms;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public interface MessagesSPI {
public String getId();
public String getName();
public boolean isValid();
public boolean send(String messageId, String text, String recipient) throws SimpleMessageException;
}
package org.olat.core.commons.services.sms;
/**
*
* Initial date: 7 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class SimpleMessageException extends Exception {
private static final long serialVersionUID = 787789477989775426L;
private final ErrorCode code;
public SimpleMessageException(Exception cause, ErrorCode code) {
super(cause);
this.code = code;
}
public ErrorCode getErrorCode() {
return code;
}
public enum ErrorCode {
numberNotValid,
}
}
/**
* <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.core.commons.services.sms;
import java.util.List;
import org.olat.core.configuration.AbstractSpringModule;
import org.olat.core.configuration.ConfigOnOff;
import org.olat.core.id.UserConstants;
import org.olat.core.util.StringHelper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.user.propertyhandlers.UserPropertyHandler;
import org.olat.user.propertyhandlers.UserPropertyUsageContext;
import org.olat.user.propertyhandlers.ui.UsrPropCfgManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
@Service
public class SimpleMessageModule extends AbstractSpringModule implements ConfigOnOff {
public static final String SMS_ENABLED = "message.enabled";
public static final String RESET_PASSWORD_ENABLED = "message.reset.password.enabled";
@Value("${message.enabled:false}")
private boolean enabled;
@Value("${message.reset.password.enabled:true}")
private boolean resetPassword;
@Autowired
private UsrPropCfgManager usrPropCfgMng;
@Autowired
public SimpleMessageModule(CoordinatorManager coordinatorManager) {
super(coordinatorManager);
}
@Override
public void init() {
String enabledObj = getStringPropertyValue(SMS_ENABLED, true);
if(StringHelper.containsNonWhitespace(enabledObj)) {
enabled = "true".equals(enabledObj);
}
String resetPasswordEnabledObj = getStringPropertyValue(RESET_PASSWORD_ENABLED, true);
if(StringHelper.containsNonWhitespace(resetPasswordEnabledObj)) {
resetPassword = "true".equals(resetPasswordEnabledObj);
}
if(enabled) {//check
enableSmsUserProperty();
}
}
@Override
protected void initFromChangedProperties() {
init();
}
@Override
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
setStringProperty(SMS_ENABLED, Boolean.toString(enabled), true);
}
private void enableSmsUserProperty() {
List<UserPropertyHandler> handlers = usrPropCfgMng.getUserPropertiesConfigObject().getPropertyHandlers();
UserPropertyHandler smsHandler = null;
UserPropertyHandler mobileHandler = null;
for(UserPropertyHandler handler:handlers) {
if(UserConstants.SMSTELMOBILE.equals(handler.getName())) {
smsHandler = handler;
} else if(UserConstants.TELMOBILE.equals(handler.getName())) {
mobileHandler = handler;
}
}
if(smsHandler != null) {
UserPropertyUsageContext context = usrPropCfgMng.getUserPropertiesConfigObject()
.getUsageContexts().get("org.olat.user.ProfileFormController");
if(!context.contains(smsHandler)) {
if(mobileHandler == null) {
context.addPropertyHandler(smsHandler);
} else {
int index = context.getPropertyHandlers().indexOf(mobileHandler);
context.addPropertyHandler(index + 1, smsHandler);
}
}
}
}
public boolean isResetPasswordEnabled() {
return resetPassword;
}
public void setResetPasswordEnabled(boolean resetPassword) {
this.resetPassword = resetPassword;
setStringProperty(RESET_PASSWORD_ENABLED, Boolean.toString(resetPassword), true);
}
}
/**
* <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.core.commons.services.sms;
import java.util.List;
import org.olat.core.commons.services.sms.model.MessageStatistics;
import org.olat.core.id.Identity;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public interface SimpleMessageService {
/**
* @return A six digits token random generated.
*/
public String generateToken();
/**
* A method to validate the phone number.
*
* @param number The phone number
* @return true if the service can send a message with the specified number.
*/
public boolean validate(String number);
/**
* The list of service providers registered in the system.
*
* @return A list of service providers.
*/
public List<MessagesSPI> getMessagesSpiList();
/**
* Return the active messages service provider.
*
* @return A message service provider
*/
public MessagesSPI getMessagesSpi();
/**
* Return the message service provider identified by its id.
*
* @param serviceId The id of the desired service provider.
* @return A message service provider or null
*/
public MessagesSPI getMessagesSpi(String serviceId);
public void sendMessage(String text, Identity recipient) throws SimpleMessageException;
public void sendMessage(String text, String phone, Identity recipient) throws SimpleMessageException;
public List<MessageStatistics> getStatisticsPerMonth();
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="smsTelMobile.AfterLogin.Injection" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="afterLoginInterceptionManager" />
<property name="targetMethod" value="addAfterLoginControllerConfig" />
<property name="arguments">
<ref bean="smsTelMobile.AfterLoginConfig"/>
</property>
</bean>
<bean id="smsTelMobile.AfterLoginConfig" class="org.olat.login.AfterLoginConfig">
<property name="afterLoginControllerList">
<list>
<map>
<entry key="controller">
<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
<property name="className" value="org.olat.core.commons.services.sms.ui.SMSPhoneController"/>
</bean>
</entry>
<entry key="forceUser"><value>false</value></entry>
<entry key="redoTimeout"><value>0</value></entry>
<entry key="i18nIntro"><value>org.olat.core.commons.services.sms.ui:confirm.sms.phone</value></entry>
<entry key="order"><value>0</value></entry>
<!-- 31536000 = 60 * 60 * 24 * 365 (or a year in seconds) -->
<entry key="redoTimeout"><value>31536000</value></entry>
</map>
</list>
</property>
</bean>
<bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
<property name="order" value="8835" />
<property name="actionController">
<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
<property name="className" value="org.olat.core.commons.services.sms.ui.SimpleMessageServiceAdminController"/>
</bean>
</property>
<property name="navigationKey" value="smsAdmin" />
<property name="i18nActionKey" value="admin.menu.title"/>
<property name="i18nDescriptionKey" value="admin.menu.title.alt"/>
<property name="translationPackage" value="org.olat.core.commons.services.sms.ui"/>
<property name="parentTreeNodeIdentifier" value="loginAndSecurityParent" />
<property name="extensionPoints">
<list>
<value>org.olat.admin.SystemAdminMainController</value>
</list>
</property>
</bean>
</beans>
\ No newline at end of file
/**
* <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.core.commons.services.sms.manager;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.olat.core.commons.persistence.DB;
import org.olat.core.commons.persistence.PersistenceHelper;
import org.olat.core.commons.services.sms.MessageLog;
import org.olat.core.commons.services.sms.model.MessageLogImpl;
import org.olat.core.commons.services.sms.model.MessageStatistics;
import org.olat.core.id.Identity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
@Service
public class MessageLogDAO {
@Autowired
private DB dbInstance;
/**
* Create a transient log entry.
*
* @param recipient
* @return The log entry
*/
public MessageLog create(Identity recipient, String serviceId) {
MessageLogImpl log = new MessageLogImpl();
log.setCreationDate(new Date());
log.setLastModified(log.getCreationDate());
log.setMessageUuid(UUID.randomUUID().toString());
log.setServiceId(serviceId);
log.setRecipient(recipient);
dbInstance.getCurrentEntityManager().persist(log);
return log;
}
public MessageLog save(MessageLog log) {
MessageLog mergedLog;
if(log.getKey() == null) {
dbInstance.getCurrentEntityManager().persist(log);
mergedLog = log;
} else {
((MessageLogImpl)log).setLastModified(new Date());
mergedLog = dbInstance.getCurrentEntityManager().merge(log);
}
return mergedLog;
}
public MessageLog loadMessageByKey(Long key) {
StringBuilder sb = new StringBuilder();
sb.append("select mlog from smsmessagelog mlog where mlog.key=:messageKey");
List<MessageLog> mLogs = dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), MessageLog.class)
.setParameter("messageKey", key)
.getResultList();
return mLogs == null || mLogs.isEmpty() ? null : mLogs.get(0);
}
public List<MessageStatistics> getStatisticsPerMonth(String serviceId) {
StringBuilder sb = new StringBuilder();
sb.append("select count(mlog.key) as numOfMessages, month(mlog.creationDate) as month, year(mlog.creationDate) as year")
.append(" from smsmessagelog mlog")
.append(" where mlog.serviceId=:serviceId")
.append(" group by month(mlog.creationDate), year(mlog.creationDate)");
List<Object[]> objects = dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Object[].class)
.setParameter("serviceId", serviceId)
.getResultList();
Calendar cal = Calendar.getInstance();
List<MessageStatistics> stats = new ArrayList<>(objects.size());
for(Object[] object:objects) {
int pos = 0;
Long numOfMessages = PersistenceHelper.extractLong(object, pos++);
Long month = PersistenceHelper.extractLong(object, pos++);
Long year = PersistenceHelper.extractLong(object, pos++);
if(numOfMessages != null) {
cal.set(Calendar.YEAR, year.intValue());
cal.set(Calendar.MONTH, month.intValue() - 1);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date date = cal.getTime();
stats.add(new MessageStatistics(serviceId, date, numOfMessages));
}
}
return stats;
}
}
\ No newline at end of file
/**
* <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.core.commons.services.sms.manager;
import java.util.List;
import java.util.Random;
import org.olat.core.commons.services.sms.MessageLog;
import org.olat.core.commons.services.sms.MessagesSPI;
import org.olat.core.commons.services.sms.SimpleMessageException;
import org.olat.core.commons.services.sms.SimpleMessageModule;
import org.olat.core.commons.services.sms.SimpleMessageService;
import org.olat.core.commons.services.sms.model.MessageStatistics;
import org.olat.core.helpers.Settings;
import org.olat.core.id.Identity;
import org.olat.core.id.UserConstants;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.StringHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
@Service
public class SimpleMessageServiceImpl implements SimpleMessageService {
private static final OLog log = Tracing.createLoggerFor(SimpleMessageServiceImpl.class);
private static final Random rnd = new Random();
@Autowired
private MessageLogDAO messageLogDao;
@Autowired
private SimpleMessageModule messageModule;
@Autowired
private List<MessagesSPI> messagesSpiList;
@Override
public List<MessagesSPI> getMessagesSpiList() {
return messagesSpiList;
}
@Override
public String generateToken() {
StringBuilder sb = new StringBuilder();
for(int i=0; i<6; i++) {
int n = Math.round(rnd.nextFloat() * 9.0f);
if(n < 0) {
n = 0;
} else if(n > 9) {
n = 9;
}
sb.append(n);
}
return sb.toString();
}
@Override
public boolean validate(String number) {
if(!StringHelper.containsNonWhitespace(number)) return false;
number = number.replace("+", "").replace(" ", "");
if(StringHelper.isLong(number)) {
try {
Long phone = new Long(number);
return phone > 0;
} catch (NumberFormatException e) {
//
}
}
return false;
}
@Override
public void sendMessage(String text, Identity recipient) throws SimpleMessageException {
String telNumber = recipient.getUser().getProperty(UserConstants.SMSTELMOBILE, null);
sendMessage(text, telNumber, recipient);
}
@Override
public void sendMessage(String text, String telNumber, Identity recipient) throws SimpleMessageException {
MessagesSPI spi = getMessagesSpi();
MessageLog mLog = messageLogDao.create(recipient, spi.getId());
boolean allOk = spi.send(mLog.getMessageUuid(), text, telNumber);
mLog.setServerResponse(Boolean.toString(allOk));
messageLogDao.save(mLog);
log.audit("SMS send: " + allOk + " to " + recipient + " with number: " + telNumber);
}
@Override
public List<MessageStatistics> getStatisticsPerMonth() {
MessagesSPI selectedSpi = getMessagesSpi();
return messageLogDao.getStatisticsPerMonth(selectedSpi.getId());
}
@Override
public MessagesSPI getMessagesSpi(String serviceId) {
MessagesSPI spi = null;
if("devnull".equals(serviceId)) {
spi = new DevNullProvider();
} else if(messagesSpiList != null) {
for(MessagesSPI mSpi:messagesSpiList) {
if(mSpi.getId().equals(serviceId)) {
spi = mSpi;
}
}
}
return spi;
}
@Override
public MessagesSPI getMessagesSpi() {
if(Settings.isDebuging()) return new DevNullProvider();
if(messageModule.isEnabled() && messagesSpiList.size() > 0) {
return messagesSpiList.get(0);
}
return new DevNullProvider();
}
private static class DevNullProvider implements MessagesSPI {
@Override
public String getId() {
return "devnull";
}
@Override
public String getName() {
return "/dev/null";
}
@Override
public boolean isValid() {
return true;
}
@Override
public boolean send(String messageId, String text, String recipient) {
log.info("Send: " + text);
return true;
}
}
}
\ No newline at end of file
/**
* <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.core.commons.services.sms.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
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.olat.basesecurity.IdentityImpl;
import org.olat.core.commons.services.sms.MessageLog;
import org.olat.core.id.CreateInfo;
import org.olat.core.id.Identity;
import org.olat.core.id.ModifiedInfo;
import org.olat.core.id.Persistable;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
@Entity(name="smsmessagelog")
@Table(name="o_sms_message_log")
public class MessageLogImpl implements Persistable, ModifiedInfo, CreateInfo, MessageLog {
private static final long serialVersionUID = 2605977680881759364L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@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;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="lastmodified", nullable=false, insertable=true, updatable=true)
private Date lastModified;
@Column(name="s_message_uuid", nullable=false, insertable=true, updatable=false)
private String messageUuid;
@Column(name="s_server_response", nullable=true, insertable=true, updatable=false)
private String serverResponse;
@Column(name="s_service_id", nullable=false, insertable=true, updatable=false)
private String serviceId;
@ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=false)
@JoinColumn(name="fk_identity", nullable=true, insertable=true, updatable=false)
private Identity recipient;
@Override
public Long getKey() {
return key;
}
public void setKey(Long key) {
this.key = key;
}
@Override
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
@Override
public Date getLastModified() {
return lastModified;
}
@Override
public void setLastModified(Date date) {
lastModified = date;
}
public String getMessageUuid() {
return messageUuid;
}
public void setMessageUuid(String messageUuid) {
this.messageUuid = messageUuid;
}
public String getServerResponse() {
return serverResponse;
}
public void setServerResponse(String serverResponse) {
this.serverResponse = serverResponse;
}
public String getServiceId() {
return serviceId;
}
public void setServiceId(String serviceId) {
this.serviceId = serviceId;
}
public Identity getRecipient() {
return recipient;
}
public void setRecipient(Identity recipient) {
this.recipient = recipient;
}
@Override
public int hashCode() {
return key == null ? 349857 : key.hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj == this) {
return true;
}
if(obj instanceof MessageLogImpl) {
MessageLogImpl log = (MessageLogImpl)obj;
return key != null && key.equals(log.key);
}
return false;
}
@Override
public boolean equalsByPersistableKey(Persistable persistable) {
return equals(persistable);
}
}
\ No newline at end of file
package org.olat.core.commons.services.sms.model;
import java.util.Date;
/**
*
* Initial date: 7 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class MessageStatistics {
private final Date date;
private final String service;
private final long numOfMessages;
public MessageStatistics(String service, Date date, long numOfMessages) {
this.service = service;
this.date = date;
this.numOfMessages = numOfMessages;
}
public Date getDate() {
return date;
}
public String getService() {
return service;
}
public long getNumOfMessages() {
return numOfMessages;
}
}
/**
* <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.core.commons.services.sms.spi;
import org.apache.http.HttpEntity;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.olat.core.commons.services.sms.MessagesSPI;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.StringHelper;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* Implementation for https://websms.ch
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
@Service("messagesSpiWebSMS")
public class WebSMSProvider implements MessagesSPI, InitializingBean {
private static final OLog log = Tracing.createLoggerFor(WebSMSProvider.class);
private final BasicCredentialsProvider provider = new BasicCredentialsProvider();
@Value("${websms.url:https://api.websms.com/rest/smsmessaging/text}")
private String url;
@Value("${websms.username:}")
private String username;
@Value("${websms.password:}")
private String password;
private boolean test = false;
/**
* Method means for unit tests. The changes are not persisted.
*
* @param username
* @param password
*/
protected void setCredentials(String username, String password) {
this.username = username;
this.password = password;
provider.setCredentials(new AuthScope("api.websms.com", 443),
new UsernamePasswordCredentials(username, password));
}
protected void setTest(boolean test) {
this.test = test;
}
@Override
public String getId() {
return "websms";
}
@Override
public String getName() {
return "WebSMS";
}
@Override
public boolean isValid() {
return StringHelper.containsNonWhitespace(username) && StringHelper.containsNonWhitespace(password);
}
@Override
public void afterPropertiesSet() throws Exception {
provider.setCredentials(new AuthScope("api.websms.com", 443),
new UsernamePasswordCredentials(username, password));
}
@Override
public boolean send(String messageId, String text, String recipient) {
HttpPost send = new HttpPost(url);
try(CloseableHttpClient httpclient = HttpClientBuilder.create()
.setDefaultCredentialsProvider(provider)
.build()) {
String phone = recipient.replace("+", "").replace(" ", "");
String objectStr = jsonPayload(messageId, text, new Long(phone));
HttpEntity smsEntity = new StringEntity(objectStr, ContentType.APPLICATION_JSON);
send.setEntity(smsEntity);
CloseableHttpResponse response = httpclient.execute(send);
int returnCode = response.getStatusLine().getStatusCode();
String responseString = EntityUtils.toString(response.getEntity());
if(returnCode == 200 || returnCode >= 2000) {
return true;
}
log.error("WebSMS return an error code " + returnCode + ": " + responseString);
return false;
} catch(Exception e) {
log.error("", e);
return false;
}
}
/**
* {
* "userDataHeaderPresent" : false,
* "messageContent" : [ "...", ... ],
* "test" : false,
* "recipientAddressList" : [ ..., ... ],
* "senderAddress" : "...",
* "senderAddressType" : "national",
* "sendAsFlashSms" : false,
* "notificationCallbackUrl" : "...",
* "clientMessageId" : "...",
* "priority" : ...,
* }
* @param obj
* @return
*/
private String jsonPayload(String messageId, String text, Long recipient) {
try {
JSONObject message = new JSONObject();
message.put("userDataHeaderPresent", false);
message.put("messageContent", text);
message.put("test", test);
JSONArray recipients = new JSONArray();
recipients.put(recipient);
message.put("recipientAddressList", recipients);//arrsx
//optional message.put("senderAddress", "");
//optional message.put("senderAddressType", "national");
//optional message.put("sendAsFlashSms", false);
//optional message.put("senderAddress", "");//national international shortcode alphanumeric
//optional message.put("notificationCallbackUrl", "");
message.put("clientMessageId", messageId);
//optional message.put("priority", false);
return message.toString();
} catch (Exception e) {
log.error("", e);
return null;
}
}
}
package org.olat.core.commons.services.sms.ui;
import java.util.List;
import java.util.Locale;
import org.olat.core.commons.persistence.SortKey;
import org.olat.core.commons.services.sms.model.MessageStatistics;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate;
/**
*
* Initial date: 7 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class MessageStatisticsDataModel extends DefaultFlexiTableDataModel<MessageStatistics>
implements SortableFlexiTableDataModel<MessageStatistics> {
private final Locale locale;
public MessageStatisticsDataModel(FlexiTableColumnModel columnModel, Locale locale) {
super(columnModel);
this.locale = locale;
}
@Override
public void sort(SortKey orderBy) {
if(orderBy != null) {
SortableFlexiTableModelDelegate<MessageStatistics> sorter = new SortableFlexiTableModelDelegate<>(orderBy, this, locale);
List<MessageStatistics> stats = sorter.sort();
super.setObjects(stats);
}
}
@Override
public Object getValueAt(int row, int col) {
MessageStatistics infos = getObject(row);
return getValueAt(infos, col);
}
@Override
public Object getValueAt(MessageStatistics row, int col) {
switch(MLogStatsCols.values()[col]) {
case year:
case month: return row.getDate();
case numOfMessages: return row.getNumOfMessages();
default: return null;
}
}
@Override
public DefaultFlexiTableDataModel<MessageStatistics> createCopyWithEmptyList() {
return new MessageStatisticsDataModel(getTableColumnModel(), locale);
}
public enum MLogStatsCols implements FlexiSortableColumnDef {
year("table.header.year"),
month("table.header.month"),
numOfMessages("table.header.numOfMessages");
private final String i18nKey;
private MLogStatsCols(String i18nKey) {
this.i18nKey = i18nKey;
}
@Override
public String i18nHeaderKey() {
return i18nKey;
}
@Override
public boolean sortable() {
return true;
}
@Override
public String sortKey() {
return name();
}
}
}
\ No newline at end of file
/**
* <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.core.commons.services.sms.ui;
import java.util.List;
import org.olat.core.commons.services.sms.SimpleMessageService;
import org.olat.core.commons.services.sms.model.MessageStatistics;
import org.olat.core.commons.services.sms.ui.MessageStatisticsDataModel.MLogStatsCols;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class MessagesStatisticsController extends FormBasicController {
private FlexiTableElement tableEl;
private MessageStatisticsDataModel model;
@Autowired
private SimpleMessageService messageService;
public MessagesStatisticsController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl, "statistics");
initForm(ureq);
loadModel();
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
DefaultFlexiColumnModel yearColumn = new DefaultFlexiColumnModel(MLogStatsCols.year, new YearCellRenderer());
yearColumn.setExportable(false);
columnsModel.addFlexiColumnModel(yearColumn);
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(MLogStatsCols.month, new MonthCellRenderer(getLocale())));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(MLogStatsCols.numOfMessages));
model = new MessageStatisticsDataModel(columnsModel, getLocale());
tableEl = uifactory.addTableElement(getWindowControl(), "stats", model, 50, false, getTranslator(), formLayout);
tableEl.setCustomizeColumns(false);
tableEl.setExportEnabled(true);
}
private void loadModel() {
List<MessageStatistics> stats = messageService.getStatisticsPerMonth();
model.setObjects(stats);
tableEl.reset(true, true, true);
}
@Override
protected void doDispose() {
//
}
@Override
protected void formOK(UserRequest ureq) {
//
}
}
package org.olat.core.commons.services.sms.ui;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
import org.olat.core.gui.render.Renderer;
import org.olat.core.gui.render.StringOutput;
import org.olat.core.gui.render.URLBuilder;
import org.olat.core.gui.translator.Translator;
/**
*
* Initial date: 7 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class MonthCellRenderer implements FlexiCellRenderer {
private final SimpleDateFormat format;
public MonthCellRenderer(Locale locale) {
format = new SimpleDateFormat("MMMM", locale);
}
@Override
public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source,
URLBuilder ubu, Translator translator) {
if(cellValue instanceof Date) {
target.append(format.format((Date)cellValue));
}
}
}
/**
* <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.core.commons.services.sms.ui;
import org.olat.core.commons.services.sms.SimpleMessageException;
import org.olat.core.commons.services.sms.SimpleMessageModule;
import org.olat.core.commons.services.sms.SimpleMessageService;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.elements.TextElement;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.id.User;
import org.olat.core.id.UserConstants;
import org.olat.core.util.StringHelper;
import org.olat.login.SupportsAfterLoginInterceptor;
import org.olat.user.UserManager;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class SMSPhoneController extends FormBasicController implements SupportsAfterLoginInterceptor {
private FormLink dontActivateButton;
private TextElement phoneEl, tokenEl;
private String sentToken;
@Autowired
private UserManager userManager;
@Autowired
private SimpleMessageModule messageModule;
@Autowired
private SimpleMessageService messageService;
public SMSPhoneController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl);
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
phoneEl = uifactory.addTextElement("sms.phone.number", "sms.phone.number", 32, "", formLayout);
phoneEl.setPlaceholderKey("sms.phone.number.hint", null);
tokenEl = uifactory.addTextElement("sms.token.number", "sms.token.number", 16, "", formLayout);
tokenEl.setExampleKey("sms.token.number.explain", null);
tokenEl.setVisible(false);
FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
formLayout.add(buttonsCont);
uifactory.addFormSubmitButton("save", buttonsCont);
dontActivateButton = uifactory.addFormLink("dont.activate", buttonsCont, Link.BUTTON);
}
@Override
protected void doDispose() {
//
}
@Override
public boolean isUserInteractionRequired(UserRequest ureq) {
return messageModule.isEnabled() && messageModule.isResetPasswordEnabled()
&& !ureq.getUserSession().getRoles().isGuestOnly()
&& !messageService.validate(ureq.getIdentity().getUser().getProperty(UserConstants.SMSTELMOBILE, getLocale()));
}
@Override
protected boolean validateFormLogic(UserRequest ureq) {
boolean allOk = true;
phoneEl.clearError();
if(phoneEl.isVisible()) {
if(!StringHelper.containsNonWhitespace(phoneEl.getValue())) {
phoneEl.setErrorKey("form.legende.mandatory", null);
allOk &= false;
} else if(!messageService.validate(phoneEl.getValue())) {
phoneEl.setErrorKey("error.phone.invalid", null);
allOk &= false;
}
}
tokenEl.clearError();
if(tokenEl.isVisible()) {
String tokenValue = tokenEl.getValue();
if(!StringHelper.containsNonWhitespace(tokenValue)) {
tokenEl.setErrorKey("form.legende.mandatory", null);
allOk &= false;
} else if(sentToken == null || !sentToken.equals(tokenValue)) {
tokenEl.setErrorKey("error.invalid.token", null);
allOk &= false;
}
}
return allOk &= super.validateFormLogic(ureq);
}
@Override
protected void formOK(UserRequest ureq) {
if(phoneEl.isVisible()) {
try {
phoneEl.setVisible(false);
tokenEl.setVisible(true);
sentToken = messageService.generateToken();
String msg = translate("sms.token", new String[]{ sentToken });
messageService.sendMessage(msg, phoneEl.getValue(), getIdentity());
} catch (SimpleMessageException e) {
phoneEl.setVisible(true);
tokenEl.setVisible(false);
phoneEl.setErrorKey("error.phone.invalid", null);
}
} else if(tokenEl.isVisible()) {
User user = getIdentity().getUser();
user.setProperty(UserConstants.SMSTELMOBILE, phoneEl.getValue());
userManager.updateUserFromIdentity(getIdentity());
fireEvent(ureq, Event.DONE_EVENT);
}
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(source == dontActivateButton) {
fireEvent(ureq, Event.DONE_EVENT);
}
super.formInnerEvent(ureq, source, event);
}
}
\ No newline at end of file
/**
* <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.core.commons.services.sms.ui;
import java.util.List;
import org.olat.core.commons.services.sms.MessagesSPI;
import org.olat.core.commons.services.sms.SimpleMessageModule;
import org.olat.core.commons.services.sms.SimpleMessageService;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class SimpleMessageServiceAdminConfigurationController extends FormBasicController {
private static final String[] onKeys = new String[]{ "on" };
private SingleSelection serviceEl;
private MultipleSelectionElement enableEl;
private MultipleSelectionElement resetPasswordEl;
@Autowired
private SimpleMessageModule messageModule;
@Autowired
private SimpleMessageService messagesService;
public SimpleMessageServiceAdminConfigurationController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl);
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
setFormTitle("admin.configuration.title");
setFormDescription("admin.configuration.description");
String[] onValues = new String[]{ translate("on") };
enableEl = uifactory.addCheckboxesHorizontal("enable", "admin.enable", formLayout, onKeys, onValues);
enableEl.addActionListener(FormEvent.ONCHANGE);
if(messageModule.isEnabled()) {
enableEl.select(onKeys[0], true);
}
List<MessagesSPI> spies = messagesService.getMessagesSpiList();
String[] serviceKeys = new String[spies.size()];
String[] serviceValues = new String[spies.size()];
for(int i=spies.size(); i-->0; ) {
serviceKeys[i] = spies.get(i).getId();
serviceValues[i] = spies.get(i).getName();
}
serviceEl = uifactory.addDropdownSingleselect("service", "service", formLayout, serviceKeys, serviceValues, null);
if(messagesService.getMessagesSpi() != null) {
String activeServiceId = messagesService.getMessagesSpi().getId();
for(int i=serviceKeys.length; i-->0; ) {
if(serviceKeys[i].equals(activeServiceId)) {
serviceEl.select(serviceKeys[i], true);
}
}
}
String[] resetPasswordValues = new String[]{ translate("on.sms") };
resetPasswordEl = uifactory.addCheckboxesHorizontal("reset.password", "reset.password", formLayout, onKeys, resetPasswordValues);
resetPasswordEl.addActionListener(FormEvent.ONCHANGE);
if(messageModule.isResetPasswordEnabled()) {
resetPasswordEl.select(onKeys[0], true);
}
updateEnableDisable();
}
private void updateEnableDisable() {
boolean enabled = enableEl.isAtLeastSelected(1);
serviceEl.setVisible(enabled);
resetPasswordEl.setVisible(enabled);
serviceEl.clearError();
if(serviceEl.isOneSelected()) {
String serviceId = serviceEl.getSelectedKey();
MessagesSPI spi = messagesService.getMessagesSpi(serviceId);
if(spi != null && !spi.isValid()) {
serviceEl.setErrorKey("warning.spi.not.configured", new String[]{ spi.getName() });
}
}
}
@Override
protected void doDispose() {
//
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(enableEl == source) {
updateEnableDisable();
messageModule.setEnabled(enableEl.isAtLeastSelected(1));
} else if(resetPasswordEl == source) {
messageModule.setResetPasswordEnabled(resetPasswordEl.isAtLeastSelected(1));
}
super.formInnerEvent(ureq, source, event);
}
@Override
protected void formOK(UserRequest ureq) {
//
}
}
/**
* <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.core.commons.services.sms.ui;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.components.link.LinkFactory;
import org.olat.core.gui.components.segmentedview.SegmentViewComponent;
import org.olat.core.gui.components.segmentedview.SegmentViewEvent;
import org.olat.core.gui.components.segmentedview.SegmentViewFactory;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
/**
*
* Initial date: 3 févr. 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class SimpleMessageServiceAdminController extends BasicController {
private final VelocityContainer mainVC;
private final SegmentViewComponent segmentView;
private final Link configurationLink, statisticsLink;
private MessagesStatisticsController statisticsCtrl;
private SimpleMessageServiceAdminConfigurationController configCtrl;
public SimpleMessageServiceAdminController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl);
mainVC = createVelocityContainer("admin");
segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
segmentView.setReselect(true);
configurationLink = LinkFactory.createLink("admin.settings", mainVC, this);
segmentView.addSegment(configurationLink, true);
statisticsLink = LinkFactory.createLink("admin.statistics", mainVC, this);
segmentView.addSegment(statisticsLink, false);
doOpenConfiguration(ureq);
putInitialPanel(mainVC);
}
@Override
protected void doDispose() {
//
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
if(source == segmentView) {
if(event instanceof SegmentViewEvent) {
SegmentViewEvent sve = (SegmentViewEvent)event;
String segmentCName = sve.getComponentName();
Component clickedLink = mainVC.getComponent(segmentCName);
if (clickedLink == configurationLink) {
doOpenConfiguration(ureq);
} else if (clickedLink == statisticsLink) {
doOpenStatistics(ureq);
}
}
}
}
private void doOpenStatistics(UserRequest ureq) {
if(statisticsCtrl == null) {
statisticsCtrl = new MessagesStatisticsController(ureq, getWindowControl());
listenTo(statisticsCtrl);
}
mainVC.put("segmentCmp", statisticsCtrl.getInitialComponent());
}
private void doOpenConfiguration(UserRequest ureq) {
if(configCtrl == null) {
configCtrl = new SimpleMessageServiceAdminConfigurationController(ureq, getWindowControl());
listenTo(configCtrl);
}
mainVC.put("segmentCmp", configCtrl.getInitialComponent());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment