@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()); }
return project; }); p.apiKeys.add(ProjectApiKeys.create(r.getString(6), r.getString(7), r.getString(8))); return null; }).iterator();
@Override public String getProjectOfApiKey(String apiKey, AccessKeyType type) { Optional<String> project = apiKeys.entrySet().stream() .filter(e -> e.getValue().stream() .anyMatch(a -> a.getKey(type).equals(apiKey))) .findAny().map(e -> e.getKey()); if (!project.isPresent()) { throw new IllegalStateException(); } return project.get(); }
@Test public void testPrimitiveTypes() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); ImmutableMap<String, Object> properties = ImmutableMap.of( "test", 1L, "test1", false, "test2", Instant.now(), "test3", "test", "test4", LocalDate.now()); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "collection", "test", "api", api, "properties", properties)); Event event = mapper.readValue(bytes, Event.class); assertEquals("test", event.project()); assertEquals("test", event.collection()); assertEquals(api, event.api()); assertEquals(eventBuilder .createEvent("test", properties).properties(), event.properties()); assertEquals(ImmutableSet.copyOf(metastore.getCollection("test", "test")), ImmutableSet.of( new SchemaField("test", FieldType.DOUBLE), new SchemaField("_user", FieldType.STRING), new SchemaField("test1", FieldType.BOOLEAN), new SchemaField("test2", FieldType.TIMESTAMP), new SchemaField("test3", FieldType.STRING), new SchemaField("test4", FieldType.DATE))); }
@Test public void testBatchWithoutProject() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); ImmutableMap<String, Object> props = ImmutableMap.of( "test0", "test", "test1", ImmutableList.of("test"), "test2", false); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "api", api, "events", ImmutableList.of( ImmutableMap.of("collection", "test", "properties", props), ImmutableMap.of("collection", "test", "properties", props)))); EventList events = mapper.readValue(bytes, EventList.class); assertEquals("test", events.project); assertEquals(api, events.api); for (Event event : events.events) { assertEquals("test", event.collection()); assertEquals(eventBuilder.createEvent("test", props).properties(), event.properties()); } }
@Test public void testBatch() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); ImmutableMap<String, Object> props = ImmutableMap.of( "test0", "test", "test1", ImmutableList.of("test"), "test2", false); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "api", api, "events", ImmutableList.of( ImmutableMap.of("collection", "test", "properties", props), ImmutableMap.of("collection", "test", "properties", props)))); EventList events = mapper.readValue(bytes, EventList.class); assertEquals("test", events.project); assertEquals(api, events.api); for (Event event : events.events) { assertEquals("test", event.collection()); assertEquals(eventBuilder.createEvent("test", props).properties(), event.properties()); } }
@Test(expectedExceptions = RakamException.class) public void testInvalidField() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "collection", "test", "api", api, "properties", ImmutableMap.of("test0", "test", "test1", ImmutableList.of("test", "test"), "test2", false), "test", "test" )); Event event = mapper.readValue(bytes, Event.class); ; assertEquals("test", event.project()); assertEquals("test", event.collection()); assertEquals(api, event.api()); assertEquals(eventBuilder .createEvent("test", ImmutableMap.of()).properties(), event.properties()); }
@Test public void testEmptyMap() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "collection", "test", "api", api, "properties", ImmutableMap.of("test", 1, "test2", new HashMap<String, String>() { { put("a", null); } }), "test20", ImmutableMap.of(), "test3", true)); Event event = mapper.readValue(bytes, Event.class); assertEquals("test", event.project()); assertEquals("test", event.collection()); assertEquals(api, event.api()); assertEquals(eventBuilder .createEvent("test", ImmutableMap.of("test", 1.0, "test3", true)).properties(), event.properties()); }
@Override public ProjectApiKeys createApiKeys(String project) { String masterKey = CryptUtil.generateRandomKey(64); String readKey = CryptUtil.generateRandomKey(64); String writeKey = CryptUtil.generateRandomKey(64); try (Connection connection = connectionPool.getConnection()) { PreparedStatement ps = connection.prepareStatement("INSERT INTO api_key " + "(master_key, read_key, write_key, project) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS); ps.setString(1, masterKey); ps.setString(2, readKey); ps.setString(3, writeKey); ps.setString(4, project); ps.executeUpdate(); final ResultSet generatedKeys = ps.getGeneratedKeys(); generatedKeys.next(); } catch (SQLException e) { throw Throwables.propagate(e); } return ProjectApiKeys.create(masterKey, readKey, writeKey); }
@JsonRequest @Path("/give-user-access") @ProtectEndpoint(writeOperation = true) public SuccessMessage giveUserAccess(@Named("user_id") Project project, @ApiParam("email") String email, @ApiParam(value = "keys") ApiKeyService.ProjectApiKeys keys, @ApiParam(value = "read_permission") boolean readPermission, @ApiParam(value = "write_permission") boolean writePermission, @ApiParam(value = "master_permission") boolean masterPermission, @ApiParam(value = "active_ui_features", required = false) WebUserService.UIFeatures activeUiFeatures) { Optional<WebUser> user = service.getUser(project.userId); if (!user.get().projects.stream() .anyMatch(e -> e.apiKeys.stream().anyMatch(a -> a.masterKey() != null))) { throw new RakamException(FORBIDDEN); } service.giveAccessToUser(project.project, user.get().id, email, keys, readPermission, writePermission, masterPermission, activeUiFeatures, Optional.empty()); return SuccessMessage.success(); }
@Test public void testMapType() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); ImmutableMap<String, Object> properties = ImmutableMap.of("test0", "test", "test1", ImmutableMap.of("a", 4.0, "b", 5.0, "c", 6.0, "d", 7.0), "test2", false); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "collection", "test", "api", api, "properties", properties)); Event event = mapper.readValue(bytes, Event.class); assertEquals("test", event.project()); assertEquals("test", event.collection()); assertEquals(api, event.api()); assertEquals(eventBuilder .createEvent("test", properties).properties(), event.properties()); }
@JsonRequest @Path("/update-user-access") @ProtectEndpoint(writeOperation = true) public SuccessMessage updateUserAccess(@Named("user_id") Project project, @ApiParam("email") String email, @ApiParam(value = "read_permission") boolean readPermission, @ApiParam(value = "write_permission") boolean writePermission, @ApiParam(value = "master_permission") boolean masterPermission, @ApiParam(value = "active_ui_features") WebUserService.UIFeatures activeUiFeatures) { Optional<WebUser> user = service.getUser(project.userId); if (!user.get().projects.stream() .anyMatch(e -> e.apiKeys.stream().anyMatch(a -> a.masterKey() != null))) { throw new RakamException(FORBIDDEN); } service.giveAccessToExistingUser(project.project, user.get().id, email, readPermission, writePermission, masterPermission, activeUiFeatures); return SuccessMessage.success(); }
@Test public void testArrayType() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); ImmutableMap<String, Object> properties = ImmutableMap.of("test0", "test", "test1", ImmutableList.of("test", "test"), "test2", false); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "collection", "test", "api", api, "properties", properties)); Event event = mapper.readValue(bytes, Event.class); assertEquals("test", event.project()); assertEquals("test", event.collection()); assertEquals(api, event.api()); assertEquals(eventBuilder .createEvent("test", properties).properties(), event.properties()); }
@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) { } } }
@Test public void testEmptyArray() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "collection", "test", "api", api, "properties", ImmutableMap.of("test", 1, "test2", Arrays.asList(null, null), "test20", Arrays.asList(), "test3", true))); Event event = mapper.readValue(bytes, Event.class); assertEquals("test", event.project()); assertEquals("test", event.collection()); assertEquals(api, event.api()); assertEquals(eventBuilder .createEvent("test", ImmutableMap.of("test", 1.0, "test3", true)).properties(), event.properties()); }
@Test public void testInvalidMap() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "collection", "test", "api", api, "properties", ImmutableMap.of("test1", ImmutableMap.of("test", 1, "test2", "test")))); Event event = mapper.readValue(bytes, Event.class); assertEquals("test", event.project()); assertEquals("test", event.collection()); assertEquals(api, event.api()); assertEquals(eventBuilder .createEvent("test", ImmutableMap.of("test1", ImmutableMap.of("test", 1.0, "test2", 0.0))).properties(), event.properties()); }
@Test public void testSimple() throws Exception { Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "collection", "test", "api", api, "properties", ImmutableMap.of())); Event event = mapper.readValue(bytes, Event.class); assertEquals("test", event.project()); assertEquals("test", event.collection()); assertEquals(api, event.api()); assertEquals(eventBuilder .createEvent("test", ImmutableMap.of()).properties(), event.properties()); }
@Test() public void testObjectSentToInvalidScalarValue() throws Exception { metastore.getOrCreateCollectionFields("test", "test", ImmutableSet.of(new SchemaField("test", FieldType.INTEGER))); Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); ImmutableMap<String, Object> props = ImmutableMap.of( "test", ImmutableList.of("test")); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "api", api, "collection", "test", "properties", props)); Event event = mapper.readValue(bytes, Event.class); assertNull(event.getAttribute("test")); }
@Test public void testObjectSentToScalarValue() throws Exception { metastore.getOrCreateCollectionFields("test", "test", ImmutableSet.of(new SchemaField("test", FieldType.STRING))); Event.EventContext api = Event.EventContext.apiKey(apiKeys.writeKey()); ImmutableMap<String, Object> props = ImmutableMap.of( "test", ImmutableList.of("test")); byte[] bytes = mapper.writeValueAsBytes(ImmutableMap.of( "api", api, "collection", "test", "properties", props)); Event events = mapper.readValue(bytes, Event.class); assertEquals(events.properties().get("test"), "[\"test\"]"); }