blob: 088197a86f89c6ca984245da396d6ff137d04239 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sling.jackrabbit.usermanager.impl.post;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.http.HttpServletResponse;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceNotFoundException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HtmlResponse;
import org.apache.sling.jackrabbit.usermanager.DeleteAuthorizables;
import org.apache.sling.jackrabbit.usermanager.DeleteGroup;
import org.apache.sling.jackrabbit.usermanager.DeleteUser;
import org.apache.sling.jackrabbit.usermanager.impl.resource.AuthorizableResourceProvider;
import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.SlingPostConstants;
/**
* <h2>Rest Service Description</h2>
* <p>
* Deletes an Authorizable, currently a user or a group. Maps on to nodes of resourceType <code>sling/users</code> or <code>sling/users</code> like
* <code>/rep:system/rep:userManager/rep:users</code> or <code>/rep:system/rep:userManager/rep:groups</code> mapped to a resource url
* <code>/system/userManager/user</code> or <code>/system/userManager/group</code>. This servlet responds at
* <code>/system/userManager/user.delete.html</code> or <code>/system/userManager/group.delete.html</code>.
* The servlet also responds to single delete requests eg <code>/system/userManager/group/newGroup.delete.html</code>
* </p>
* <h4>Methods</h4>
* <ul>
* <li>POST</li>
* </ul>
* <h4>Post Parameters</h4>
* <dl>
* <dt>:applyTo</dt>
* <dd>An array of relative resource references to Authorizables to be deleted, if this parameter is present, the url is ignored and all the Authorizables in the list are removed.</dd>
* </dl>
* <h4>Response</h4>
* <dl>
* <dt>200</dt>
* <dd>Success, no body.</dd>
* <dt>404</dt>
* <dd>The resource was not found</dd>
* <dt>500</dt>
* <dd>Failure</dd>
* </dl>
* <h4>Example</h4>
*
* <code>
* curl -Fgo=1 http://localhost:8080/system/userManager/user/ieb.delete.html
* </code>
*
*
* @scr.component immediate="true" label="%deleteAuthorizable.post.operation.name"
* description="%deleteAuthorizable.post.operation.description"
* @scr.service interface="javax.servlet.Servlet"
* @scr.service interface="org.apache.sling.jackrabbit.usermanager.DeleteUser"
* @scr.service interface="org.apache.sling.jackrabbit.usermanager.DeleteGroup"
* @scr.service interface="org.apache.sling.jackrabbit.usermanager.DeleteAuthorizables"
* @scr.property name="sling.servlet.resourceTypes" values.0="sling/user"
* values.1="sling/group" values.2="sling/userManager"
* @scr.property name="sling.servlet.methods" value="POST"
* @scr.property name="sling.servlet.selectors" value="delete"
*/
public class DeleteAuthorizableServlet extends AbstractPostServlet
implements DeleteUser, DeleteGroup, DeleteAuthorizables {
private static final long serialVersionUID = 5874621724096106496L;
/*
* (non-Javadoc)
* @see
* org.apache.sling.jackrabbit.usermanager.post.AbstractAuthorizablePostServlet
* #handleOperation(org.apache.sling.api.SlingHttpServletRequest,
* org.apache.sling.api.servlets.HtmlResponse, java.util.List)
*/
@Override
protected void handleOperation(SlingHttpServletRequest request,
HtmlResponse htmlResponse, List<Modification> changes)
throws RepositoryException {
Session session = request.getResourceResolver().adaptTo(Session.class);
Resource resource = request.getResource();
String[] applyTo = request.getParameterValues(SlingPostConstants.RP_APPLY_TO);
if (applyTo != null) {
deleteAuthorizables(session,
resource,
applyTo,
changes);
} else {
Authorizable item = resource.adaptTo(Authorizable.class);
if (item == null) {
String msg = "Missing source " + resource.getPath()
+ " for delete";
htmlResponse.setStatus(HttpServletResponse.SC_NOT_FOUND, msg);
throw new ResourceNotFoundException(msg);
} else {
if (item instanceof User) {
deleteUser(session, item.getID(), changes);
} else if (item instanceof Group) {
deleteGroup(session, item.getID(), changes);
}
}
}
}
/* (non-Javadoc)
* @see org.apache.sling.jackrabbit.usermanager.DeleteUser#deleteUser(javax.jcr.Session, java.lang.String, java.util.List)
*/
public void deleteUser(Session jcrSession, String name,
List<Modification> changes) throws RepositoryException {
User user;
UserManager userManager = AccessControlUtil.getUserManager(jcrSession);
Authorizable authorizable = userManager.getAuthorizable(name);
if (authorizable instanceof User) {
user = (User)authorizable;
} else {
throw new ResourceNotFoundException(
"User to delete could not be determined");
}
String userPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_USER_PREFIX
+ user.getID();
user.remove();
changes.add(Modification.onDeleted(userPath));
}
/* (non-Javadoc)
* @see org.apache.sling.jackrabbit.usermanager.DeleteGroup#deleteGroup(javax.jcr.Session, java.lang.String, java.util.List)
*/
public void deleteGroup(Session jcrSession,
String name,
List<Modification> changes) throws RepositoryException {
Group group;
UserManager userManager = AccessControlUtil.getUserManager(jcrSession);
Authorizable authorizable = userManager.getAuthorizable(name);
if (authorizable instanceof Group) {
group = (Group)authorizable;
} else {
throw new ResourceNotFoundException(
"Group to delete could not be determined");
}
String groupPath = AuthorizableResourceProvider.SYSTEM_USER_MANAGER_GROUP_PREFIX
+ group.getID();
group.remove();
changes.add(Modification.onDeleted(groupPath));
}
/* (non-Javadoc)
* @see org.apache.sling.jackrabbit.usermanager.DeleteAuthorizables#deleteAuthorizables(javax.jcr.Session, org.apache.sling.api.resource.Resource, java.lang.String[], java.util.List)
*/
public void deleteAuthorizables(Session jcrSession,
Resource baseResource,
String[] paths,
List<Modification> changes)
throws RepositoryException {
ApplyToIterator iterator = new ApplyToIterator(baseResource, paths);
while (iterator.hasNext()) {
Resource resource = iterator.next();
Authorizable item = resource.adaptTo(Authorizable.class);
if (item != null) {
item.remove();
changes.add(Modification.onDeleted(resource.getPath()));
}
}
}
private static class ApplyToIterator implements Iterator<Resource> {
private final ResourceResolver resolver;
private final Resource baseResource;
private final String [] paths;
private int pathIndex;
private Resource nextResource;
ApplyToIterator(Resource baseResource, String [] paths) {
this.resolver = baseResource.getResourceResolver();
this.baseResource = baseResource;
this.paths = paths;
this.pathIndex = 0;
nextResource = seek();
}
public boolean hasNext() {
return nextResource != null;
}
public Resource next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Resource result = nextResource;
nextResource = seek();
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
private Resource seek() {
while (pathIndex < paths.length) {
String path = paths[pathIndex];
pathIndex++;
Resource res = resolver.getResource(baseResource, path);
if (res != null) {
return res;
}
}
// no more elements in the array
return null;
}
}
}