Skip to content

Commit

Permalink
Add Patch users (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
orius123 authored Jul 14, 2024
1 parent 28608a0 commit 5c9da10
Show file tree
Hide file tree
Showing 12 changed files with 207 additions and 46 deletions.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ try {
// Handle the error
}

// Update will override all fields as is. Use carefully.
// Update will override all fields as is. Use carefully. Use patch instead if providing select fields.
try {
us.update("[email protected]", UserRequest.builder()
.email("[email protected]")
Expand All @@ -723,7 +723,17 @@ try {
.tenantId("tenant-ID1")
.roleNames(Arrays.asList("role-name1"),
AssociatedTenant.builder()
.tenantId("tenant-ID2")))));
.tenantId("tenant-ID2"))))
.build());
} catch (DescopeException de) {
// Handle the error
}

// Patch will override provided fields but will leave other fields untouched.
try {
us.patch("[email protected]", PatchUserRequest.builder()
.name("Desmond Copeland")
.build());
} catch (DescopeException de) {
// Handle the error
}
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.26</version>
<version>1.0.27</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
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.26</version>
<version>1.0.27</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
3 changes: 2 additions & 1 deletion src/main/java/com/descope/literals/Routes.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public static class ManagementEndPoints {
// User
public static final String CREATE_USER_LINK = "/v1/mgmt/user/create";
public static final String CREATE_USERS_BATCH_LINK = "/v1/mgmt/user/create/batch";
public static final String PATCH_USER_LINK = "/v1/mgmt/user/patch";
public static final String UPDATE_USER_LINK = "/v1/mgmt/user/update";
public static final String DELETE_USER_LINK = "/v1/mgmt/user/delete";
public static final String DELETE_ALL_TEST_USERS_LINK = "/v1/mgmt/user/test/delete/all";
Expand Down Expand Up @@ -125,7 +126,7 @@ public static class ManagementEndPoints {
public static final String LOAD_ALL_TENANTS_LINK = "/v1/mgmt/tenant/all";
public static final String TENANT_SEARCH_ALL_LINK = "/v1/mgmt/tenant/search";
public static final String GET_TENANT_SETTINGS_LINK = "/v1/mgmt/tenant/settings";

// SSO
public static final String SSO_GET_SETTINGS_LINK = "/v1/mgmt/sso/settings";
public static final String SSO_DELETE_SETTINGS_LINK = "/v1/mgmt/sso/settings";
Expand Down
49 changes: 49 additions & 0 deletions src/main/java/com/descope/model/user/request/PatchUserRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.descope.model.user.request;

import static com.descope.utils.CollectionUtils.addIfNotNull;

import com.descope.model.auth.AssociatedTenant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class PatchUserRequest {
String name;
String givenName;
String middleName;
String familyName;
String phone;
String email;
List<String> roleNames;
List<AssociatedTenant> userTenants;
Map<String, Object> customAttributes;
String picture;
Boolean verifiedEmail;
Boolean verifiedPhone;
List<String> ssoAppIds;

public Map<String, Object> toMap() {
Map<String, Object> m = new HashMap<>();
addIfNotNull(m, "email", email);
addIfNotNull(m, "verifiedEmail", verifiedEmail);
addIfNotNull(m, "phone", phone);
addIfNotNull(m, "verifiedPhone", verifiedPhone);
addIfNotNull(m, "givenName", givenName);
addIfNotNull(m, "middleName", middleName);
addIfNotNull(m, "familyName", familyName);
addIfNotNull(m, "roleNames", roleNames);
addIfNotNull(m, "userTenants", userTenants);
addIfNotNull(m, "customAttributes", customAttributes);
addIfNotNull(m, "picture", picture);
addIfNotNull(m, "ssoAppIDs", ssoAppIds);
return m;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.descope.model.user.request;


import static com.descope.utils.CollectionUtils.addIfNotNull;

import com.descope.model.auth.AssociatedTenant;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/descope/proxy/ApiProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public interface ApiProxy {

<B, R> R post(URI uri, B body, Class<R> returnClz);

<B, R> R patch(URI uri, B body, Class<R> returnClz);

<B, R> R postAndGetArray(URI uri, B body, TypeReference<R> typeReference);

<B, R> R delete(URI uri, B body, Class<R> returnClz);
Expand Down
15 changes: 13 additions & 2 deletions src/main/java/com/descope/proxy/impl/AbstractProxyImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public R handleResponse(ClassicHttpResponse response) throws HttpException, IOEx
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
final ByteArrayOutputStream bs = new ByteArrayOutputStream();
final TeeInputStream tee = new TeeInputStream(res.getEntity().getContent(), bs, true);

if (res.getCode() < 200 || response.getCode() > 299) {
if (res.getCode() == 429) { // Rate limit from infra
throw new RateLimitExceededException(
Expand Down Expand Up @@ -118,7 +118,7 @@ public R handleResponse(ClassicHttpResponse response) throws HttpException, IOEx
throw ServerCommonException.parseResponseError("Error parsing response", bs.toString(), e);
}
}
}
}
});
}
}
Expand Down Expand Up @@ -167,6 +167,17 @@ protected <B, R> R post(URI uri, B body, TypeReference<R> typeReference) {
return exchange(builder.build(), null, typeReference);
}

