001/* 002 * Copyright 2015-2019 Ping Identity Corporation 003 * 004 * This program is free software; you can redistribute it and/or modify 005 * it under the terms of the GNU General Public License (GPLv2 only) 006 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 007 * as published by the Free Software Foundation. 008 * 009 * This program is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU General Public License for more details. 013 * 014 * You should have received a copy of the GNU General Public License 015 * along with this program; if not, see <http://www.gnu.org/licenses>. 016 */ 017 018package com.unboundid.scim2.server.providers; 019 020import com.fasterxml.jackson.core.JsonParser; 021import com.fasterxml.jackson.databind.ObjectReader; 022import com.unboundid.scim2.common.messages.SearchRequest; 023import com.unboundid.scim2.common.utils.JsonUtils; 024import com.unboundid.scim2.common.utils.StaticUtils; 025import com.unboundid.scim2.server.utils.ServerUtils; 026 027import javax.annotation.Priority; 028import javax.ws.rs.BadRequestException; 029import javax.ws.rs.HttpMethod; 030import javax.ws.rs.NotSupportedException; 031import javax.ws.rs.Priorities; 032import javax.ws.rs.container.ContainerRequestContext; 033import javax.ws.rs.container.ContainerRequestFilter; 034import javax.ws.rs.container.PreMatching; 035import javax.ws.rs.core.MediaType; 036import javax.ws.rs.core.NoContentException; 037import javax.ws.rs.core.PathSegment; 038import javax.ws.rs.core.UriBuilder; 039import javax.ws.rs.ext.Provider; 040import java.io.IOException; 041import java.util.List; 042 043import static com.unboundid.scim2.common.utils.ApiConstants.*; 044 045/** 046 * A ContainerRequestFilter implementation to convert a search request using 047 * HTTP POST combine with the "{@code .search}" path extension to a regular search 048 * using HTTP GET. 049 */ 050@Provider 051@PreMatching 052@Priority(Priorities.ENTITY_CODER) 053public class DotSearchFilter implements ContainerRequestFilter 054{ 055 /** 056 * {@inheritDoc} 057 */ 058 public void filter(final ContainerRequestContext requestContext) 059 throws IOException 060 { 061 if(requestContext.getMethod().equals(HttpMethod.POST) && 062 requestContext.getUriInfo().getPath().endsWith( 063 SEARCH_WITH_POST_PATH_EXTENSION)) 064 065 { 066 if(requestContext.getMediaType() == null || 067 !(requestContext.getMediaType().isCompatible( 068 ServerUtils.MEDIA_TYPE_SCIM_TYPE) || 069 requestContext.getMediaType().isCompatible( 070 MediaType.APPLICATION_JSON_TYPE))) 071 { 072 throw new NotSupportedException(); 073 } 074 075 ObjectReader reader = 076 JsonUtils.getObjectReader().forType(SearchRequest.class); 077 JsonParser p = reader.getFactory().createParser( 078 requestContext.getEntityStream()); 079 if(p.nextToken() == null) 080 { 081 throw new BadRequestException( 082 new NoContentException("Empty Entity")); 083 } 084 SearchRequest searchRequest = reader.readValue(p); 085 UriBuilder builder = requestContext.getUriInfo().getBaseUriBuilder(); 086 List<PathSegment> pathSegments = 087 requestContext.getUriInfo().getPathSegments(); 088 for(int i = 0; i < pathSegments.size() - 1; i ++) 089 { 090 builder.path(pathSegments.get(i).getPath()); 091 } 092 if(searchRequest.getAttributes() != null) 093 { 094 builder.queryParam(QUERY_PARAMETER_ATTRIBUTES, 095 StaticUtils.collectionToString(searchRequest.getAttributes(), ",")); 096 } 097 if(searchRequest.getExcludedAttributes() != null) 098 { 099 builder.queryParam(QUERY_PARAMETER_EXCLUDED_ATTRIBUTES, 100 StaticUtils.collectionToString( 101 searchRequest.getExcludedAttributes(), ",")); 102 } 103 if(searchRequest.getFilter() != null) 104 { 105 builder.queryParam(QUERY_PARAMETER_FILTER, 106 searchRequest.getFilter()); 107 } 108 if(searchRequest.getSortBy() != null) 109 { 110 builder.queryParam(QUERY_PARAMETER_SORT_BY, 111 searchRequest.getSortBy()); 112 } 113 if(searchRequest.getSortOrder() != null) 114 { 115 builder.queryParam(QUERY_PARAMETER_SORT_ORDER, 116 searchRequest.getSortOrder().getName()); 117 } 118 if(searchRequest.getStartIndex() != null) 119 { 120 builder.queryParam(QUERY_PARAMETER_PAGE_START_INDEX, 121 searchRequest.getStartIndex()); 122 } 123 if(searchRequest.getCount() != null) 124 { 125 builder.queryParam(QUERY_PARAMETER_PAGE_SIZE, 126 searchRequest.getCount()); 127 } 128 requestContext.setRequestUri(builder.build()); 129 requestContext.setMethod(HttpMethod.GET); 130 } 131 } 132}