@JsonRequest @ApiOperation(value = "Check API Keys") @Path("/check-api-keys") public List<Boolean> checkApiKeys(@ApiParam("keys") List<ProjectApiKeys> keys, @ApiParam("project") String project) { return keys.stream().map(key -> { try { Consumer<String> stringConsumer = e -> { if (!e.equals(project.toLowerCase(Locale.ENGLISH))) { throw new RakamException(FORBIDDEN); } }; Optional.ofNullable(key.masterKey()).map(k -> apiKeyService.getProjectOfApiKey(k, MASTER_KEY)).ifPresent(stringConsumer); Optional.ofNullable(key.readKey()).map(k -> apiKeyService.getProjectOfApiKey(k, READ_KEY)).ifPresent(stringConsumer); Optional.ofNullable(key.writeKey()).map(k -> apiKeyService.getProjectOfApiKey(k, WRITE_KEY)).ifPresent(stringConsumer); return true; } catch (RakamException e) { return false; } }).collect(Collectors.toList()); }
@ApiOperation(value = "Get project stats") @JsonRequest @Path("/stats") public Map<String, Metastore.Stats> getStats(@BodyParam List<String> apiKeys) { Map<String, String> keys = new LinkedHashMap<>(); for (String apiKey : apiKeys) { String project; try { project = apiKeyService.getProjectOfApiKey(apiKey, READ_KEY); } catch (RakamException e) { if (e.getStatusCode() == FORBIDDEN) { continue; } throw e; } keys.put(project, apiKey); } Map<String, Metastore.Stats> stats = metastore.getStats(keys.keySet()); if (stats == null) { return ImmutableMap.of(); } return stats.entrySet().stream() .collect(Collectors.toMap(e -> keys.get(e.getKey()), e -> e.getValue())); }
@GET @IgnoreApi @ApiOperation(value = "Collect event", response = Integer.class) @Path("/collect/*") public void collectGet(RakamHttpRequest request) { String identifier = request.path().substring(20); List<String> writeKeyList = request.params().get("write_key"); if (writeKeyList == null || writeKeyList.isEmpty()) { throw new RakamException("write_key query parameter is null", FORBIDDEN); } String project = apiKeyService.getProjectOfApiKey(writeKeyList.get(0), WRITE_KEY); call(request, project, identifier, request.params(), request.headers(), null); }
@Path("/data") @GET @IgnoreApi public void data(RakamHttpRequest request) { Map<String, List<String>> params = request.params(); List<String> api_key = params.get("read_key"); if (api_key == null || api_key.isEmpty()) { request.response("\"read_key is missing\"", BAD_REQUEST).end(); return; } // since this endpoint is created for clients to read the ab-testing rule, // the permission is WRITE_KEY String project = apiKeyService.getProjectOfApiKey(api_key.get(0), ApiKeyService.AccessKeyType.WRITE_KEY); request.response(JsonHelper.encodeAsBytes(metadata.getReports(project))) .end(); }
@POST @IgnoreApi @ApiOperation(value = "Collect event", response = Integer.class) @Path("/collect/*") public void collectPost(RakamHttpRequest request) { String identifier = request.path().substring(20); List<String> writeKeyList = request.params().get("write_key"); if (writeKeyList == null || writeKeyList.isEmpty()) { throw new RakamException("write_key query parameter is null", FORBIDDEN); } String project = apiKeyService.getProjectOfApiKey(writeKeyList.get(0), WRITE_KEY); request.bodyHandler(inputStream -> { String data; try { data = new String(ByteStreams.toByteArray(inputStream), CharsetUtil.UTF_8); } catch (IOException e) { throw new RakamException("Unable to parse data: " + e.getMessage(), INTERNAL_SERVER_ERROR); } call(request, project, identifier, request.params(), request.headers(), data); }); }
String project = apiKeyService.getProjectOfApiKey(master_key, MASTER_KEY);
String project = apiKeyService.getProjectOfApiKey(apiKey, type); return new RequestContext(project.toLowerCase(Locale.ENGLISH), apiKey, access);
@Test public void testInvalidApiKeys() throws Exception { getApiKeyService().createApiKeys(PROJECT_NAME); try { getApiKeyService().getProjectOfApiKey("invalidKey", AccessKeyType.READ_KEY); fail(); } catch (RakamException e) { } try { getApiKeyService().getProjectOfApiKey("invalidKey", AccessKeyType.WRITE_KEY); fail(); } catch (RakamException e) { } try { getApiKeyService().getProjectOfApiKey("invalidKey", AccessKeyType.MASTER_KEY); fail(); } catch (RakamException e) { } }
@Test public void testCreateApiKeys() throws Exception { ApiKeyService.ProjectApiKeys testing = getApiKeyService().createApiKeys(PROJECT_NAME); assertEquals(getApiKeyService().getProjectOfApiKey(testing.readKey(), AccessKeyType.READ_KEY), PROJECT_NAME); assertEquals(getApiKeyService().getProjectOfApiKey(testing.writeKey(), AccessKeyType.WRITE_KEY), PROJECT_NAME); assertEquals(getApiKeyService().getProjectOfApiKey(testing.masterKey(), AccessKeyType.MASTER_KEY), PROJECT_NAME); }
@ApiOperation(value = "Batch operation on a single user properties", request = SingleUserBatchOperationRequest.class, response = Integer.class, authorizations = {@Authorization(value = "write_key")}) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/batch") @JsonRequest public void batchSingleUserOperations(RakamHttpRequest request) { request.bodyHandler(s -> { SingleUserBatchOperationRequest req; try { req = JsonHelper.read(s, SingleUserBatchOperationRequest.class); } catch (Exception e) { returnError(request, e.getMessage(), BAD_REQUEST); return; } String project = apiKeyService.getProjectOfApiKey(req.api.apiKey, WRITE_KEY); InetAddress socketAddress = ((InetSocketAddress) request.context().channel() .remoteAddress()).getAddress(); DefaultFullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, wrappedBuffer(OK_MESSAGE)); List<Cookie> cookies = mapEvent(mapper -> mapper.map(project, req.data, new HttpRequestParams(request), socketAddress)); service.batch(project, req.data); setBrowser(request, response); if (cookies != null && !cookies.isEmpty()) { response.headers().add(SET_COOKIE, STRICT.encode(cookies)); } request.response(response).end(); }); }
@JsonRequest @ApiOperation(value = "Merge user with anonymous id", authorizations = @Authorization(value = "write_key")) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/merge") @IgnoreApi @AllowCookie public void mergeUser(RakamHttpRequest request, @BodyParam MergeRequest mergeRequest) { // TODO: what if a user sends real user ids instead of its previous anonymous id? if (!config.getEnableUserMapping()) { throw new RakamException("The feature is not supported", PRECONDITION_FAILED); } Object anonymousId = mergeRequest.anonymousId; DefaultFullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, wrappedBuffer(OK_MESSAGE)); setBrowser(request, response); if (anonymousId == null) { throw new RakamException("Anonymous id is required", BAD_REQUEST); } String project = apiKeyService.getProjectOfApiKey(mergeRequest.api.apiKey, WRITE_KEY); service.merge(project, mergeRequest.id, anonymousId, Instant.ofEpochMilli(mergeRequest.createdAt), Instant.ofEpochMilli(mergeRequest.mergedAt)); request.response(response).end(); }
@Path("/listen") @GET @ApiImplicitParams({ @ApiImplicitParam(name = "project", dataType = "string", paramType = "query"), }) @ApiOperation(value = "Listen all mailboxes", consumes = "text/event-stream", produces = "text/event-stream", authorizations = @Authorization(value = "read_key") ) @IgnoreApi public void listenMails(RakamHttpRequest request) { RakamHttpRequest.StreamResponse response = request.streamResponse(); List<String> apiKey = request.params().get("api_key"); if (apiKey == null || apiKey.isEmpty()) { response.send("result", encode(HttpServer.errorMessage("api_key query parameter is required", HttpResponseStatus.BAD_REQUEST))).end(); return; } List<String> api_key = request.params().get("read_key"); String project = apiKeyService.getProjectOfApiKey(api_key.get(0), ApiKeyService.AccessKeyType.READ_KEY); UserMailboxStorage.MessageListener update = storage.listenAllUsers(project, data -> response.send("update", data.serialize())); response.listenClose(() -> update.shutdown()); }
@JsonRequest @ApiOperation(value = "Unset user property") @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/unset_properties") @AllowCookie public SuccessMessage unsetProperty(@ApiParam("api") User.UserContext api, @ApiParam("id") Object id, @ApiParam("properties") List<String> properties) { String project = apiKeyService.getProjectOfApiKey(api.apiKey, WRITE_KEY); service.unsetProperties(project, id, properties); return SuccessMessage.success(); }
@JsonRequest @ApiOperation(value = "Set user properties once", request = User.class, response = Integer.class) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/set_properties_once") public void setPropertiesOnce(RakamHttpRequest request) { request.bodyHandler(s -> { User req; try { req = JsonHelper.readSafe(s, User.class); } catch (IOException e) { returnError(request, e.getMessage(), BAD_REQUEST); return; } String project = apiKeyService.getProjectOfApiKey(req.api.apiKey, WRITE_KEY); DefaultFullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, wrappedBuffer(OK_MESSAGE)); response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN, request.headers().get(ORIGIN)); List<Cookie> cookies = mapProperties(project, req, request); if (cookies != null) { response.headers().add(SET_COOKIE, STRICT.encode(cookies)); } String headerList = getHeaderList(response.headers().iterator()); if (headerList != null) { response.headers().set(ACCESS_CONTROL_EXPOSE_HEADERS, headerList); } // TODO: we may cache these values and reduce the db hit. service.setUserPropertiesOnce(project, req.id, req.properties); request.response(OK_MESSAGE).end(); }); }
project = apiKeyService.getProjectOfApiKey(context.apiKey, apiKey == null ? WRITE_KEY : (ApiKeyService.AccessKeyType) apiKey); } catch (RakamException e) { masterKey = true; try { project = apiKeyService.getProjectOfApiKey(context.apiKey, MASTER_KEY); } catch (RakamException e) { if (e.getStatusCode() == FORBIDDEN) {
String project = apiKeyService.getProjectOfApiKey(req.api.apiKey, MASTER_KEY);
@JsonRequest @ApiOperation(value = "Set user property", authorizations = @Authorization(value = "master_key")) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/increment_property") @AllowCookie public SuccessMessage incrementProperty(@ApiParam("api") User.UserContext api, @ApiParam("id") String user, @ApiParam("property") String property, @ApiParam("value") double value) { String project = apiKeyService.getProjectOfApiKey(api.apiKey, WRITE_KEY); service.incrementProperty(project, user, property, value); return SuccessMessage.success(); }
@Test public void testRevokeApiKeys() throws Exception { ApiKeyService.ProjectApiKeys apiKeys = getApiKeyService().createApiKeys(PROJECT_NAME); getApiKeyService().revokeApiKeys(PROJECT_NAME, apiKeys.masterKey()); try { getApiKeyService().getProjectOfApiKey(apiKeys.readKey(), AccessKeyType.READ_KEY); fail(); } catch (RakamException e) { } try { getApiKeyService().getProjectOfApiKey(apiKeys.writeKey(), AccessKeyType.WRITE_KEY); fail(); } catch (RakamException e) { } try { getApiKeyService().getProjectOfApiKey(apiKeys.masterKey(), AccessKeyType.MASTER_KEY); fail(); } catch (RakamException e) { } } }
String project = apiKeyService.getProjectOfApiKey(req.api.apiKey, WRITE_KEY);
project = apiKeyService.getProjectOfApiKey(apiKey.get(0), keyType); } catch (RakamException e) { if (e.getStatusCode() == FORBIDDEN) {