UserSettingsService.java
/*
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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.opencastproject.adminui.usersettings;
import static org.opencastproject.db.Queries.namedQuery;
import org.opencastproject.adminui.usersettings.persistence.UserSettingDto;
import org.opencastproject.adminui.usersettings.persistence.UserSettingsServiceException;
import org.opencastproject.db.DBSession;
import org.opencastproject.db.DBSessionFactory;
import org.opencastproject.security.api.OrganizationDirectoryService;
import org.opencastproject.security.api.SecurityService;
import org.opencastproject.security.api.UserDirectoryService;
import org.apache.commons.lang3.tuple.Pair;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.function.Function;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
/**
* Finds the user settings and message signatures from the current user.
*/
@Component(
immediate = true,
service = UserSettingsService.class,
property = {
"service.description=Admin UI - Users Settings Service",
"opencast.service.type=org.opencastproject.adminui.usersettings.UserSettingsService"
}
)
public class UserSettingsService {
public static final String PERSISTENCE_UNIT = "org.opencastproject.adminui";
/** Logging utilities */
private static final Logger logger = LoggerFactory.getLogger(UserSettingsService.class);
/** Factory used to create {@link EntityManager}s for transactions */
protected EntityManagerFactory emf;
protected DBSessionFactory dbSessionFactory;
protected DBSession db;
/** The user directory service */
protected UserDirectoryService userDirectoryService;
/** The organization directory service */
protected OrganizationDirectoryService organizationDirectoryService;
/** The security service */
protected SecurityService securityService;
/**
* Creates {@link EntityManagerFactory} using persistence provider and properties passed via OSGi.
*
* @param cc
*/
@Activate
public void activate(ComponentContext cc) {
logger.info("Activating persistence manager for user settings");
db = dbSessionFactory.createSession(emf);
}
/** OSGi DI */
@Reference(target = "(osgi.unit.name=org.opencastproject.adminui)")
public void setEntityManagerFactory(EntityManagerFactory emf) {
this.emf = emf;
}
@Reference
public void setDBSessionFactory(DBSessionFactory dbSessionFactory) {
this.dbSessionFactory = dbSessionFactory;
}
/**
* OSGi callback to set user directory service.
*
* @param userDirectoryService
* user directory service
*/
@Reference
public void setUserDirectoryService(UserDirectoryService userDirectoryService) {
this.userDirectoryService = userDirectoryService;
}
/**
* OSGi callback to set the security service.
*
* @param securityService
* the security service
*/
@Reference
public void setSecurityService(SecurityService securityService) {
this.securityService = securityService;
}
/**
* OSGi callback to set the organization directory service.
*
* @param organizationDirectoryService
* the organization directory service
*/
public void setOrganizationDirectoryService(OrganizationDirectoryService organizationDirectoryService) {
this.organizationDirectoryService = organizationDirectoryService;
}
/**
* Finds the user settings for the current user.
*
* @param limit
* The maximum limit of results to return.
* @param offset
* The starting page offset.
* @return The user settings for the current user.
* @throws UserSettingsServiceException
*/
public UserSettings findUserSettings(int limit, int offset) throws UserSettingsServiceException {
try {
UserSettings userSettings = db.exec(getUserSettingsQuery(limit, offset));
userSettings.setTotal(db.exec(getUserSettingsTotalQuery()));
userSettings.setLimit(limit);
userSettings.setOffset(offset);
return userSettings;
} catch (Exception e) {
logger.error("Could not get user settings:", e);
throw new UserSettingsServiceException(e);
}
}
/**
* @return Function that finds the total number of user settings for the current user.
*/
private Function<EntityManager, Integer> getUserSettingsTotalQuery() {
String orgId = securityService.getOrganization().getId();
String username = securityService.getUser().getUsername();
return namedQuery.find(
"UserSettings.countByUserName",
Number.class,
Pair.of("username", username),
Pair.of("org", orgId)
).andThen(Number::intValue);
}
/**
* @param offset
* The number of limits to page to.
* @param limit
* The maximum number of settings to return.
* @return Function that finds all of the user settings for the current user.
*/
private Function<EntityManager, UserSettings> getUserSettingsQuery(int limit, int offset) {
return em -> {
String orgId = securityService.getOrganization().getId();
String username = securityService.getUser().getUsername();
logger.debug("Getting user settings for '{}' in org '{}'", username, orgId);
List<UserSettingDto> result = em
.createNamedQuery("UserSettings.findByUserName", UserSettingDto.class)
.setParameter("username", username)
.setParameter("org", orgId)
.setMaxResults(limit)
.setFirstResult(offset)
.getResultList();
if (result.size() == 0) {
logger.debug("Found no user settings.");
}
UserSettings userSettings = new UserSettings();
for (UserSettingDto userSettingsDto : result) {
UserSetting userSetting = userSettingsDto.toUserSetting();
logger.debug("Found user setting id: {} key: {} value: {}", userSetting.getId(), userSetting.getKey(),
userSetting.getValue());
userSettings.addUserSetting(userSetting);
}
return userSettings;
};
}
/**
* Create a new user setting key value pair.
*
* @param key
* The key to use for the current user setting.
* @param value
* The value of the user setting.
* @return A new user setting object
* @throws UserSettingsServiceException
*/
public UserSetting addUserSetting(String key, String value) throws UserSettingsServiceException {
String orgId = securityService.getOrganization().getId();
String username = securityService.getUser().getUsername();
try {
return db.execTx(em -> {
UserSettingDto userSettingDto = new UserSettingDto();
userSettingDto.setKey(key);
userSettingDto.setValue(value);
userSettingDto.setUsername(username);
userSettingDto.setOrganization(orgId);
em.persist(userSettingDto);
return userSettingDto.toUserSetting();
});
} catch (Exception e) {
logger.error("Could not update user setting username '{}' org: '{}' key: '{}' value: '{}'", username, orgId, key,
value, e);
throw new UserSettingsServiceException(e);
}
}
/**
* Get all user settings based upon its key.
* @param key The key to search for.
* @return A function returning {@link UserSettingDto} that matches the key.
*/
private Function<EntityManager, List<UserSettingDto>> getUserSettingsByKeyQuery(String key) {
String orgId = securityService.getOrganization().getId();
String username = securityService.getUser().getUsername();
logger.debug("Getting user settings for '{}' in org '{}'", username, orgId);
return namedQuery.findAll(
"UserSettings.findByKey",
UserSettingDto.class,
Pair.of("key", key),
Pair.of("username", username),
Pair.of("org", orgId)
);
}
/**
* Update a user setting that currently exists using its key to find it.
* @param key The key for the user setting.
* @param value The new value to set for the user setting.
* @return An updated {@link UserSetting}
* @throws UserSettingsServiceException
*/
public UserSetting updateUserSetting(String key, String value, String oldValue) throws UserSettingsServiceException {
try {
UserSettingDto userSettingDto = db.exec(getUserSettingsByKeyQuery(key)).stream()
.filter(setting -> setting.getKey().equalsIgnoreCase(key) && setting.getValue().equalsIgnoreCase(oldValue))
.findFirst()
.orElseThrow(() -> new UserSettingsServiceException("Unable to find user setting with key " + key + " value "
+ value + " and old value " + oldValue));
return updateUserSetting(userSettingDto.getId(), key, value);
} catch (Exception e) {
logger.error("Could not update user setting", e);
throw new UserSettingsServiceException(e);
}
}
/**
* Update a user setting that currently exists using its unique id to find it.
* @param id The id for the user setting.
* @param key The key for the user setting.
* @param value The value for the user setting.
* @return The updated {@link UserSetting}.
* @throws UserSettingsServiceException
*/
public UserSetting updateUserSetting(long id, String key, String value) throws UserSettingsServiceException {
String orgId = securityService.getOrganization().getId();
String username = securityService.getUser().getUsername();
logger.debug("Updating user setting id: {} key: {} value: {}", id, key, value);
try {
return db.execTx(em -> {
UserSettingDto userSettingDto = em.find(UserSettingDto.class, id);
userSettingDto.setKey(key);
userSettingDto.setValue(value);
em.persist(userSettingDto);
return userSettingDto.toUserSetting();
});
} catch (Exception e) {
logger.error("Could not update user setting username '{}' org: '{}' id: '{}' key: '{}' value: '{}'",
username, orgId, id, key, value, e);
throw new UserSettingsServiceException(e);
}
}
/**
* Delete a user setting by using a unique id to find it.
*
* @param id
* The unique id for the user setting.
* @throws UserSettingsServiceException
*/
public void deleteUserSetting(long id) throws UserSettingsServiceException {
try {
db.execTx(em -> {
UserSettingDto userSettingsDto = em.find(UserSettingDto.class, id);
em.remove(userSettingsDto);
});
} catch (Exception e) {
logger.error("Could not delete user setting '{}'", id, e);
throw new UserSettingsServiceException(e);
}
}
}