Skip to content

Commit

Permalink
Add create audit event (#107)
Browse files Browse the repository at this point in the history
* Add create audit event

* Add audit-create to cli
  • Loading branch information
slavikm authored Apr 16, 2024
1 parent a8fd7cc commit c8863b2
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 25 deletions.
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ These sections show how to use the SDK to perform API management functions. Befo
7. [Query SSO Groups](#query-sso-groups)
8. [Manage Flows](#manage-flows)
9. [Manage JWTs](#manage-jwts)
10. [Search Audit](#search-audit)
10. [Audit](#audit)
11. [Manage Project](#manage-project)

If you wish to run any of our code samples and play with them, check out our [Code Examples](#code-examples) section.
Expand Down Expand Up @@ -1158,7 +1158,7 @@ try {

```

### Search Audit
### Audit

You can perform an audit search for either specific values or full-text across the fields. Audit search is limited to the last 30 days.

Expand All @@ -1176,13 +1176,26 @@ try {
try {
AuditSearchResponse resp = as.search(AuditSearchRequest.builder()
.from(Instant.now().minus(Duration.ofDays(30)))
.actions(Arrays.asList("LoginSucceed")));
.actions(Arrays.asList("LoginSucceed"))
.build());
} catch (DescopeException de) {
// Handle the error
}

```
You can also create audit event with data

```java
try {
as.createEvent(AuditCreateRequest.builder()
.userId("some-id")
.actorId("some-actor-id")
.type(AuditType.INFO)
.action("some-action-name")
.build());
} catch (DescopeException de) {
// Handle the error
}
```
### Manage Project

You can change the project name, as well as to clone the current project to a new one.
Expand Down
2 changes: 1 addition & 1 deletion examples/management-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<dependency>
<groupId>com.descope</groupId>
<artifactId>java-sdk</artifactId>
<version>1.0.16</version>
<version>1.0.17</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
Expand Down
65 changes: 65 additions & 0 deletions examples/management-cli/src/main/java/com/descope/AuditCreate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.descope;

import com.descope.client.DescopeClient;
import com.descope.enums.AuditType;
import com.descope.exception.DescopeException;
import com.descope.model.audit.AuditSearchRequest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.Callable;
import org.apache.commons.lang3.StringUtils;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

@Command(name = "audit-create", description = "Create an audit event")
public class AuditCreate extends HelpBase implements Callable<Integer> {

@Option(names = { "-u", "--user"}, description = "User ID in the event")
String userId;

@Option(names = { "-i", "--actor"}, description = "Actor ID in the event")
String actorId;

@Option(names = { "-t", "--type"}, description = "event type (info, warn, error)")
String type;

@Option(names = { "-a", "--action"}, description = "the name of the action")
String action;

@Option(names = { "-n", "--tenant"}, description = "the tenant for the action")
String tenant;

@Override
public Integer call() throws JsonProcessingException {
int exitCode = 0;
try {
var builder = AuditCreate.builder();
if (StringUtils.isNotBlank(userId)) {
builder.userId(userId);
}
if (StringUtils.isNotBlank(actorId)) {
builder.actorId(actorId);
}
if (StringUtils.isNotBlank(type)) {
builder.type(AuditType.fromString(type));
}
if (StringUtils.isNotBlank(action)) {
builder.action(action);
}
if (StringUtils.isNotBlank(tenant)) {
builder.tenant(tenant);
}
var client = new DescopeClient();
var auditService = client.getManagementServices().getAuditService();
auditService.createEvent(builder.build());
System.out.println("Done");
} catch (DescopeException de) {
exitCode = 1;
System.err.println(String.format("%s - %s", de.getCode(), de.getMessage()));
}
return exitCode;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
RoleDelete.class,
RoleUpdate.class,
RoleLoadAll.class,
AuditSearch.class
AuditSearch.class,
AuditCreate.class
})
public class ManagementCLI implements Callable<Integer> {
@Option(names = { "-h", "--help"}, usageHelp = true, description = "show this help message and exit")
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.descope</groupId>
<artifactId>java-sdk</artifactId>
<modelVersion>4.0.0</modelVersion>
<version>1.0.16</version>
<version>1.0.17</version>
<name>${project.groupId}:${project.artifactId}</name>
<description>Java library used to integrate with Descope.</description>
<url>https://github.com/descope/descope-java</url>
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/com/descope/enums/AuditType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.descope.enums;

import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;

public enum AuditType {
INFO("info"),
WARN("warn"),
ERROR("error");

@Getter
@JsonValue
private final String value;

AuditType(String value) {
this.value = value;
}

public static AuditType fromString(String value) {
if (ERROR.value.equalsIgnoreCase(value)) {
return ERROR;
}
if (WARN.value.equalsIgnoreCase(value)) {
return WARN;
}
return INFO;
}
}
1 change: 1 addition & 0 deletions src/main/java/com/descope/literals/Routes.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ public static class ManagementEndPoints {

// Audit
public static final String MANAGEMENT_AUDIT_SEARCH_LINK = "/v1/mgmt/audit/search";
public static final String MANAGEMENT_AUDIT_CREATE_EVENT = "/v1/mgmt/audit/event";

// Authz
public static final String MANAGEMENT_AUTHZ_SCHEMA_SAVE = "/v1/mgmt/authz/schema/save";
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/descope/model/audit/AuditCreateRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.descope.model.audit;

import com.descope.enums.AuditType;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AuditCreateRequest {
String userId;
String action;
AuditType type;
String actorId;
String tenantId;
Map<String, Object> data;
}
3 changes: 3 additions & 0 deletions src/main/java/com/descope/model/audit/AuditRecord.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.descope.model.audit;

import com.descope.enums.AuditType;
import java.time.Instant;
import java.util.List;
import java.util.Map;
Expand All @@ -15,6 +16,8 @@
public class AuditRecord {
String projectId;
String userId;
String actorId;
AuditType type;
String action;
Instant occurred;
String device;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/descope/model/audit/AuditSearchRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
public class AuditSearchRequest {
/** List of user IDs to filter by. */
List<String> userIds;
/** List of actor user IDs to filter by. */
List<String> actorIds;
/** List of actions to filter by. */
List<String> actions;
/** List of actions to exclude. */
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/com/descope/sdk/mgmt/AuditService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.descope.sdk.mgmt;

import com.descope.exception.DescopeException;
import com.descope.model.audit.AuditCreateRequest;
import com.descope.model.audit.AuditSearchRequest;
import com.descope.model.audit.AuditSearchResponse;

Expand All @@ -12,8 +13,15 @@ public interface AuditService {
*
* @param request request is optional, and if provided, all attributes within it are optional.
* @return {@link AuditSearchResponse}
* @throws DescopeException If there occurs any exception, a subtype of this exception will be
* thrown.
* @throws DescopeException If there occurs any exception, a subtype of this exception will be thrown.
*/
AuditSearchResponse search(AuditSearchRequest request) throws DescopeException;

/**
* Create an audit event.
*
* @param request the parameters for the event
* @throws DescopeException If there occurs any exception, a subtype of this exception will be thrown.
*/
void createEvent(AuditCreateRequest request) throws DescopeException;
}
30 changes: 30 additions & 0 deletions src/main/java/com/descope/sdk/mgmt/impl/AuditServiceImpl.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.descope.sdk.mgmt.impl;

import static com.descope.literals.Routes.ManagementEndPoints.MANAGEMENT_AUDIT_CREATE_EVENT;
import static com.descope.literals.Routes.ManagementEndPoints.MANAGEMENT_AUDIT_SEARCH_LINK;

import com.descope.enums.AuditType;
import com.descope.exception.DescopeException;
import com.descope.exception.ServerCommonException;
import com.descope.model.audit.AuditCreateRequest;
import com.descope.model.audit.AuditRecord;
import com.descope.model.audit.AuditSearchRequest;
import com.descope.model.audit.AuditSearchResponse;
Expand All @@ -19,6 +22,7 @@
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;

class AuditServiceImpl extends ManagementsBase implements AuditService {

Expand All @@ -44,6 +48,7 @@ public AuditSearchResponse search(AuditSearchRequest request) throws DescopeExce
ApiProxy apiProxy = getApiProxy();
ActualAuditSearchRequest actualReq = new ActualAuditSearchRequest(
request.getUserIds(),
request.getActorIds(),
request.getActions(),
request.getExcludedActions(),
request.getDevices(),
Expand All @@ -64,6 +69,8 @@ public AuditSearchResponse search(AuditSearchRequest request) throws DescopeExce
new AuditRecord(
auditRecord.projectId,
auditRecord.userId,
auditRecord.actorId,
AuditType.fromString(auditRecord.type),
auditRecord.action,
Instant.ofEpochMilli(
auditRecord.occurred != null ? Long.parseLong(auditRecord.occurred) : 0),
Expand All @@ -86,6 +93,7 @@ private URI composeSearchUri() {
@AllArgsConstructor
static class ActualAuditSearchRequest {
List<String> userIds;
List<String> actorIds;
List<String> actions;
List<String> excludedActions;
List<String> devices;
Expand All @@ -106,6 +114,8 @@ static class ActualAuditSearchRequest {
static class ActualAuditRecord {
String projectId;
String userId;
String actorId;
String type;
String action;
String occurred;
String device;
Expand All @@ -123,4 +133,24 @@ static class ActualAuditRecord {
static class ActualAuditSearchResponse {
List<ActualAuditRecord> audits;
}

public void createEvent(AuditCreateRequest request) throws DescopeException {
if (request == null) {
throw ServerCommonException.invalidArgument("request");
}
if (StringUtils.isBlank(request.getAction())) {
throw ServerCommonException.invalidArgument("request.action");
}
if (StringUtils.isBlank(request.getActorId())) {
throw ServerCommonException.invalidArgument("request.actorId");
}
if (StringUtils.isBlank(request.getTenantId())) {
throw ServerCommonException.invalidArgument("request.tenantId");
}
if (request.getType() == null) {
throw ServerCommonException.invalidArgument("request.type");
}
ApiProxy apiProxy = getApiProxy();
apiProxy.post(getUri(MANAGEMENT_AUDIT_CREATE_EVENT), request, Void.class);
}
}
Loading

0 comments on commit c8863b2

Please sign in to comment.