@SneakyThrows
protected <B, R> R patch(URI uri, B body, Class<R> returnClz) {
final ClassicRequestBuilder builder = ClassicRequestBuilder.patch(uri);
if (body != null) {
final ObjectMapper objectMapper = new ObjectMapper().setSerializationInclusion(Include.NON_NULL);
final byte[] payload = objectMapper.writeValueAsBytes(body);
builder.setEntity(new ByteArrayEntity(payload, ContentType.APPLICATION_JSON));
}
return exchange(builder.build(), returnClz, null);
}

protected <R> R get(URI uri, Class<R> returnClz) {
return exchange(ClassicRequestBuilder.get(uri).build(), returnClz, null);
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/descope/proxy/impl/ApiProxyImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public <B, R> R post(URI uri, B body, Class<R> returnClz) {
return super.post(uri, body, returnClz);
}

@Override
public <B, R> R patch(URI uri, B body, Class<R> returnClz) {
return super.patch(uri, body, returnClz);
}

@Override
public <B, R> R postAndGetArray(URI uri, B body, TypeReference<R> typeReference) {
return super.post(uri, body, typeReference);
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/descope/sdk/mgmt/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.descope.exception.DescopeException;
import com.descope.model.auth.InviteOptions;
import com.descope.model.user.request.BatchUserRequest;
import com.descope.model.user.request.PatchUserRequest;
import com.descope.model.user.request.UserRequest;
import com.descope.model.user.request.UserSearchRequest;
import com.descope.model.user.response.AllUsersResponseDetails;
Expand Down Expand Up @@ -90,6 +91,7 @@ public interface UserService {
*
* <p>IMPORTANT: All parameters will override whatever values are currently set in the existing
* user. Use carefully.
* Instead, use Patch if you don't want to pass all parameters.
*
* @param loginId The loginID is required and will determine what the user will use to sign in,
* make sure the login id is unique for test.
Expand All @@ -100,6 +102,18 @@ public interface UserService {
*/
UserResponseDetails update(String loginId, UserRequest request) throws DescopeException;

/**
* Patches an existing user.
*
* <p>Only the fields that are set in the request will be updated.
*
* @param loginId The loginID is required and will determine which user to update.
* @param request The request containing the fields to be updated. Fields not set will remain unchanged.
* @return {@link UserResponseDetails UserResponseDetails} containing the updated user details.
* @throws DescopeException If there occurs any exception, a subtype of this exception will be thrown.
*/
UserResponseDetails patch(String loginId, PatchUserRequest request) throws DescopeException;

/**
* Logout user from all devices.
*
Expand Down
27 changes: 24 additions & 3 deletions src/main/java/com/descope/sdk/mgmt/impl/UserServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static com.descope.literals.Routes.ManagementEndPoints.LOAD_USER_LINK;
import static com.descope.literals.Routes.ManagementEndPoints.LOGOUT_USER_LINK;
import static com.descope.literals.Routes.ManagementEndPoints.MAGIC_LINK_FOR_TEST_LINK;
import static com.descope.literals.Routes.ManagementEndPoints.PATCH_USER_LINK;
import static com.descope.literals.Routes.ManagementEndPoints.UPDATE_CUSTOM_ATTRIBUTE_LINK;
import static com.descope.literals.Routes.ManagementEndPoints.UPDATE_PICTURE_LINK;
import static com.descope.literals.Routes.ManagementEndPoints.UPDATE_USER_LINK;
Expand Down Expand Up @@ -46,6 +47,7 @@
import com.descope.model.user.request.GenerateEmbeddedLinkRequest;
import com.descope.model.user.request.MagicLinkTestUserRequest;
import com.descope.model.user.request.OTPTestUserRequest;
import com.descope.model.user.request.PatchUserRequest;
import com.descope.model.user.request.UserRequest;
import com.descope.model.user.request.UserSearchRequest;
import com.descope.model.user.response.AllUsersResponseDetails;
Expand Down Expand Up @@ -151,6 +153,21 @@ public UsersBatchResponse inviteBatch(List<BatchUserRequest> users, InviteOption
return apiProxy.post(createUsersUri, req, UsersBatchResponse.class);
}

@Override
public UserResponseDetails patch(String loginId, PatchUserRequest request) throws DescopeException {
if (StringUtils.isBlank(loginId)) {
throw ServerCommonException.invalidArgument("Login ID");
}
if (request == null) {
request = new PatchUserRequest();
}
Map<String, Object> req = mapOf("loginId", loginId);
req.putAll(request.toMap());
URI patchUserUri = composePatchUserUri();
ApiProxy apiProxy = getApiProxy();
return apiProxy.patch(patchUserUri, req, UserResponseDetails.class);
}

@Override
public UserResponseDetails update(String loginId, UserRequest request) throws DescopeException {
if (StringUtils.isBlank(loginId)) {
Expand Down Expand Up @@ -583,7 +600,7 @@ public List<UserHistoryResponse> history(List<String> userIds) throws DescopeExc
}
ApiProxy apiProxy = getApiProxy();
return apiProxy.postAndGetArray(getUri(USER_HISTORY_LINK), userIds,
new TypeReference<List<UserHistoryResponse>>() {});
new TypeReference<List<UserHistoryResponse>>() {});
}

public String generateEmbeddedLink(
Expand All @@ -594,8 +611,8 @@ public String generateEmbeddedLink(
URI generateEmbeddedLinkUri = composeGenerateEmbeddedLink();
GenerateEmbeddedLinkRequest request = new GenerateEmbeddedLinkRequest(loginId, customClaims);
ApiProxy apiProxy = getApiProxy();
GenerateEmbeddedLinkResponse response =
apiProxy.post(generateEmbeddedLinkUri, request, GenerateEmbeddedLinkResponse.class);
GenerateEmbeddedLinkResponse response = apiProxy.post(generateEmbeddedLinkUri, request,
GenerateEmbeddedLinkResponse.class);
return response.getToken();
}

Expand All @@ -607,6 +624,10 @@ private URI composeCreateBatchUsersUri() {
return getUri(CREATE_USERS_BATCH_LINK);
}

private URI composePatchUserUri() {
return getUri(PATCH_USER_LINK);
}

private URI composeUpdateUserUri() {
return getUri(UPDATE_USER_LINK);
}
Expand Down
Loading

0 comments on commit 5c9da10

Please sign in to comment.