bug6059: made RiotServer replicable

This commit is contained in:
Axel Uhl committed 2024-12-19 13:54:25 +01:00
1 parent 87241a3fad
commit ec8cef1e11
31 files changed
+434 -185

No files matched your search

@@ -31,6 +31,8 @@ Require-Bundle: org.json.simple;bundle-version="1.1.0",
javax.ws.rs;bundle-version="1.1.1"
Import-Package: com.sap.sailing.shared.server.security,
com.sap.sse.security.shared,
javax.servlet;version="[3.1.0,4.0.0)",
javax.servlet.http;version="[3.1.0,4.0.0)",
javax.xml.bind,
org.apache.commons.lang,
org.codehaus.jackson.jaxrs;version="1.9.13",
@@ -43,15 +43,15 @@
<servlet>
<servlet-name>Igtimi Oauth Callback REST API</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<servlet-class>com.sap.sailing.domain.igtimiadapter.gateway.impl.RestServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.sap.sailing.domain.igtimiadapter.gateway.impl.RestApiApplication</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.DisableWADL</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.DisableWADL</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
@@ -50,4 +50,4 @@ bearerTokenOrAnonymous = com.sap.sailing.shared.server.security.BearerTokenOrBas
[urls]
/authorizationcallback = bearerToken
/v1/** = bearerTokenOrAnonymous
/api/v1/** = bearerTokenOrAnonymous
@@ -0,0 +1,15 @@
package com.sap.sailing.domain.igtimiadapter.gateway.impl;
import org.osgi.util.tracker.ServiceTracker;
import com.sap.sailing.domain.igtimiadapter.server.riot.RiotServer;
import com.sap.sse.security.jaxrs.AbstractSecurityResource;
public class AbstractRiotServerResource extends AbstractSecurityResource {
public RiotServer getRiotService() {
@SuppressWarnings("unchecked")
ServiceTracker<RiotServer, RiotServer> tracker = (ServiceTracker<RiotServer, RiotServer>) servletContext
.getAttribute(RestServletContainer.RIOT_SERVICE_TRACKER_NAME);
return tracker.getService();
}
}
@@ -0,0 +1,39 @@
package com.sap.sailing.domain.igtimiadapter.gateway.impl;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.ws.rs.core.Application;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import com.sap.sailing.domain.igtimiadapter.server.riot.RiotServer;
import com.sap.sse.util.ServiceTrackerFactory;
public class RestServletContainer extends com.sap.sse.security.jaxrs.RestServletContainer {
private static final long serialVersionUID = -8877374150158641006L;
public static final String RIOT_SERVICE_TRACKER_NAME = "riotServiceTracker";
private ServiceTracker<RiotServer, RiotServer> riotServiceTracker;
public RestServletContainer() {
super();
}
public RestServletContainer(Application app) {
super(app);
}
public RestServletContainer(Class<? extends Application> appClass) {
super(appClass);
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
final BundleContext context = getBundleContext(config);
riotServiceTracker = ServiceTrackerFactory.createAndOpen(context, RiotServer.class);
config.getServletContext().setAttribute(RIOT_SERVICE_TRACKER_NAME, riotServiceTracker);
}
}
@@ -20,15 +20,14 @@ import com.sap.sailing.domain.igtimiadapter.impl.DataAccessWindowSerializer;
import com.sap.sailing.domain.igtimiadapter.server.riot.RiotServer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.TimeRange;
import com.sap.sse.rest.StreamingOutputUtil;
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
@Path(RestApiApplication.API + RestApiApplication.V1 + RiotDataAccessWindowsResource.DATA_ACCESS_WINDOWS)
public class RiotDataAccessWindowsResource extends StreamingOutputUtil {
public class RiotDataAccessWindowsResource extends AbstractRiotServerResource {
protected static final String DATA_ACCESS_WINDOWS = "/data_access_windows";
@GET
@Produces("text/plain;charset=UTF-8")
@Produces("application/json;charset=UTF-8")
public Response getDataAccessWindows(@QueryParam("permission") String permission,
@QueryParam("start_time") String startTime, @QueryParam("end_time") String endTime,
@QueryParam("serial_numbers[]") Set<String> serialNumbers,
@@ -1,30 +1,37 @@
package com.sap.sailing.domain.igtimiadapter.gateway.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import org.apache.http.client.ClientProtocolException;
import org.apache.shiro.SecurityUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import com.sap.sailing.domain.igtimiadapter.Device;
import com.sap.sailing.domain.igtimiadapter.impl.DeviceDeserializer;
import com.sap.sailing.domain.igtimiadapter.impl.DeviceSerializer;
import com.sap.sailing.domain.igtimiadapter.server.riot.RiotServer;
import com.sap.sse.rest.StreamingOutputUtil;
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
@Path(RestApiApplication.API + RestApiApplication.V1 + RiotDevicesResource.DEVICES)
public class RiotDevicesResource extends StreamingOutputUtil {
public class RiotDevicesResource extends AbstractRiotServerResource {
protected static final String DEVICES = "/devices";
@GET
@Produces("text/plain;charset=UTF-8")
@Produces("application/json;charset=UTF-8")
public Response getDevices() throws ClientProtocolException, IllegalStateException, IOException, ParseException {
final RiotServer riot = Activator.getInstance().getRiotServer();
final JSONObject result = new JSONObject();
@@ -37,4 +44,16 @@ public class RiotDevicesResource extends StreamingOutputUtil {
}
return Response.ok(streamingOutput(result)).build();
}
@POST
@Consumes("application/json;charset=UTF-8")
public Response putDevice(@Context HttpServletRequest request) throws IOException, ParseException {
final InputStream inputStream = request.getInputStream();
final JSONObject deviceJson = (JSONObject) new JSONParser().parse(new InputStreamReader(inputStream));
final Device device = new DeviceDeserializer().createDeviceFromJson(deviceJson);
SecurityUtils.getSubject().checkPermission(device.getIdentifier().getStringPermission(DefaultActions.CREATE));
final RiotServer riot = getRiotService();
riot.addDevice(device);
return Response.ok().build();
}
}
@@ -27,16 +27,15 @@ import com.sap.sailing.domain.igtimiadapter.impl.ResourceSerializer;
import com.sap.sailing.domain.igtimiadapter.server.riot.RiotServer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.TimeRange;
import com.sap.sse.rest.StreamingOutputUtil;
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
@Path(RestApiApplication.API + RestApiApplication.V1 + RiotResourcesResource.RESOURCES)
public class RiotResourcesResource extends StreamingOutputUtil {
public class RiotResourcesResource extends AbstractRiotServerResource {
protected static final String RESOURCES = "/resources";
private static final String DATA = "/data";
@GET
@Produces("text/plain;charset=UTF-8")
@Produces("application/json;charset=UTF-8")
public Response getResources(@QueryParam("permission") String permission,
@QueryParam("start_time") String startTime, @QueryParam("end_time") String endTime,
@QueryParam("serial_numbers[]") Set<String> serialNumbers,
@@ -59,7 +58,7 @@ public class RiotResourcesResource extends StreamingOutputUtil {
}
@GET
@Produces("text/plain;charset=UTF-8")
@Produces("application/json;charset=UTF-8")
@Path(DATA)
public Response getResourcesData(@Context UriInfo ui) {
final MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
@@ -22,7 +22,7 @@ public class RiotServerListersResource extends StreamingOutputUtil {
protected static final String WEB_SOCKETS = "/web_sockets";
@GET
@Produces("text/plain;charset=UTF-8")
@Produces("application/json;charset=UTF-8")
@Path(WEB_SOCKETS)
public Response getDevices(@Context UriInfo uriInfo) throws MalformedURLException, URISyntaxException {
final JSONObject result = new JSONObject();
@@ -14,7 +14,9 @@ Import-Package: com.google.gwt.user.client.rpc.core.com.sap.sse.security.shared,
com.sap.sailing.domain.common.security,
com.sap.sse.common,
com.sap.sse.common.impl,
com.sap.sse.operationaltransformation,
com.sap.sse.replication,
com.sap.sse.replication.interfaces.impl,
com.sap.sse.security,
com.sap.sse.security.shared,
com.sap.sse.shared.util,
@@ -0,0 +1,22 @@
package com.sap.sailing.domain.igtimiadapter.server.replication;
import com.sap.sailing.domain.igtimiadapter.DataAccessWindow;
import com.sap.sailing.domain.igtimiadapter.Device;
import com.sap.sailing.domain.igtimiadapter.Resource;
import com.sap.sailing.domain.igtimiadapter.server.riot.RiotServer;
public interface ReplicableRiotServer extends RiotServer {
Void internalAddDevice(Device device);
Void internalRemoveDevice(long deviceId);
Void internalAddResource(Resource resource);
Void internalRemoveResource(long resourceId);
Void internalAddDataAccessWindow(DataAccessWindow daw);
Void internalRemoveDataAccessWindow(long dawId);
}
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.igtimiadapter.server.replication;
import com.sap.sse.replication.OperationWithResult;
public interface RiotReplicationOperation<ResultType> extends OperationWithResult<ReplicableRiotServer, ResultType> {
}
@@ -13,8 +13,11 @@ import com.sap.sailing.domain.igtimiadapter.Resource;
import com.sap.sailing.domain.igtimiadapter.datatypes.Fix;
import com.sap.sailing.domain.igtimiadapter.persistence.DomainObjectFactory;
import com.sap.sailing.domain.igtimiadapter.persistence.MongoObjectFactory;
import com.sap.sailing.domain.igtimiadapter.server.replication.ReplicableRiotServer;
import com.sap.sailing.domain.igtimiadapter.server.replication.RiotReplicationOperation;
import com.sap.sailing.domain.igtimiadapter.server.riot.impl.RiotServerImpl;
import com.sap.sailing.domain.igtimiadapter.shared.IgtimiWindReceiver;
import com.sap.sse.replication.Replicable;
/**
* A server implementation according to the protocol specification found
@@ -42,7 +45,7 @@ import com.sap.sailing.domain.igtimiadapter.shared.IgtimiWindReceiver;
* @author Axel Uhl (d043530)
*
*/
public interface RiotServer {
public interface RiotServer extends Replicable<ReplicableRiotServer, RiotReplicationOperation<?>> {
/**
* Created a {@link RiotServer} listening on the {@code port} specified. If the port is not
* available, an {@link IOException} will be thrown.
@@ -74,8 +77,26 @@ public interface RiotServer {
int getPort() throws IOException;
Iterable<Resource> getResources();
Resource getResourceById(long id);
void addResource(Resource resource);
void removeResource(long resourceId);
Iterable<Device> getDevices();
Device getDeviceById(long id);
void addDevice(Device device);
void removeDevice(long deviceId);
Iterable<DataAccessWindow> getDataAccessWindows();
DataAccessWindow getDataAccessWindowById(long id);
void addDataAccessWindow(DataAccessWindow daw);
void removeDataAccessWindow(long dawId);
}
@@ -1,8 +1,12 @@
package com.sap.sailing.domain.igtimiadapter.server.riot.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.Thread.State;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
@@ -25,12 +29,16 @@ import com.sap.sailing.domain.igtimiadapter.Resource;
import com.sap.sailing.domain.igtimiadapter.datatypes.Fix;
import com.sap.sailing.domain.igtimiadapter.persistence.DomainObjectFactory;
import com.sap.sailing.domain.igtimiadapter.persistence.MongoObjectFactory;
import com.sap.sailing.domain.igtimiadapter.server.replication.ReplicableRiotServer;
import com.sap.sailing.domain.igtimiadapter.server.replication.RiotReplicationOperation;
import com.sap.sailing.domain.igtimiadapter.server.riot.RiotConnection;
import com.sap.sailing.domain.igtimiadapter.server.riot.RiotServer;
import com.sap.sse.common.Duration;
import com.sap.sse.replication.interfaces.impl.AbstractReplicableWithObjectInputStream;
import com.sap.sse.shared.util.Wait;
import com.sap.sse.util.ObjectInputStreamResolvingAgainstCache;
public class RiotServerImpl implements RiotServer, Runnable {
public class RiotServerImpl extends AbstractReplicableWithObjectInputStream<ReplicableRiotServer, RiotReplicationOperation<?>> implements RiotServer, ReplicableRiotServer, Runnable {
private static final Logger logger = Logger.getLogger(RiotServerImpl.class.getName());
private final ConcurrentMap<Long, Resource> resources;
@@ -176,26 +184,135 @@ public class RiotServerImpl implements RiotServer, Runnable {
}
@Override
public Iterable<Resource> getResources() {
return Collections.unmodifiableCollection(resources.values());
public Iterable<Device> getDevices() {
return Collections.unmodifiableCollection(devices.values());
}
@Override
public Device getDeviceById(long id) {
return devices.get(id);
}
@Override
public Iterable<Device> getDevices() {
return Collections.unmodifiableCollection(devices.values());
public void addDevice(Device device) {
apply(s->s.internalAddDevice(device));
}
@Override
public Void internalAddDevice(Device device) {
devices.put(device.getId(), device);
return null;
}
@Override
public void removeDevice(long deviceId) {
apply(s->s.internalRemoveDevice(deviceId));
}
@Override
public Void internalRemoveDevice(long deviceId) {
devices.remove(deviceId);
return null;
}
@Override
public Iterable<Resource> getResources() {
return Collections.unmodifiableCollection(resources.values());
}
@Override
public Resource getResourceById(long id) {
return resources.get(id);
}
@Override
public void addResource(Resource resource) {
apply(s->s.internalAddResource(resource));
}
@Override
public Void internalAddResource(Resource resource) {
resources.put(resource.getId(), resource);
return null;
}
@Override
public void removeResource(long resourceId) {
apply(s->s.internalRemoveResource(resourceId));
}
@Override
public Void internalRemoveResource(long resourceId) {
resources.remove(resourceId);
return null;
}
@Override
public Iterable<DataAccessWindow> getDataAccessWindows() {
return Collections.unmodifiableCollection(dataAccessWindows.values());
}
@Override
public DataAccessWindow getDataAccessWindowById(long id) {
return dataAccessWindows.get(id);
}
@Override
public void addDataAccessWindow(DataAccessWindow daw) {
apply(s->s.internalAddDataAccessWindow(daw));
}
@Override
public Void internalAddDataAccessWindow(DataAccessWindow daw) {
dataAccessWindows.put(daw.getId(), daw);
return null;
}
@Override
public void removeDataAccessWindow(long dawId) {
apply(s->s.internalRemoveDataAccessWindow(dawId));
}
@Override
public Void internalRemoveDataAccessWindow(long dawId) {
dataAccessWindows.remove(dawId);
return null;
}
/**
* Use this method only for testing/debugging. It clears the transient state of this service,in particular
* all resources and data access windows.
*/
public void clear() {
devices.clear();
resources.clear();
dataAccessWindows.clear();
connections.clear();
listeners.clear();
}
@Override
public void clearReplicaState() throws MalformedURLException, IOException, InterruptedException {
clear();
}
@Override
public ObjectInputStream createObjectInputStreamResolvingAgainstCache(InputStream is,
Map<String, Class<?>> classLoaderCache) throws IOException {
return new ObjectInputStreamResolvingAgainstCache<Object>(is, /* dummy cache */ new Object(), /* resolve listener */ null, classLoaderCache) {
}; // use anonymous inner class in this class loader to see all that this class sees
}
@Override
public void initiallyFillFromInternal(ObjectInputStream is)
throws IOException, ClassNotFoundException, InterruptedException {
// TODO Auto-generated method stub
}
@Override
public void serializeForInitialReplicationInternal(ObjectOutputStream objectOutputStream) throws IOException {
objectOutputStream.writeObject(devices);
objectOutputStream.writeObject(resources);
objectOutputStream.writeObject(dataAccessWindows);
}
}
@@ -20,7 +20,7 @@ public class DeviceImpl extends HasIdImpl implements Device {
super(id);
this.serialNumber = serialNumber;
this.name = name;
this.serviceTag = serialNumber;
this.serviceTag = serviceTag;
}
@Override
@@ -1005,7 +1005,6 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
public void registerCompetitors(Iterable<Competitor> competitors) {
RegattaLog regattaLog = getRegattaLike().getRegattaLog();
TimePoint now = MillisecondsTimePoint.now();
for (Competitor competitor: competitors) {
regattaLog.add(new RegattaLogRegisterCompetitorEventImpl(now, now, regattaLogEventAuthorForRegatta,
UUID.randomUUID(), competitor));
@@ -811,7 +811,7 @@ public class RegattasResource extends AbstractSailingServerResource {
SecuredDomainType.COMPETITOR, CompetitorImpl.getTypeRelativeObjectIdentifier(competitorUuid), name,
createCompetitorJob);
}
regatta.registerCompetitor(competitor);
regatta.registerCompetitor(competitor); // FIXME what about replication???
response = Response.ok(streamingOutput(CompetitorJsonSerializer.create().serialize(competitor)))
.header("Content-Type", MediaType.APPLICATION_JSON + ";charset=UTF-8").build();
if (deviceUuid != null) {
@@ -964,7 +964,7 @@ public class RegattasResource extends AbstractSailingServerResource {
} else {
getSecurityService().checkCurrentUserHasOneOfExplicitPermissions(competitor,
SecuredSecurityTypes.PublicReadableActions.READ_AND_READ_PUBLIC_ACTIONS);
regatta.deregisterCompetitor(competitor);
regatta.deregisterCompetitor(competitor); // FIXME what about replication???
response = Response.ok().build();
}
}
@@ -126,7 +126,7 @@ public class TagsResource extends AbstractSailingServerResource {
final TaggingService taggingService = getService().getTaggingService();
try {
taggingService.addTag(leaderboardName, raceColumnName, fleetName, tag, comment, imageURL, resizedImageURL,
visibleForPublic, new MillisecondsTimePoint(raceTimepoint));
visibleForPublic, new MillisecondsTimePoint(raceTimepoint)); // FIXME what about replication???
response = Response.created(uriInfo.getRequestUri()).build();
} catch (IllegalArgumentException | RaceLogNotFoundException | TagAlreadyExistsException e) {
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
@@ -158,7 +158,7 @@ public class TagsResource extends AbstractSailingServerResource {
TagDTO tagToRemove = serializer.deserializeTag(tagJson);
TaggingService taggingService = getService().getTaggingService();
try {
taggingService.removeTag(leaderboardName, raceColumnName, fleetName, tagToRemove);
taggingService.removeTag(leaderboardName, raceColumnName, fleetName, tagToRemove); // FIXME what about replication???
response = Response.noContent().build();
} catch (IllegalArgumentException | NotRevokableException | RaceLogNotFoundException e) {
response = Response.status(Status.BAD_REQUEST).type(TEXT_PLAIN_UTF8).build();
@@ -196,7 +196,6 @@ public class TagsResource extends AbstractSailingServerResource {
Response response;
final TagDTO tagToUpdate = serializer.deserializeTag(tagJson);
final TaggingService taggingService = getService().getTaggingService();
// only call update method when any of the parameters needs to be changed
if (tagParam != null || commentParam != null || imageURLParam != null || visibleForPublicParam != null) {
// keep old values when no new values are provided
@@ -205,12 +204,11 @@ public class TagsResource extends AbstractSailingServerResource {
String imageURL = (imageURLParam == null ? tagToUpdate.getImageURL() : imageURLParam);
String resizedImageURL = (resizedImageURLParam == null ? tagToUpdate.getResizedImageURL()
: resizedImageURLParam);
boolean visibleForPublic = (visibleForPublicParam == null ? tagToUpdate.isVisibleForPublic()
: visibleForPublicParam.equalsIgnoreCase("true") ? true : false);
try {
taggingService.updateTag(leaderboardName, raceColumnName, fleetName, tagToUpdate, tag, comment,
imageURL, resizedImageURL, visibleForPublic);
imageURL, resizedImageURL, visibleForPublic); // FIXME what about replication???
response = Response.noContent().build();
} catch (IllegalArgumentException | NotRevokableException | RaceLogNotFoundException
| TagAlreadyExistsException e) {
@@ -4,9 +4,6 @@ import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.servlet.ServletContext;
import javax.ws.rs.core.Context;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
@@ -23,47 +20,13 @@ import com.sap.sailing.server.interfaces.RacingEventService;
import com.sap.sailing.shared.server.SharedSailingData;
import com.sap.sse.InvalidDateException;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.TypeBasedServiceFinderFactory;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.osgi.CachedOsgiTypeBasedServiceFinderFactory;
import com.sap.sse.replication.ReplicationService;
import com.sap.sse.rest.StreamingOutputUtil;
import com.sap.sse.security.SecurityService;
import com.sap.sse.util.DateParser;
import com.sun.jersey.api.core.ResourceContext;
public abstract class SharedAbstractSailingServerResource extends StreamingOutputUtil {
public abstract class SharedAbstractSailingServerResource extends SharedAbstractSecuredServerResource {
private static final String SLASH_ENCODING = "__";
@Context ServletContext servletContext;
@Context ResourceContext resourceContext;
protected ServletContext getServletContext() {
return servletContext;
}
protected ResourceContext getResourceContext() {
return resourceContext;
}
public <T> T getService(Class<T> clazz) {
BundleContext context = getBundleContext();
ServiceTracker<T, T> tracker = new ServiceTracker<T, T>(context, clazz, null);
tracker.open();
T service = tracker.getService();
tracker.close();
return service;
}
protected BundleContext getBundleContext() {
BundleContext context = (BundleContext) servletContext
.getAttribute(RestServletContainer.OSGI_RFC66_WEBBUNDLE_BUNDLECONTEXT_NAME);
return context;
}
protected TypeBasedServiceFinderFactory getServiceFinderFactory () {
return new CachedOsgiTypeBasedServiceFinderFactory(getBundleContext());
}
public RacingEventService getService() {
@SuppressWarnings("unchecked")
ServiceTracker<RacingEventService, RacingEventService> tracker = (ServiceTracker<RacingEventService, RacingEventService>) servletContext.getAttribute(RestServletContainer.RACING_EVENT_SERVICE_TRACKER_NAME);
@@ -0,0 +1,44 @@
package com.sap.sailing.shared.server.gateway.jaxrs;
import javax.servlet.ServletContext;
import javax.ws.rs.core.Context;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import com.sap.sse.common.TypeBasedServiceFinderFactory;
import com.sap.sse.osgi.CachedOsgiTypeBasedServiceFinderFactory;
import com.sap.sse.rest.StreamingOutputUtil;
import com.sun.jersey.api.core.ResourceContext;
public class SharedAbstractSecuredServerResource extends StreamingOutputUtil {
@Context ServletContext servletContext;
@Context ResourceContext resourceContext;
protected ServletContext getServletContext() {
return servletContext;
}
protected ResourceContext getResourceContext() {
return resourceContext;
}
public <T> T getService(Class<T> clazz) {
BundleContext context = getBundleContext();
ServiceTracker<T, T> tracker = new ServiceTracker<T, T>(context, clazz, null);
tracker.open();
T service = tracker.getService();
tracker.close();
return service;
}
protected BundleContext getBundleContext() {
BundleContext context = (BundleContext) servletContext
.getAttribute(RestServletContainer.OSGI_RFC66_WEBBUNDLE_BUNDLECONTEXT_NAME);
return context;
}
protected TypeBasedServiceFinderFactory getServiceFinderFactory () {
return new CachedOsgiTypeBasedServiceFinderFactory(getBundleContext());
}
}
@@ -5,7 +5,7 @@ package com.sap.sse.common;
* particularly during de-serialization when the de-serialized instance needs to be replaced by an instance managed by
* the domain factory.<p>
*
* If the de-serializing stream is a {@link ObjectInputStreamResolvingAgainstDomainFactory} stream, it will automatically
* If the de-serializing stream is a {@link ObjectInputStreamResolvingAgainstCache} stream, it will automatically
* do a {@link #resolve(Object)} for instances whose classes implement this interface. Implementing classes need to
* delegate accordingly to the domain factory passed as argument.
*
@@ -74,7 +74,7 @@ public class LandscapeResource extends AbstractSecurityResource {
TimePoint.now(), keyName, publicKey.getBytes(), encryptedPrivateKey.getBytes());
final AwsLandscapeState landscape = Activator.getInstance().getLandscapeState();
try {
getService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError(sshKeyPair.getPermissionType(),
getSecurityService().setOwnershipCheckPermissionForObjectCreationAndRevertOnError(sshKeyPair.getPermissionType(),
sshKeyPair.getIdentifier().getTypeRelativeObjectIdentifier(), keyName,
()->landscape.addSSHKeyPair(sshKeyPair));
response = Response.ok(streamingOutput(sshKeyPairJsonSerializer.serialize(sshKeyPair))).build();
@@ -34,7 +34,6 @@ public class Activator implements BundleActivator {
} catch (IOException ioe) {
logger.log(Level.SEVERE, "Couldn't read mail properties from " + propertiesfile.getCanonicalPath(), ioe);
}
MailService mailService = new MailServiceImpl(mailProperties, new MailServiceResolverAgainstOsgiRegistryImpl(
new CachedOsgiTypeBasedServiceFinderFactory(context).createServiceFinder(MailService.class)));
registration = context.registerService(MailService.class, mailService, null);
@@ -80,7 +80,7 @@ public class SecurityResourceTest {
assertNotNull(session);
servlet = new SecurityResource() {
@Override
public SecurityService getService() {
public SecurityService getSecurityService() {
return service;
}
};
@@ -12,9 +12,9 @@ import com.sap.sse.security.SecurityUrlPathProvider;
public abstract class AbstractSecurityResource extends StreamingOutputUtil {
@Context
ServletContext servletContext;
protected ServletContext servletContext;
public SecurityService getService() {
public SecurityService getSecurityService() {
@SuppressWarnings("unchecked")
ServiceTracker<SecurityService, SecurityService> tracker = (ServiceTracker<SecurityService, SecurityService>) servletContext
.getAttribute(RestServletContainer.SECURITY_SERVICE_TRACKER_NAME);
@@ -42,7 +42,7 @@ public class RestServletContainer extends ServletContainer {
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
BundleContext context = (BundleContext) config.getServletContext().getAttribute(OSGI_RFC66_WEBBUNDLE_BUNDLECONTEXT_NAME);
BundleContext context = getBundleContext(config);
securityServiceTracker = new ServiceTracker<SecurityService, SecurityService>(context, SecurityService.class.getName(), null);
securityServiceTracker.open();
config.getServletContext().setAttribute(SECURITY_SERVICE_TRACKER_NAME, securityServiceTracker);
@@ -52,6 +52,10 @@ public class RestServletContainer extends ServletContainer {
config.getServletContext().setAttribute(SECURITY_URL_PATH_PROVIDER_NAME, securityUrlPathFinder);
}
protected BundleContext getBundleContext(ServletConfig config) {
return (BundleContext) config.getServletContext().getAttribute(OSGI_RFC66_WEBBUNDLE_BUNDLECONTEXT_NAME);
}
@Override
public void destroy() {
super.destroy();
@@ -61,14 +61,14 @@ public class OwnershipResource extends AbstractSecurityResource {
} catch (Exception ex) {
throw new OwnershipException("Not permitted to change ownership.", Status.FORBIDDEN);
}
final OwnershipAnnotation existingOwnership = getService().getOwnership(identifier);
final OwnershipAnnotation existingOwnership = getSecurityService().getOwnership(identifier);
final User user;
if (json.containsKey(KEY_USERNAME)) {
final String username = (String) json.get(KEY_USERNAME);
if (username == null) {
user = null;
} else {
user = getService().getUserByName(username);
user = getSecurityService().getUserByName(username);
if (user == null) {
// username provided but cannot be resolved
throw new OwnershipException("User Not found", Status.BAD_REQUEST);
@@ -83,7 +83,7 @@ public class OwnershipResource extends AbstractSecurityResource {
if (userGroupIdAsString == null) {
userGroup = null;
} else {
userGroup = getService().getUserGroup(UUID.fromString(userGroupIdAsString));
userGroup = getSecurityService().getUserGroup(UUID.fromString(userGroupIdAsString));
if (userGroup == null) {
throw new OwnershipException("UserGroup Not found", Status.BAD_REQUEST);
}
@@ -92,9 +92,9 @@ public class OwnershipResource extends AbstractSecurityResource {
userGroup = existingOwnership == null ? null : existingOwnership.getAnnotation().getTenantOwner();
}
if (json.containsKey(KEY_DISPLAY_NAME)) {
getService().setOwnership(identifier, user, userGroup, (String) json.get(KEY_DISPLAY_NAME));
getSecurityService().setOwnership(identifier, user, userGroup, (String) json.get(KEY_DISPLAY_NAME));
} else {
getService().setOwnership(identifier, user, userGroup);
getSecurityService().setOwnership(identifier, user, userGroup);
}
return Response.ok(new GeneralResponse(true, "Ownership changed successfully").toString()).build();
}
@@ -118,7 +118,7 @@ public class OwnershipResource extends AbstractSecurityResource {
private Response getOwnership(String objectType, final String[] typeRelativeObjectIdArray) {
QualifiedObjectIdentifier identifier = new QualifiedObjectIdentifierImpl(objectType,
new TypeRelativeObjectIdentifier(typeRelativeObjectIdArray));
final OwnershipAnnotation existingOwnership = getService().getOwnership(identifier);
final OwnershipAnnotation existingOwnership = getSecurityService().getOwnership(identifier);
final JSONObject result = new JSONObject();
result.put(KEY_OBJECT_TYPE, objectType);
result.put(KEY_OBJECT_ID, identifier.getTypeRelativeObjectIdentifier().toString());
@@ -135,7 +135,7 @@ public class OwnershipResource extends AbstractSecurityResource {
@PathParam("typeRelativeObjectId") String typeRelativeObjectId) throws OwnershipException {
QualifiedObjectIdentifier identifier = new QualifiedObjectIdentifierImpl(objectType,
new TypeRelativeObjectIdentifier(typeRelativeObjectId));
final AccessControlListAnnotation acl = getService().getAccessControlList(identifier);
final AccessControlListAnnotation acl = getSecurityService().getAccessControlList(identifier);
final JSONObject result = new JSONObject();
result.put(KEY_OBJECT_TYPE, objectType);
result.put(KEY_OBJECT_ID, typeRelativeObjectId);
@@ -178,7 +178,7 @@ public class OwnershipResource extends AbstractSecurityResource {
if (groupIdAsString == null) {
group = null;
} else {
group = getService().getUserGroup(UUID.fromString(groupIdAsString));
group = getSecurityService().getUserGroup(UUID.fromString(groupIdAsString));
if (group == null) {
throw new OwnershipException(String.format("UserGroup with ID %s Not found", groupIdAsString), Status.BAD_REQUEST);
}
@@ -192,9 +192,9 @@ public class OwnershipResource extends AbstractSecurityResource {
}
if (json.containsKey(KEY_DISPLAY_NAME)) {
final String displayName = (String) json.get(KEY_DISPLAY_NAME);
getService().overrideAccessControlList(identifier, actionsByUserGroup, displayName);
getSecurityService().overrideAccessControlList(identifier, actionsByUserGroup, displayName);
} else {
getService().overrideAccessControlList(identifier, actionsByUserGroup);
getSecurityService().overrideAccessControlList(identifier, actionsByUserGroup);
}
return Response.ok(new GeneralResponse(true, "ACL changed successfully").toString()).build();
}
@@ -24,7 +24,7 @@ public class PreferencesResource extends AbstractSecurityResource {
Response response = null;
if (SecurityUtils.getSubject().isAuthenticated()) {
String username = SecurityUtils.getSubject().getPrincipal().toString();
String settings = getService().getPreference(username, settingsKey);
String settings = getSecurityService().getPreference(username, settingsKey);
if (settings == null) {
response = Response.noContent().build();
} else {
@@ -43,7 +43,7 @@ public class PreferencesResource extends AbstractSecurityResource {
Response response = null;
if (SecurityUtils.getSubject().isAuthenticated()) {
String username = SecurityUtils.getSubject().getPrincipal().toString();
getService().setPreference(username, settingsKey, json);
getSecurityService().setPreference(username, settingsKey, json);
response = Response.ok().build();
} else {
response = Response.status(401).build();
@@ -58,7 +58,7 @@ public class PreferencesResource extends AbstractSecurityResource {
Response response = null;
if (SecurityUtils.getSubject().isAuthenticated()) {
String username = SecurityUtils.getSubject().getPrincipal().toString();
getService().unsetPreference(username, settingsKey);
getSecurityService().unsetPreference(username, settingsKey);
response = Response.ok().build();
} else {
response = Response.status(401).build();
@@ -41,12 +41,12 @@ public class RoleResource extends AbstractSecurityResource {
@Produces("application/json;charset=UTF-8")
public Response createRole(@FormParam(KEY_ROLE_NAME) String roleName) {
final String roleDefinitionIdAsString = UUID.randomUUID().toString();
final RoleDefinition role = getService().setOwnershipWithoutCheckPermissionForObjectCreationAndRevertOnError(
final RoleDefinition role = getSecurityService().setOwnershipWithoutCheckPermissionForObjectCreationAndRevertOnError(
SecuredSecurityTypes.ROLE_DEFINITION, new TypeRelativeObjectIdentifier(roleDefinitionIdAsString),
roleName, new Callable<RoleDefinition>() {
@Override
public RoleDefinition call() throws Exception {
return getService().createRoleDefinition(UUID.fromString(roleDefinitionIdAsString), roleName);
return getSecurityService().createRoleDefinition(UUID.fromString(roleDefinitionIdAsString), roleName);
}
});
final Response resp;
@@ -71,15 +71,15 @@ public class RoleResource extends AbstractSecurityResource {
// parse UUID
final UUID roleUUID = UUID.fromString(roleId);
// get role definition from role id
final RoleDefinition roleDefinition = getService().getRoleDefinition(roleUUID);
final RoleDefinition roleDefinition = getSecurityService().getRoleDefinition(roleUUID);
// null check role definition
if (roleDefinition == null) {
resp = Response.status(Status.NOT_FOUND).entity(String.format("No role with id '%s' found.", roleUUID))
.build();
} else {
// check delete permission and remove role
getService().checkPermissionAndDeleteOwnershipForObjectRemoval(roleDefinition, () -> {
getService().deleteRoleDefinition(roleDefinition);
getSecurityService().checkPermissionAndDeleteOwnershipForObjectRemoval(roleDefinition, () -> {
getSecurityService().deleteRoleDefinition(roleDefinition);
});
resp = Response.status(Status.NO_CONTENT).build();
}
@@ -101,14 +101,14 @@ public class RoleResource extends AbstractSecurityResource {
// parse UUID
final UUID roleUUID = UUID.fromString(roleId);
// get role definition from role id
final RoleDefinition roleDefinition = getService().getRoleDefinition(roleUUID);
final RoleDefinition roleDefinition = getSecurityService().getRoleDefinition(roleUUID);
// null check role definition
if (roleDefinition == null) {
resp = Response.status(Status.NOT_FOUND).entity(String.format("No role with id '%s' found.", roleUUID))
.build();
} else {
// check update permission on role
getService().checkCurrentUserUpdatePermission(roleDefinition);
getSecurityService().checkCurrentUserUpdatePermission(roleDefinition);
// create permission objects
final Set<WildcardPermission> permissions = new HashSet<>();
final JSONObject body = (JSONObject) new JSONParser().parse(json);
@@ -122,11 +122,11 @@ public class RoleResource extends AbstractSecurityResource {
addedPermissions.removeAll(permissions);
final Set<WildcardPermission> removedPermissions = new HashSet<>(permissions);
removedPermissions.removeAll(roleDefinition.getPermissions());
if (!getService().hasUserAllWildcardPermissionsForAlreadyRealizedQualifications(roleDefinition,
if (!getSecurityService().hasUserAllWildcardPermissionsForAlreadyRealizedQualifications(roleDefinition,
addedPermissions)) {
resp = Response.status(Status.UNAUTHORIZED)
.entity("Not permitted to grant permissions for role " + roleDefinition.getName()).build();
} else if (!getService().hasUserAllWildcardPermissionsForAlreadyRealizedQualifications(roleDefinition,
} else if (!getSecurityService().hasUserAllWildcardPermissionsForAlreadyRealizedQualifications(roleDefinition,
removedPermissions)) {
resp = Response.status(Status.UNAUTHORIZED)
.entity("Not permitted to revoke permissions for role " + roleDefinition.getName()).build();
@@ -137,7 +137,7 @@ public class RoleResource extends AbstractSecurityResource {
if (roleName != null) {
roleDefinition.setName(roleName);
}
getService().updateRoleDefinition(roleDefinition);
getSecurityService().updateRoleDefinition(roleDefinition);
resp = Response.ok().build();
}
}
@@ -158,14 +158,14 @@ public class RoleResource extends AbstractSecurityResource {
// parse UUID
final UUID roleUUID = UUID.fromString(roleId);
// get role definition from role id
final RoleDefinition roleDefinition = getService().getRoleDefinition(roleUUID);
final RoleDefinition roleDefinition = getSecurityService().getRoleDefinition(roleUUID);
// null check role definition
if (roleDefinition == null) {
resp = Response.status(Status.NOT_FOUND).entity(String.format("No role with id '%s' found.", roleUUID))
.build();
} else {
// check read permission on role
getService().checkCurrentUserReadPermission(roleDefinition);
getSecurityService().checkCurrentUserReadPermission(roleDefinition);
// build json result with permissions and id
final JSONObject jsonResult = new JSONObject();
final JSONArray jsonPermissions = new JSONArray();
@@ -101,10 +101,10 @@ public class SecurityResource extends AbstractSecurityResource {
final TimePoint start = TimePoint.now();
try {
final WildcardPermission wildcardPermission = new WildcardPermission(permission);
final Iterable<User> usersWithPermission = getService().getUsersWithPermissions(wildcardPermission);
final Iterable<User> usersWithPermission = getSecurityService().getUsersWithPermissions(wildcardPermission);
final JSONArray usernames = new JSONArray();
for (final User userWithPermission : usersWithPermission) {
if (getService().hasCurrentUserReadPermission(userWithPermission)) {
if (getSecurityService().hasCurrentUserReadPermission(userWithPermission)) {
usernames.add(userWithPermission.getName());
}
}
@@ -140,11 +140,11 @@ public class SecurityResource extends AbstractSecurityResource {
@Path(CHANGE_PASSWORD_METHOD)
@Produces("text/plain;charset=UTF-8")
public Response changePassword(@FormParam(USERNAME) String username, @FormParam(PASSWORD) String password) {
if (!getService().hasCurrentUserUpdatePermission(getService().getUserByName(username))) {
if (!getSecurityService().hasCurrentUserUpdatePermission(getSecurityService().getUserByName(username))) {
return Response.status(Status.UNAUTHORIZED).build();
} else {
try {
getService().updateSimpleUserPassword(username, password);
getSecurityService().updateSimpleUserPassword(username, password);
return Response.ok().build();
} catch (UserManagementException e) {
return Response.status(Status.PRECONDITION_FAILED).entity(e.getMessage()).build();
@@ -160,16 +160,16 @@ public class SecurityResource extends AbstractSecurityResource {
try {
final User user;
if (username != null) {
user = getService().getUserByName(username);
user = getSecurityService().getUserByName(username);
} else if (email != null) {
user = getService().getUserByEmail(email);
user = getSecurityService().getUserByEmail(email);
} else {
return Response.status(Status.PRECONDITION_FAILED).entity("username or email must be provided").build();
}
if (user == null) {
return Response.status(Status.PRECONDITION_FAILED).entity("user not found").build();
} else {
getService().resetPassword(user.getName(), getPasswordResetURL(uriInfo, application));
getSecurityService().resetPassword(user.getName(), getPasswordResetURL(uriInfo, application));
return Response.ok().build();
}
} catch (UserManagementException | MailException e) {
@@ -187,7 +187,7 @@ public class SecurityResource extends AbstractSecurityResource {
@QueryParam(FULL_NAME) String queryFullName, @FormParam(FULL_NAME) String formFullName,
@QueryParam(COMPANY) String queryCompany, @FormParam(COMPANY) String formCompany) {
try {
User user = getService().checkPermissionForObjectCreationAndRevertOnErrorForUserCreation(queryUsername,
User user = getSecurityService().checkPermissionForObjectCreationAndRevertOnErrorForUserCreation(queryUsername,
new Callable<User>() {
@Override
public User call() throws Exception {
@@ -197,8 +197,8 @@ public class SecurityResource extends AbstractSecurityResource {
final String emailToUse = preferFirstIfNotNullOrElseSecond(formEmail, queryEmail);
final String fullNameToUse = preferFirstIfNotNullOrElseSecond(formFullName, queryFullName);
final String companyToUse = preferFirstIfNotNullOrElseSecond(formCompany, queryCompany);
User newUser = getService().createSimpleUser(usernameToUse, emailToUse, passwordToUse, fullNameToUse, companyToUse,
Locale.ENGLISH, validationBaseURL, getService().getDefaultTenantForCurrentUser());
User newUser = getSecurityService().createSimpleUser(usernameToUse, emailToUse, passwordToUse, fullNameToUse, companyToUse,
Locale.ENGLISH, validationBaseURL, getSecurityService().getDefaultTenantForCurrentUser());
SecurityUtils.getSubject().login(new UsernamePasswordToken(usernameToUse, passwordToUse));
return newUser;
}
@@ -241,14 +241,14 @@ public class SecurityResource extends AbstractSecurityResource {
@Produces("application/json;charset=UTF-8")
public Response getUser(@QueryParam(USERNAME) String username) {
final Subject subject = SecurityUtils.getSubject();
final User user = getService().getUserByName(username == null ? subject.getPrincipal().toString() : username);
final User user = getSecurityService().getUserByName(username == null ? subject.getPrincipal().toString() : username);
if (user == null) {
return Response.status(Status.PRECONDITION_FAILED).entity("User "+username+" not known").build();
} else if (getService().hasCurrentUserReadPermission(user) || getService()
} else if (getSecurityService().hasCurrentUserReadPermission(user) || getSecurityService()
.hasCurrentUserOneOfExplicitPermissions(user, SecuredSecurityTypes.PublicReadableActions.READ_PUBLIC)) {
JSONObject result = new JSONObject();
result.put(USERNAME, user.getName());
if (getService().hasCurrentUserReadPermission(user)) {
if (getSecurityService().hasCurrentUserReadPermission(user)) {
result.put(FULL_NAME, user.getFullName());
result.put(EMAIL, user.getEmail());
result.put(COMPANY, user.getCompany());
@@ -263,11 +263,11 @@ public class SecurityResource extends AbstractSecurityResource {
@Path(USER_METHOD)
@Produces("text/plain;charset=UTF-8")
public Response deleteUser(@QueryParam(USERNAME) String username) {
User user = getService().getUserByName(username);
User user = getSecurityService().getUserByName(username);
if (user != null) {
return getService().checkPermissionAndDeleteOwnershipForObjectRemoval(user, () -> {
return getSecurityService().checkPermissionAndDeleteOwnershipForObjectRemoval(user, () -> {
try {
getService().deleteUser(username);
getSecurityService().deleteUser(username);
return Response.ok().build();
} catch (UserManagementException e) {
return Response.status(Status.PRECONDITION_FAILED).entity(e.getMessage()).build();
@@ -287,36 +287,36 @@ public class SecurityResource extends AbstractSecurityResource {
final Response response;
try {
// get user for which to add a role
final User user = getService().getUserByName(username);
final User user = getSecurityService().getUserByName(username);
if (user == null) {
response = Response.status(Status.NOT_FOUND).entity("User not found").build();
} else {
// get user for which the role is qualified, if one exists
final User qualifiedForUser = qualifyingUserName == null ? null : getService().getUserByName(qualifyingUserName);
final User qualifiedForUser = qualifyingUserName == null ? null : getSecurityService().getUserByName(qualifyingUserName);
if (qualifyingUserName != null && qualifiedForUser == null) {
response = Response.status(Status.NOT_FOUND).entity("Qualifying user not found").build();
} else {
// get the group tenant the role is qualified for if one exists
final UserGroup qualifyingGroup = qualifyingGroupId == null ? null : getService().getUserGroup(UUID.fromString(qualifyingGroupId));
final UserGroup qualifyingGroup = qualifyingGroupId == null ? null : getSecurityService().getUserGroup(UUID.fromString(qualifyingGroupId));
if (qualifyingGroupId != null && qualifyingGroup == null) {
response = Response.status(Status.NOT_FOUND).entity("Qualifying group not found").build();
} else {
final Role role = getService().getOrThrowRoleFromIDsAndCheckMetaPermissions(
final Role role = getSecurityService().getOrThrowRoleFromIDsAndCheckMetaPermissions(
roleDefinitionId == null ? null : UUID.fromString(roleDefinitionId),
qualifyingGroup == null ? null : qualifyingGroup.getId(),
qualifiedForUser == null ? null : qualifiedForUser.getName(), transitive);
final TypeRelativeObjectIdentifier associationTypeIdentifier = PermissionAndRoleAssociation.get(role, user);
final String message = "User "+SecurityUtils.getSubject().getPrincipal()+" added role " + role.getName() + " for user " + username;
getService().setOwnershipWithoutCheckPermissionForObjectCreationAndRevertOnError(
getSecurityService().setOwnershipWithoutCheckPermissionForObjectCreationAndRevertOnError(
SecuredSecurityTypes.ROLE_ASSOCIATION, associationTypeIdentifier,
associationTypeIdentifier.toString(), new Action() {
@Override
public void run() throws Exception {
final QualifiedObjectIdentifier qualifiedObjectAssociationIdentifier = SecuredSecurityTypes.ROLE_ASSOCIATION
.getQualifiedObjectIdentifier(associationTypeIdentifier);
getService().addToAccessControlList(qualifiedObjectAssociationIdentifier,
getSecurityService().addToAccessControlList(qualifiedObjectAssociationIdentifier,
null, DefaultActions.READ.name());
getService().addRoleForUser(user, role);
getSecurityService().addRoleForUser(user, role);
logger.info(message);
}
});
@@ -335,16 +335,16 @@ public class SecurityResource extends AbstractSecurityResource {
@Produces("application/json;charset=UTF-8")
public Response getRoles(@QueryParam(USERNAME) String username) {
final JSONArray result = new JSONArray();
final User user = username == null ? getService().getCurrentUser() : getService().getUserByName(username);
final User user = username == null ? getSecurityService().getCurrentUser() : getSecurityService().getUserByName(username);
if (user != null) {
getService().checkCurrentUserReadPermission(user);
getSecurityService().checkCurrentUserReadPermission(user);
for (final Role role : user.getRoles()) {
final JSONObject roleJson = new JSONObject();
result.add(roleJson);
final TypeRelativeObjectIdentifier associationTypeIdentifier = PermissionAndRoleAssociation.get(role, user);
final QualifiedObjectIdentifier qualifiedObjectIdentifierForRoleAssociation = SecuredSecurityTypes.ROLE_ASSOCIATION.getQualifiedObjectIdentifier(associationTypeIdentifier);
if (getService().hasCurrentUserAnyPermission(qualifiedObjectIdentifierForRoleAssociation.getPermission(DefaultActions.READ))) {
final OwnershipAnnotation ownership = getService().getOwnership(qualifiedObjectIdentifierForRoleAssociation);
if (getSecurityService().hasCurrentUserAnyPermission(qualifiedObjectIdentifierForRoleAssociation.getPermission(DefaultActions.READ))) {
final OwnershipAnnotation ownership = getSecurityService().getOwnership(qualifiedObjectIdentifierForRoleAssociation);
roleJson.put(ROLE_DEFINITION_ID, role.getRoleDefinition().getIdAsString());
roleJson.put(ROLE_NAME, role.getRoleDefinition().getName());
roleJson.put(OWNING_GROUP_ID, ownership == null ? null : ownership.getAnnotation() == null ? null : ownership.getAnnotation().getTenantOwner() == null ? null : ownership.getAnnotation().getTenantOwner().getId().toString());
@@ -364,17 +364,17 @@ public class SecurityResource extends AbstractSecurityResource {
public Response updateUser(@Context UriInfo uriInfo, @QueryParam(USERNAME) String username,
@QueryParam(EMAIL) String email, @QueryParam(FULL_NAME) String fullName,
@QueryParam(COMPANY) String company) {
if (!getService().hasCurrentUserUpdatePermission(getService().getUserByName(username))) {
if (!getSecurityService().hasCurrentUserUpdatePermission(getSecurityService().getUserByName(username))) {
return Response.status(Status.UNAUTHORIZED).build();
} else {
try {
final User user = getService().getUserByName(username);
final User user = getSecurityService().getUserByName(username);
if (user == null) {
return Response.status(Status.PRECONDITION_FAILED).entity("User "+username+" not known").build();
} else {
getService().updateUserProperties(username, fullName, company, user.getLocale());
getSecurityService().updateUserProperties(username, fullName, company, user.getLocale());
if (!Util.equalsWithNull(user.getEmail(), email)) {
getService().updateSimpleUserEmail(username, email, getEmailValidationBaseURL(uriInfo));
getSecurityService().updateSimpleUserEmail(username, email, getEmailValidationBaseURL(uriInfo));
}
return Response.ok().build();
}
@@ -409,7 +409,7 @@ public class SecurityResource extends AbstractSecurityResource {
@Path(LOGOUT_METHOD)
@Produces("application/json;charset=UTF-8")
public Response logoutPost() {
getService().logout();
getSecurityService().logout();
return Response.ok().build();
}
@@ -437,7 +437,7 @@ public class SecurityResource extends AbstractSecurityResource {
public Response respondToRemoveAccessTokenForUser(final String username) {
final Response result;
getService().removeAccessToken(username);
getSecurityService().removeAccessToken(username);
result = respondWithAccessTokenForAuthenticatedSubject();
return result;
}
@@ -471,12 +471,12 @@ public class SecurityResource extends AbstractSecurityResource {
Response respondWithAccessTokenForUser(final String username) {
JSONObject response = new JSONObject();
response.put(USERNAME, username);
getService().checkCurrentUserReadPermission(getService().getUserByName(username));
getSecurityService().checkCurrentUserReadPermission(getSecurityService().getUserByName(username));
String accessToken;
if (getService().hasCurrentUserUpdatePermission(getService().getUserByName(username))) {
accessToken = getService().getOrCreateAccessToken(username);
if (getSecurityService().hasCurrentUserUpdatePermission(getSecurityService().getUserByName(username))) {
accessToken = getSecurityService().getOrCreateAccessToken(username);
} else {
accessToken = getService().getAccessToken(username);
accessToken = getSecurityService().getAccessToken(username);
if (accessToken == null) {
throw new AuthorizationException(
"No access token was found and the permission to create one is lacking.");
@@ -55,7 +55,7 @@ public class UserGroupResource extends AbstractSecurityResource {
Response response;
try {
final UUID groupId = UUID.fromString(userGroupId);
final UserGroup usergroup = getService().getUserGroup(groupId);
final UserGroup usergroup = getSecurityService().getUserGroup(groupId);
response = handleExistingUserGroup(usergroup);
} catch (IllegalArgumentException e) {
response = Response.status(Status.BAD_REQUEST).entity("Invalid group id.").build();
@@ -68,7 +68,7 @@ public class UserGroupResource extends AbstractSecurityResource {
public Response getUserGroupByName(@QueryParam(KEY_GROUP_NAME) String userGroupName) {
Response response;
if (userGroupName != null) {
final UserGroup usergroup = getService().getUserGroupByName(userGroupName);
final UserGroup usergroup = getSecurityService().getUserGroupByName(userGroupName);
response = handleExistingUserGroup(usergroup);
} else {
response = Response.status(Status.BAD_REQUEST).entity("Please specify a groupname.").build();
@@ -82,7 +82,7 @@ public class UserGroupResource extends AbstractSecurityResource {
@Produces("application/json;charset=UTF-8")
public Response getUserGroupsCurrentUserIsPartOf() throws ParseException {
Response response = null;
User user = getService().getCurrentUser();
User user = getSecurityService().getCurrentUser();
if (user != null) {
JSONObject root = new JSONObject();
JSONArray groups = new JSONArray();
@@ -102,11 +102,11 @@ public class UserGroupResource extends AbstractSecurityResource {
@Produces("application/json;charset=UTF-8")
public Response getReadableUserGroupsForCurrentUser(@QueryParam("userName") String userName) {
Response response = null;
final User user = userName != null ? getService().getUserByName(userName) : getService().getCurrentUser();
if (user != null && getService().hasCurrentUserReadPermission(user)) {
final User user = userName != null ? getSecurityService().getUserByName(userName) : getSecurityService().getCurrentUser();
if (user != null && getSecurityService().hasCurrentUserReadPermission(user)) {
final List<UserGroup> userGroups = new ArrayList<>();
getService().getUserGroupList().forEach(ug -> {
if (getService().getSecurityManager().isPermitted(
getSecurityService().getUserGroupList().forEach(ug -> {
if (getSecurityService().getSecurityManager().isPermitted(
new SimplePrincipalCollection(user.getName(), user.getName()),
ug.getIdentifier().getPermission(DefaultActions.READ).toString())) {
userGroups.add(ug);
@@ -130,7 +130,7 @@ public class UserGroupResource extends AbstractSecurityResource {
if (usergroup == null) {
response = Response.status(Status.BAD_REQUEST).entity("Usergroup with this id does not exist.").build();
} else {
if (getService().hasCurrentUserReadPermission(usergroup)) {
if (getSecurityService().hasCurrentUserReadPermission(usergroup)) {
final JSONObject jsonResult = convertUserGroupToJson(usergroup, /* includingUsers */ true,
/* includingRoles */ true);
response = Response.ok(streamingOutput(jsonResult)).build();
@@ -151,7 +151,7 @@ public class UserGroupResource extends AbstractSecurityResource {
final JSONArray jsonUsersInGroup = new JSONArray();
for (final User user : usergroup.getUsers()) {
// filter users
if (getService().hasCurrentUserReadPermission(user)) {
if (getSecurityService().hasCurrentUserReadPermission(user)) {
jsonUsersInGroup.add(user.getId());
}
}
@@ -162,7 +162,7 @@ public class UserGroupResource extends AbstractSecurityResource {
for (final Map.Entry<RoleDefinition, Boolean> roleDefinition : usergroup.getRoleDefinitionMap()
.entrySet()) {
// filter users
if (getService().hasCurrentUserReadPermission(roleDefinition.getKey())) {
if (getSecurityService().hasCurrentUserReadPermission(roleDefinition.getKey())) {
JSONObject roleJson = new JSONObject();
roleJson.put(KEY_ROLE_ID, roleDefinition.getKey().getId().toString());
roleJson.put(KEY_ROLE_NAME, roleDefinition.getKey().getName());
@@ -182,17 +182,17 @@ public class UserGroupResource extends AbstractSecurityResource {
final Response response;
final JSONObject json = (JSONObject) JSONValue.parse(jsonBody);
final String groupName = (String) json.get(KEY_GROUP_NAME);
final UserGroup existingUserGroup = getService().getUserGroupByName(groupName);
final UserGroup existingUserGroup = getSecurityService().getUserGroupByName(groupName);
if (existingUserGroup != null) {
response = Response.status(Status.BAD_REQUEST).entity("Usergroup with this name already exists.").build();
} else {
UUID newTenantId = UUID.randomUUID();
UserGroup group = getService().setOwnershipWithoutCheckPermissionForObjectCreationAndRevertOnError(
UserGroup group = getSecurityService().setOwnershipWithoutCheckPermissionForObjectCreationAndRevertOnError(
SecuredSecurityTypes.USER_GROUP, UserGroupImpl.getTypeRelativeObjectIdentifier(newTenantId),
groupName, () -> {
UserGroup userGroup;
try {
userGroup = getService().createUserGroup(newTenantId, groupName);
userGroup = getSecurityService().createUserGroup(newTenantId, groupName);
} catch (UserGroupManagementException e) {
throw new UserGroupManagementException(e.getMessage());
}
@@ -214,14 +214,14 @@ public class UserGroupResource extends AbstractSecurityResource {
Response response;
try {
final UUID groupId = UUID.fromString(userGroupId);
final UserGroup usergroup = getService().getUserGroup(groupId);
final UserGroup usergroup = getSecurityService().getUserGroup(groupId);
if (usergroup == null) {
response = Response.status(Status.BAD_REQUEST).entity("Usergroup with this name does not exist.")
.build();
} else {
getService().checkPermissionAndDeleteOwnershipForObjectRemoval(usergroup, () -> {
getService().deleteUserGroup(usergroup);
getSecurityService().checkPermissionAndDeleteOwnershipForObjectRemoval(usergroup, () -> {
getSecurityService().deleteUserGroup(usergroup);
});
response = Response.status(Status.NO_CONTENT).build();
}
@@ -240,28 +240,28 @@ public class UserGroupResource extends AbstractSecurityResource {
Response response;
try {
final UUID groupId = UUID.fromString(userGroupId);
final UserGroup usergroup = getService().getUserGroup(groupId);
final UserGroup usergroup = getSecurityService().getUserGroup(groupId);
if (usergroup == null) {
response = Response.status(Status.BAD_REQUEST).entity("Usergroup with this name does not exist.")
.build();
} else {
final User user = getService().getUserByName(username);
final User user = getSecurityService().getUserByName(username);
if (user == null) {
response = Response.status(Status.BAD_REQUEST).entity("User with this name does not exist.")
.build();
} else {
if (getService().hasCurrentUserReadPermission(usergroup)) {
if (getSecurityService().hasCurrentUserReadPermission(usergroup)) {
if (Util.contains(usergroup.getUsers(), user)) {
response = Response.status(Status.BAD_REQUEST).entity("User is already in this group.")
.build();
} else {
if (getService().hasCurrentUserUpdatePermission(usergroup)) {
if (!getService().hasCurrentUserMetaPermissionsOfRoleDefinitionsWithQualification(
if (getSecurityService().hasCurrentUserUpdatePermission(usergroup)) {
if (!getSecurityService().hasCurrentUserMetaPermissionsOfRoleDefinitionsWithQualification(
usergroup.getRoleDefinitionMap().keySet(), new Ownership(null, usergroup))) {
response = Response.status(Status.UNAUTHORIZED).build();
} else {
getService().addUserToUserGroup(usergroup, user);
getSecurityService().addUserToUserGroup(usergroup, user);
response = Response.ok().build();
}
} else {
@@ -287,22 +287,22 @@ public class UserGroupResource extends AbstractSecurityResource {
Response response;
try {
final UUID groupId = UUID.fromString(userGroupId);
final UserGroup usergroup = getService().getUserGroup(groupId);
final UserGroup usergroup = getSecurityService().getUserGroup(groupId);
if (usergroup == null) {
response = Response.status(Status.BAD_REQUEST).entity("Usergroup with this name does not exist.")
.build();
} else {
final User user = getService().getUserByName(username);
final User user = getSecurityService().getUserByName(username);
if (user == null) {
response = Response.status(Status.BAD_REQUEST).entity("User with this name does not exist.")
.build();
} else {
if (getService().hasCurrentUserReadPermission(usergroup)) {
if (getSecurityService().hasCurrentUserReadPermission(usergroup)) {
if (!Util.contains(usergroup.getUsers(), user)) {
response = Response.status(Status.BAD_REQUEST).entity("User is not in this group.").build();
} else {
if (getService().hasCurrentUserUpdatePermission(usergroup)) {
getService().removeUserFromUserGroup(usergroup, user);
if (getSecurityService().hasCurrentUserUpdatePermission(usergroup)) {
getSecurityService().removeUserFromUserGroup(usergroup, user);
response = Response.status(Status.NO_CONTENT).build();
} else {
response = Response.status(Status.UNAUTHORIZED).build();
@@ -329,28 +329,28 @@ public class UserGroupResource extends AbstractSecurityResource {
try {
final UUID groupId = UUID.fromString(userGroupId);
final UUID roleId = UUID.fromString(roleIdString);
final UserGroup usergroup = getService().getUserGroup(groupId);
final UserGroup usergroup = getSecurityService().getUserGroup(groupId);
if (usergroup == null) {
response = Response.status(Status.BAD_REQUEST).entity(
String.format("Usergroup with ID %s does not exist.", userGroupId)).build();
} else {
final RoleDefinition role = getService().getRoleDefinition(roleId);
final RoleDefinition role = getSecurityService().getRoleDefinition(roleId);
if (role == null) {
response = Response.status(Status.BAD_REQUEST).entity(String.format("Role with ID %s does not exist.", roleId)).build();
} else {
if (getService().hasCurrentUserUpdatePermission(usergroup)
&& getService().hasCurrentUserReadPermission(role)) {
if (getSecurityService().hasCurrentUserUpdatePermission(usergroup)
&& getSecurityService().hasCurrentUserReadPermission(role)) {
final Boolean forAll = usergroup.getRoleAssociation(role);
JSONObject jsonBody = (JSONObject) JSONValue.parse(body);
boolean roleForAll = Boolean.valueOf((String) jsonBody.get(KEY_FOR_ALL));
if (forAll == null || forAll != roleForAll) {
if (!getService().hasCurrentUserMetaPermissionsOfRoleDefinitionWithQualification(role,
if (!getSecurityService().hasCurrentUserMetaPermissionsOfRoleDefinitionWithQualification(role,
new Ownership(null, usergroup))) {
response = Response.status(Status.UNAUTHORIZED)
.entity(String.format("Not permitted to add role %s to group %s",
role.getName(), usergroup.getName())).build();
} else {
getService().putRoleDefinitionToUserGroup(usergroup, role, roleForAll);
getSecurityService().putRoleDefinitionToUserGroup(usergroup, role, roleForAll);
response = Response.ok().build();
}
} else {
@@ -377,27 +377,27 @@ public class UserGroupResource extends AbstractSecurityResource {
Response response;
try {
final UUID groupId = UUID.fromString(userGroupId);
final UserGroup usergroup = getService().getUserGroup(groupId);
final UserGroup usergroup = getSecurityService().getUserGroup(groupId);
final UUID roleId = UUID.fromString(roleIdString);
if (usergroup == null) {
response = Response.status(Status.BAD_REQUEST).entity("Usergroup with this name does not exist.")
.build();
} else {
final RoleDefinition role = getService().getRoleDefinition(roleId);
final RoleDefinition role = getSecurityService().getRoleDefinition(roleId);
if (role == null) {
response = Response.status(Status.BAD_REQUEST).entity("Role with this id does not exist.").build();
} else {
if (getService().hasCurrentUserUpdatePermission(usergroup)
&& getService().hasCurrentUserReadPermission(role)) {
if (getSecurityService().hasCurrentUserUpdatePermission(usergroup)
&& getSecurityService().hasCurrentUserReadPermission(role)) {
if (usergroup.getRoleAssociation(role) != null) {
if (!getService().hasCurrentUserMetaPermissionsOfRoleDefinitionWithQualification(role,
if (!getSecurityService().hasCurrentUserMetaPermissionsOfRoleDefinitionWithQualification(role,
new Ownership(null, usergroup))) {
response = Response
.status(Status.UNAUTHORIZED).entity(String
.format("Not permitted to remove role %s from group", role.getName()))
.build();
} else {
getService().removeRoleDefintionFromUserGroup(usergroup, role);
getSecurityService().removeRoleDefintionFromUserGroup(usergroup, role);
response = Response.status(Status.NO_CONTENT).build();
}
} else {
@@ -421,9 +421,9 @@ public class UserGroupResource extends AbstractSecurityResource {
public Response setDefaultTenantForCurrentServerAndUser(@QueryParam("tenantGroup") UUID tenantId)
throws ParseException {
Response response = null;
User user = getService().getCurrentUser();
User user = getSecurityService().getCurrentUser();
if (user != null) {
getService().setDefaultTenantForCurrentServerForUser(user.getName(), tenantId);
getSecurityService().setDefaultTenantForCurrentServerForUser(user.getName(), tenantId);
response = Response.ok().build();
} else {
response = Response.status(401).build();
@@ -437,17 +437,17 @@ public class UserGroupResource extends AbstractSecurityResource {
public Response addGroupToUserWithoutPermissionOnUser(@QueryParam("userName") String userName,
@QueryParam("groupId") UUID userGroupId) {
Response response = null;
final User user = getService().getUserByName(userName);
final User user = getSecurityService().getUserByName(userName);
if (user != null) {
final UserGroup userGroup = getService().getUserGroup(userGroupId);
final UserGroup userGroup = getSecurityService().getUserGroup(userGroupId);
if (userGroup != null) {
if (!Util.contains(userGroup.getUsers(), user)) {
if (getService().hasCurrentUserUpdatePermission(userGroup)) {
if (!getService().hasCurrentUserMetaPermissionsOfRoleDefinitionsWithQualification(
if (getSecurityService().hasCurrentUserUpdatePermission(userGroup)) {
if (!getSecurityService().hasCurrentUserMetaPermissionsOfRoleDefinitionsWithQualification(
userGroup.getRoleDefinitionMap().keySet(), new Ownership(null, userGroup))) {
response = Response.status(Status.UNAUTHORIZED).build();
} else {
getService().addUserToUserGroup(userGroup, user);
getSecurityService().addUserToUserGroup(userGroup, user);
response = Response.ok().build();
}
} else {