@Test public void crestCreateIsAllowed() throws SSOException, DelegationException { // Given... final Set<String> actions = new HashSet<>(Arrays.asList("MODIFY")); final DelegationPermission permission = new DelegationPermission( "/abc", "rest", "1.0", "policies", "modify", actions, EXTENSIONS, DUMB_FUNC); given(factory.newInstance("/abc", "rest", "1.0", "policies", "modify", actions, EXTENSIONS)) .willReturn(permission); given(subjectContext.getCallerSSOToken()).willReturn(token); given(evaluator.isAllowed(eq(token), eq(permission), eq(ENVIRONMENT))).willReturn(true); JsonValue jsonValue = json(object(field("someKey", "someValue"))); Promise<ResourceResponse, ResourceException> promise = Promises.newResultPromise(Responses.newResourceResponse("1", "1.0", jsonValue)); given(provider.createInstance(isA(Context.class), isA(CreateRequest.class))) .willReturn(promise); // When... final FilterChain chain = AuthorizationFilters.createAuthorizationFilter(provider, module); final Router router = new Router(); router.addRoute(RoutingMode.STARTS_WITH, Router.uriTemplate("/policies"), chain); final RealmContext context = new RealmContext(subjectContext); context.setSubRealm("abc", "abc"); final CreateRequest request = Requests.newCreateRequest("/policies", JsonValue.json(new Object())); Promise<ResourceResponse, ResourceException> result = router.handleCreate(context, request); // Then... assertThat(result).succeeded().withContent().stringAt("someKey").isEqualTo("someValue"); }
@Test public void crestRequestNotAllowed() throws SSOException, DelegationException { // Given... final Set<String> actions = new HashSet<>(Arrays.asList("MODIFY")); final DelegationPermission permission = new DelegationPermission( "/abc", "rest", "1.0", "policies", "modify", actions, EXTENSIONS, DUMB_FUNC); given(factory.newInstance("/abc", "rest", "1.0", "policies", "modify", actions, EXTENSIONS)) .willReturn(permission); given(subjectContext.getCallerSSOToken()).willReturn(token); given(evaluator.isAllowed(eq(token), eq(permission), eq(ENVIRONMENT))).willReturn(false); // When... final FilterChain chain = AuthorizationFilters.createAuthorizationFilter(provider, module); final Router router = new Router(); router.addRoute(RoutingMode.STARTS_WITH, Router.uriTemplate("/policies"), chain); final RealmContext context = new RealmContext(subjectContext); context.setSubRealm("abc", "abc"); final CreateRequest request = Requests.newCreateRequest("/policies", JsonValue.json(new Object())); Promise<ResourceResponse, ResourceException> promise = router.handleCreate(context, request); // Then... assertThat(promise).failedWithException().isInstanceOf(ForbiddenException.class); }
/** * Creates the underlying backend policies. * * <p>NOTE: if the creation of the underlying policies fails, any successfully created underlying * policies will be attempted to be deleted but if the deletion fails, then the underlying * policies may be in an inconsistent state. * * @param context The request context. * @param policies The underlying policies to create. * @return A promise containing the list of created underlying policies or a {@code * ResourceException} if the creation fails. */ public Promise<List<Resource>, ResourceException> createPolicies( ServerContext context, Set<JsonValue> policies) { final List<String> policyIds = new ArrayList<String>(); List<Promise<Resource, ResourceException>> promises = new ArrayList<Promise<Resource, ResourceException>>(); for (JsonValue policy : policies) { promises.add( policyResource .handleCreate(context, Requests.newCreateRequest("", policy)) .thenOnResult( new ResultHandler<Resource>() { @Override public void handleResult(Resource result) { // Save ids of created policies, in case a latter policy fails to be created, // so we can roll back. policyIds.add(result.getId()); } })); } return Promises.when(promises) .thenAsync( new AsyncFunction<List<Resource>, List<Resource>, ResourceException>() { @Override public Promise<List<Resource>, ResourceException> apply(List<Resource> value) { return Promises.newResultPromise(value); } }, new UmaPolicyCreateFailureHandler(context, policyIds)); }
void doPost(final HttpServletRequest req, final HttpServletResponse resp) { try { // Parse out the required API versions. final AcceptAPIVersion acceptVersion = parseAcceptAPIVersion(req); // Prepare response. prepareResponse(req, resp); // Validate request. preprocessRequest(req); rejectIfNoneMatch(req); rejectIfMatch(req); final Map<String, String[]> parameters = req.getParameterMap(); final String action = asSingleValue(PARAM_ACTION, getParameter(req, PARAM_ACTION)); if (action.equalsIgnoreCase(ACTION_ID_CREATE)) { final JsonValue content = getJsonContent(req); final CreateRequest request = Requests.newCreateRequest(getResourceName(req), content); for (final Map.Entry<String, String[]> p : parameters.entrySet()) { final String name = p.getKey(); final String[] values = p.getValue(); if (parseCommonParameter(name, values, request)) { continue; } else if (name.equalsIgnoreCase(PARAM_ACTION)) { // Ignore - already handled. } else if (HttpUtils.isMultiPartRequest(req.getContentType())) { // Ignore - multipart content adds form parts to the parameter set } else { request.setAdditionalParameter(name, asSingleValue(name, values)); } } doRequest(req, resp, acceptVersion, request); } else { // Action request. final JsonValue content = getJsonActionContent(req); final ActionRequest request = Requests.newActionRequest(getResourceName(req), action).setContent(content); for (final Map.Entry<String, String[]> p : parameters.entrySet()) { final String name = p.getKey(); final String[] values = p.getValue(); if (parseCommonParameter(name, values, request)) { continue; } else if (name.equalsIgnoreCase(PARAM_ACTION)) { // Ignore - already handled. } else if (HttpUtils.isMultiPartRequest(req.getContentType())) { // Ignore - multipart content adds form parts to the parameter set } else { request.setAdditionalParameter(name, asSingleValue(name, values)); } } doRequest(req, resp, acceptVersion, request); } } catch (final Exception e) { fail(req, resp, e); } }
@Test public void testCreateSchedule() throws Exception { // given final CreateRequest createRequest = Requests.newCreateRequest("scheduler", "test1", testScheduleConfig); // when Promise<ResourceResponse, ResourceException> promise = schedulerService.handleCreate(new RootContext(), createRequest); // then AssertJPromiseAssert.assertThat(promise).isNotNull().succeeded(); ResourceResponse resourceResponse = promise.getOrThrow(); assertThat(resourceResponse.getContent().asMap()).isEqualTo(testScheduleConfig.asMap()); }
@Test public void testResource() throws Exception { ScriptName scriptName = new ScriptName("resource", getLanguageName()); ScriptEntry scriptEntry = getScriptRegistry().takeScript(scriptName); Assert.assertNotNull(scriptEntry); Script script = scriptEntry.getScript(new RootContext()); // Set RequestLevel Scope script.put("ketto", 2); script.putSafe("callback", mock(Function.class)); JsonValue createContent = new JsonValue(new LinkedHashMap<String, Object>()); createContent.put("externalId", "701984"); createContent.put("userName", "*****@*****.**"); createContent.put( "assignedDashboard", Arrays.asList("Salesforce", "Google", "ConstantContact")); createContent.put("displayName", "Babs Jensen"); createContent.put("nickName", "Babs"); JsonValue updateContent = createContent.copy(); updateContent.put("_id", UUID.randomUUID().toString()); updateContent.put("profileUrl", "https://login.example.com/bjensen"); final Context context = new ApiInfoContext( new SecurityContext(new RootContext(), "*****@*****.**", null), "", ""); script.put("context", context); CreateRequest createRequest = Requests.newCreateRequest("/Users", "701984", createContent); script.put("createRequest", createRequest); ReadRequest readRequest = Requests.newReadRequest("/Users/701984"); script.put("readRequest", readRequest); UpdateRequest updateRequest = Requests.newUpdateRequest("/Users/701984", updateContent); script.put("updateRequest", updateRequest); PatchRequest patchRequest = Requests.newPatchRequest("/Users/701984", PatchOperation.replace("userName", "ddoe")); script.put("patchRequest", patchRequest); QueryRequest queryRequest = Requests.newQueryRequest("/Users/"); script.put("queryRequest", queryRequest); DeleteRequest deleteRequest = Requests.newDeleteRequest("/Users/701984"); script.put("deleteRequest", deleteRequest); ActionRequest actionRequest = Requests.newActionRequest("/Users", "clear"); script.put("actionRequest", actionRequest); script.eval(); }
/** * Persist the supplied {@link JsonValue} {@code value} as the new state of this singleton * relationship on {@code resourceId}. * * <p><em>This is currently the only means of creating an instance of this singleton</em> * * @param context The context of this request * @param resourceId Id of the resource relation fields in value are to be memebers of * @param value A {@link JsonValue} map of relationship fields and their values * @return The persisted instance of {@code value} */ @Override public Promise<JsonValue, ResourceException> setRelationshipValueForResource( Context context, String resourceId, JsonValue value) { if (value.isNotNull()) { try { final JsonValue id = value.get(FIELD_ID); // Update if we got an id, otherwise replace if (id != null && id.isNotNull()) { final UpdateRequest updateRequest = Requests.newUpdateRequest("", value); updateRequest.setAdditionalParameter(PARAM_FIRST_ID, resourceId); return updateInstance(context, value.get(FIELD_ID).asString(), updateRequest) .then( new Function<ResourceResponse, JsonValue, ResourceException>() { @Override public JsonValue apply(ResourceResponse resourceResponse) throws ResourceException { return resourceResponse.getContent(); } }); } else { // no id, replace current instance clear(context, resourceId); final CreateRequest createRequest = Requests.newCreateRequest("", value); createRequest.setAdditionalParameter(PARAM_FIRST_ID, resourceId); return createInstance(context, createRequest) .then( new Function<ResourceResponse, JsonValue, ResourceException>() { @Override public JsonValue apply(ResourceResponse resourceResponse) throws ResourceException { return resourceResponse.getContent(); } }); } } catch (ResourceException e) { return e.asPromise(); } } else { clear(context, resourceId); return newResultPromise(json(null)); } }
/** * Calls buildAuditEvent() and invokes the request to the audit path. * * @param connectionFactory factory used to make crest call to audit service. */ public final Promise<ResourceResponse, ResourceException> log( ConfigAuditState configAuditState, Request request, Context context, ConnectionFactory connectionFactory) { try { JsonValue before = configAuditState.getBefore(); JsonValue after = configAuditState.getAfter(); // Get authenticationId from security context, if it exists. String authenticationId = (context.containsContext(SecurityContext.class)) ? context.asContext(SecurityContext.class).getAuthenticationId() : null; // Build the event utilizing the config builder. AuditEvent auditEvent = ConfigAuditEventBuilder.configEvent() .resourceOperationFromRequest(request) .authenticationFromSecurityContext(context) .runAs(authenticationId) .transactionIdFromRootContext(context) .revision(configAuditState.getRevision()) .timestamp(System.currentTimeMillis()) .eventName(CONFIG_AUDIT_EVENT_NAME) .before(null != before ? before.toString() : "") .after(null != after ? after.toString() : "") .changedFields(getChangedFields(before, after)) .toEvent(); return connectionFactory .getConnection() .create(context, Requests.newCreateRequest(AUDIT_CONFIG_REST_PATH, auditEvent.getValue())) .asPromise(); } catch (ResourceException e) { LOGGER.error("had trouble logging audit event for config changes.", e); return e.asPromise(); } catch (Exception e) { LOGGER.error("had trouble logging audit event for config changes.", e); return new InternalServerErrorException(e.getMessage(), e).asPromise(); } }
/** * TODO: Description. * * @throws SynchronizationException TODO. */ void create() throws SynchronizationException { _id = UUID.randomUUID().toString(); // client-assigned identifier JsonValue jv = toJsonValue(); try { CreateRequest r = Requests.newCreateRequest(linkId(null), _id, jv); Resource resource = mapping .getService() .getConnectionFactory() .getConnection() .create(mapping.getService().getServerContext(), r); this._id = resource.getId(); this._rev = resource.getRevision(); this.initialized = true; } catch (ResourceException ose) { LOGGER.debug("Failed to create link", ose); throw new SynchronizationException(ose); } }
void doPut(final HttpServletRequest req, final HttpServletResponse resp) { try { // Parse out the required API versions. final AcceptAPIVersion acceptVersion = parseAcceptAPIVersion(req); // Prepare response. prepareResponse(req, resp); // Validate request. preprocessRequest(req); if (req.getHeader(HEADER_IF_MATCH) != null && req.getHeader(HEADER_IF_NONE_MATCH) != null) { // FIXME: i18n throw new PreconditionFailedException( "Simultaneous use of If-Match and If-None-Match not " + "supported for PUT requests"); } final Map<String, String[]> parameters = req.getParameterMap(); final JsonValue content = getJsonContent(req); final String rev = getIfNoneMatch(req); if (ETAG_ANY.equals(rev)) { // This is a create with a user provided resource ID: split the // path into the parent resource name and resource ID. final String resourceName = getResourceName(req); final int i = resourceName.lastIndexOf('/'); final CreateRequest request; if (resourceName.isEmpty()) { // FIXME: i18n. throw new BadRequestException("No new resource ID in HTTP PUT request"); } else if (i < 0) { // We have a pathInfo of the form "{id}" request = Requests.newCreateRequest(EMPTY_STRING, content); request.setNewResourceId(resourceName); } else { // We have a pathInfo of the form "{container}/{id}" request = Requests.newCreateRequest(resourceName.substring(0, i), content); request.setNewResourceId(resourceName.substring(i + 1)); } for (final Map.Entry<String, String[]> p : parameters.entrySet()) { final String name = p.getKey(); final String[] values = p.getValue(); if (HttpUtils.isMultiPartRequest(req.getContentType())) { // Ignore - multipart content adds form parts to the parameter set } else if (parseCommonParameter(name, values, request)) { continue; } else { request.setAdditionalParameter(name, asSingleValue(name, values)); } } doRequest(req, resp, acceptVersion, request); } else { final UpdateRequest request = Requests.newUpdateRequest(getResourceName(req), content).setRevision(getIfMatch(req)); for (final Map.Entry<String, String[]> p : parameters.entrySet()) { final String name = p.getKey(); final String[] values = p.getValue(); if (HttpUtils.isMultiPartRequest(req.getContentType())) { // Ignore - multipart content adds form parts to the parameter set } else if (parseCommonParameter(name, values, request)) { continue; } else { request.setAdditionalParameter(name, asSingleValue(name, values)); } } doRequest(req, resp, acceptVersion, request); } } catch (final Exception e) { fail(req, resp, e); } }
/** * Stores the <code>Dictionary</code> under the given <code>pid</code>. * * @param pid The identifier of the dictionary. * @param properties The <code>Dictionary</code> to store. * @throws IOException If an error occurrs storing the dictionary. If this exception is thrown, it * is expected, that {@link #exists(String) exists(pid} returns <code>false</code>. */ public void store(String pid, Dictionary properties) throws IOException { logger.debug("Store call for {} {}", pid, properties); // Store config handling settings in memory if (pid.startsWith("org.apache.felix.fileinstall")) { tempStore.put(pid, properties); return; } try { if (isReady(0) && requireRepository) { String id = pidToId(pid); Map<String, Object> obj = dictToMap(properties); JsonValue content = new JsonValue(obj); String configResourceId = ConfigBootstrapHelper.getId( content.get(ConfigBootstrapHelper.CONFIG_ALIAS).asString(), content.get(ConfigBootstrapHelper.SERVICE_PID).asString(), content.get(ConfigBootstrapHelper.SERVICE_FACTORY_PID).asString()); String configString = (String) obj.get(JSONEnhancedConfig.JSON_CONFIG_PROPERTY); Map<Object, Object> configMap = deserializeConfig(configString); if (configMap != null) { configMap.put("_id", configResourceId); } obj.put(JSONEnhancedConfig.JSON_CONFIG_PROPERTY, configMap); Map<String, Object> existing = null; try { ReadRequest readRequest = Requests.newReadRequest(id); existing = repo.read(readRequest).getContent().asMap(); } catch (NotFoundException ex) { // Just detect that it doesn't exist } if (existing != null) { String rev = (String) existing.get("_rev"); existing.remove("_rev"); existing.remove("_id"); obj.remove("_rev"); // beware, this means _id and _rev should not be in config file obj.remove("_id"); // beware, this means _id and _rev should not be in config file obj.remove(RepoPersistenceManager.BUNDLE_LOCATION); obj.remove(RepoPersistenceManager.FELIX_FILEINSTALL_FILENAME); if (!existing.equals(obj)) { logger.trace("Not matching {} {}", existing, obj); boolean retry; do { retry = false; try { UpdateRequest r = Requests.newUpdateRequest(id, new JsonValue(obj)); r.setRevision(rev); repo.update(r); } catch (PreconditionFailedException ex) { logger.debug("Concurrent change during update, retrying {} {}", pid, rev); ReadRequest readRequest = Requests.newReadRequest(id); existing = repo.read(readRequest).getContent().asMap(); retry = true; } } while (retry); logger.debug("Updated existing config {} {} {}", new Object[] {pid, rev, obj}); } else { logger.debug( "Existing config same as store request, ignoring {} {} {}", new Object[] {pid, rev, obj}); } } else { logger.trace("Creating: {} {} ", id, obj); // This may create a new (empty) configuration, which felix marks with // _felix___cm__newConfiguration=true String newResourceId = id.substring(CONFIG_CONTEXT_PREFIX.length()); CreateRequest createRequest = Requests.newCreateRequest(CONFIG_CONTEXT_PREFIX, new JsonValue(obj)); createRequest.setNewResourceId(newResourceId); obj = repo.create(createRequest).getContent().asMap(); logger.debug("Stored new config in repository {} {}", pid, obj); } } else { tempStore.put(pid, properties); logger.debug("Stored in memory {} {}", pid, properties); } } catch (ResourceException ex) { throw new IOException("Failed to store configuration in repository: " + ex.getMessage(), ex); } }