mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-03 21:03:48 +00:00
Scim Interface and resource in OM (#21512)
* SCIM interface * removed unwanted code * remove SCIM registration in OM * reverted scim configuration settings, as it is not needed * Added security context to create user * Added scimusername in user jsons * added externalid, scimUsername in createUser * Added security context on create and update groups * Added jakarta imports * Authorization added * Added role, policy and bot for SCIM
This commit is contained in:
parent
f44d81ddf2
commit
023abfda1d
@ -32,6 +32,7 @@ import org.openmetadata.schema.api.security.AuthorizerConfiguration;
|
|||||||
import org.openmetadata.schema.api.security.OpsConfig;
|
import org.openmetadata.schema.api.security.OpsConfig;
|
||||||
import org.openmetadata.schema.api.security.jwt.JWTTokenConfiguration;
|
import org.openmetadata.schema.api.security.jwt.JWTTokenConfiguration;
|
||||||
import org.openmetadata.schema.configuration.LimitsConfiguration;
|
import org.openmetadata.schema.configuration.LimitsConfiguration;
|
||||||
|
import org.openmetadata.schema.security.scim.ScimConfiguration;
|
||||||
import org.openmetadata.schema.security.secrets.SecretsManagerConfiguration;
|
import org.openmetadata.schema.security.secrets.SecretsManagerConfiguration;
|
||||||
import org.openmetadata.schema.service.configuration.elasticsearch.ElasticSearchConfiguration;
|
import org.openmetadata.schema.service.configuration.elasticsearch.ElasticSearchConfiguration;
|
||||||
import org.openmetadata.service.config.OMWebConfiguration;
|
import org.openmetadata.service.config.OMWebConfiguration;
|
||||||
@ -142,6 +143,9 @@ public class OpenMetadataApplicationConfig extends Configuration {
|
|||||||
@Valid
|
@Valid
|
||||||
private ObjectStorageConfiguration objectStorage;
|
private ObjectStorageConfiguration objectStorage;
|
||||||
|
|
||||||
|
@JsonProperty("scimConfiguration")
|
||||||
|
private ScimConfiguration scimConfiguration;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "catalogConfig{"
|
return "catalogConfig{"
|
||||||
|
@ -0,0 +1,358 @@
|
|||||||
|
package org.openmetadata.service.resources.scim;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.ws.rs.Consumes;
|
||||||
|
import jakarta.ws.rs.DELETE;
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.PATCH;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.PUT;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.PathParam;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.core.Context;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import jakarta.ws.rs.core.SecurityContext;
|
||||||
|
import jakarta.ws.rs.core.UriInfo;
|
||||||
|
import java.util.List;
|
||||||
|
import org.openmetadata.schema.EntityInterface;
|
||||||
|
import org.openmetadata.schema.api.scim.ScimGroup;
|
||||||
|
import org.openmetadata.schema.api.scim.ScimPatchOp;
|
||||||
|
import org.openmetadata.schema.api.scim.ScimUser;
|
||||||
|
import org.openmetadata.schema.type.EntityReference;
|
||||||
|
import org.openmetadata.schema.type.MetadataOperation;
|
||||||
|
import org.openmetadata.schema.type.TagLabel;
|
||||||
|
import org.openmetadata.service.scim.ScimProvisioningService;
|
||||||
|
import org.openmetadata.service.security.Authorizer;
|
||||||
|
import org.openmetadata.service.security.policyevaluator.OperationContext;
|
||||||
|
import org.openmetadata.service.security.policyevaluator.ResourceContextInterface;
|
||||||
|
|
||||||
|
@Path("/v1/scim")
|
||||||
|
@Tag(name = "SCIM", description = "SCIM 2.0 compliant user and group provisioning endpoints.")
|
||||||
|
@Produces({"application/json", "application/scim+json"})
|
||||||
|
@Consumes({"application/json", "application/scim+json"})
|
||||||
|
public class ScimResource {
|
||||||
|
|
||||||
|
private static final String SCIM_RESOURCE_NAME = "scim";
|
||||||
|
private final ScimProvisioningService provisioningService;
|
||||||
|
protected final Authorizer authorizer;
|
||||||
|
|
||||||
|
public ScimResource(ScimProvisioningService provisioningService, Authorizer authorizer) {
|
||||||
|
this.provisioningService = provisioningService;
|
||||||
|
this.authorizer = authorizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/")
|
||||||
|
@Operation(
|
||||||
|
operationId = "getServiceProviderConfig",
|
||||||
|
summary = "Get SCIM Service Provider Config",
|
||||||
|
description = "Returns the SCIM service provider configuration.",
|
||||||
|
responses =
|
||||||
|
@ApiResponse(responseCode = "200", description = "SCIM Service Provider Configuration"))
|
||||||
|
public Response getServiceProviderConfig(@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.VIEW_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.getServiceProviderConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/ServiceProviderConfig")
|
||||||
|
@Operation(
|
||||||
|
operationId = "getServiceProviderConfigAlias",
|
||||||
|
summary = "Alias endpoint for SCIM Service Provider Config",
|
||||||
|
description = "Alias endpoint for service provider configuration.",
|
||||||
|
responses =
|
||||||
|
@ApiResponse(responseCode = "200", description = "SCIM Service Provider Configuration"))
|
||||||
|
public Response getServiceProviderConfigAlias(@Context SecurityContext securityContext) {
|
||||||
|
return getServiceProviderConfig(securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/Users")
|
||||||
|
@Operation(
|
||||||
|
operationId = "listScimUsers",
|
||||||
|
summary = "List SCIM users",
|
||||||
|
description = "Lists SCIM users based on optional filters.",
|
||||||
|
responses = @ApiResponse(responseCode = "200", description = "List of SCIM Users"))
|
||||||
|
public Response listUsers(@Context UriInfo uriInfo, @Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.VIEW_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.listUsers(uriInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/Users")
|
||||||
|
@Operation(
|
||||||
|
operationId = "createScimUser",
|
||||||
|
summary = "Create SCIM user",
|
||||||
|
description = "Creates a new SCIM user.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "User created"),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Invalid user input")
|
||||||
|
})
|
||||||
|
public Response createUser(
|
||||||
|
ScimUser user, @Context UriInfo uriInfo, @Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.CREATE_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.createUser(user, uriInfo, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/Users/{id}")
|
||||||
|
@Operation(
|
||||||
|
operationId = "updateScimUser",
|
||||||
|
summary = "Update SCIM user",
|
||||||
|
description = "Updates a SCIM user identified by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "User updated"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "User not found")
|
||||||
|
})
|
||||||
|
public Response updateUser(
|
||||||
|
@Parameter(description = "SCIM User ID") @PathParam("id") String id,
|
||||||
|
ScimUser user,
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.EDIT_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.updateUser(id, user, uriInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/Users/{id}")
|
||||||
|
@Operation(
|
||||||
|
operationId = "deleteScimUser",
|
||||||
|
summary = "Delete SCIM user",
|
||||||
|
description = "Deletes a SCIM user identified by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "User deleted"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "User not found")
|
||||||
|
})
|
||||||
|
public Response deleteUser(
|
||||||
|
@Parameter(description = "SCIM User ID") @PathParam("id") String id,
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.DELETE_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.deleteUser(id, uriInfo, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PATCH
|
||||||
|
@Path("/Users/{id}")
|
||||||
|
@Operation(
|
||||||
|
operationId = "patchScimUser",
|
||||||
|
summary = "Patch SCIM user",
|
||||||
|
description = "Patch updates to a SCIM user identified by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "User patched"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "User not found")
|
||||||
|
})
|
||||||
|
public Response patchUser(
|
||||||
|
@Parameter(description = "SCIM User ID") @PathParam("id") String id,
|
||||||
|
ScimPatchOp request,
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.EDIT_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.patchUser(id, request, uriInfo, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/Users/{id}")
|
||||||
|
@Operation(
|
||||||
|
operationId = "getScimUser",
|
||||||
|
summary = "Get SCIM user by ID",
|
||||||
|
description = "Retrieves a SCIM user identified by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "User found"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "User not found")
|
||||||
|
})
|
||||||
|
public Response getUser(
|
||||||
|
@Parameter(description = "SCIM User ID") @PathParam("id") String id,
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.VIEW_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.getUser(id, uriInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/Groups")
|
||||||
|
@Operation(
|
||||||
|
operationId = "listScimGroups",
|
||||||
|
summary = "List SCIM groups",
|
||||||
|
description = "Lists SCIM groups based on optional filters.",
|
||||||
|
responses = @ApiResponse(responseCode = "200", description = "List of SCIM Groups"))
|
||||||
|
public Response listGroups(@Context UriInfo uriInfo, @Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.VIEW_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.listGroups(uriInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/Groups")
|
||||||
|
@Operation(
|
||||||
|
operationId = "createScimGroup",
|
||||||
|
summary = "Create SCIM group",
|
||||||
|
description = "Creates a new SCIM group.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "Group created"),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Invalid group input")
|
||||||
|
})
|
||||||
|
public Response createGroup(
|
||||||
|
ScimGroup group, @Context UriInfo uriInfo, @Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.CREATE_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.createGroup(group, uriInfo, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/Groups/{id}")
|
||||||
|
@Operation(
|
||||||
|
operationId = "updateScimGroup",
|
||||||
|
summary = "Update SCIM group",
|
||||||
|
description = "Updates a SCIM group identified by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Group updated"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Group not found")
|
||||||
|
})
|
||||||
|
public Response updateGroup(
|
||||||
|
@Parameter(description = "SCIM Group ID") @PathParam("id") String id,
|
||||||
|
ScimGroup group,
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.EDIT_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.updateGroup(id, group, uriInfo, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/Groups/{id}")
|
||||||
|
@Operation(
|
||||||
|
operationId = "getScimGroup",
|
||||||
|
summary = "Get SCIM group by ID",
|
||||||
|
description = "Retrieves a SCIM group identified by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Group found"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Group not found")
|
||||||
|
})
|
||||||
|
public Response getGroup(
|
||||||
|
@Parameter(description = "SCIM Group ID") @PathParam("id") String id,
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.VIEW_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.getGroup(id, uriInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PATCH
|
||||||
|
@Path("/Groups/{id}")
|
||||||
|
@Operation(
|
||||||
|
operationId = "patchScimGroup",
|
||||||
|
summary = "Patch SCIM group",
|
||||||
|
description = "Patch updates to a SCIM group identified by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Group patched"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Group not found")
|
||||||
|
})
|
||||||
|
public Response patchGroup(
|
||||||
|
@Parameter(description = "SCIM Group ID") @PathParam("id") String id,
|
||||||
|
ScimPatchOp request,
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.EDIT_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.patchGroup(id, request, uriInfo, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/Groups/{id}")
|
||||||
|
@Operation(
|
||||||
|
operationId = "deleteScimGroup",
|
||||||
|
summary = "Delete SCIM group",
|
||||||
|
description = "Deletes a SCIM group identified by ID.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Group deleted"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Group not found")
|
||||||
|
})
|
||||||
|
public Response deleteGroup(
|
||||||
|
@Parameter(description = "SCIM Group ID") @PathParam("id") String id,
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.DELETE_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.deleteGroup(id, uriInfo, securityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/Schemas")
|
||||||
|
@Operation(
|
||||||
|
operationId = "getScimSchemas",
|
||||||
|
summary = "Get SCIM schemas",
|
||||||
|
description = "Returns supported SCIM schemas.",
|
||||||
|
responses = @ApiResponse(responseCode = "200", description = "SCIM schemas"))
|
||||||
|
public Response getSchemas(@Context SecurityContext securityContext) {
|
||||||
|
authorizer.authorize(
|
||||||
|
securityContext,
|
||||||
|
new OperationContext(SCIM_RESOURCE_NAME, MetadataOperation.VIEW_SCIM),
|
||||||
|
new ScimResourceContext());
|
||||||
|
return provisioningService.getSchemas();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ScimResourceContext implements ResourceContextInterface {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getResource() {
|
||||||
|
return SCIM_RESOURCE_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EntityReference> getOwners() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TagLabel> getTags() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityInterface getEntity() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityReference getDomain() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package org.openmetadata.service.scim;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import jakarta.ws.rs.core.SecurityContext;
|
||||||
|
import jakarta.ws.rs.core.UriInfo;
|
||||||
|
import org.openmetadata.schema.api.scim.ScimGroup;
|
||||||
|
import org.openmetadata.schema.api.scim.ScimPatchOp;
|
||||||
|
import org.openmetadata.schema.api.scim.ScimUser;
|
||||||
|
|
||||||
|
public interface ScimProvisioningService {
|
||||||
|
|
||||||
|
Response listUsers(UriInfo uriInfo);
|
||||||
|
|
||||||
|
Response createUser(ScimUser user, UriInfo uriInfo, SecurityContext securityContext);
|
||||||
|
|
||||||
|
Response getUser(String id, UriInfo uriInfo);
|
||||||
|
|
||||||
|
Response patchUser(
|
||||||
|
String id, ScimPatchOp request, UriInfo uriInfo, SecurityContext securityContext);
|
||||||
|
|
||||||
|
Response updateUser(String id, ScimUser user, UriInfo uriInfo);
|
||||||
|
|
||||||
|
Response deleteUser(String id, UriInfo uriInfo, SecurityContext securityContext);
|
||||||
|
|
||||||
|
Response listGroups(UriInfo uriInfo);
|
||||||
|
|
||||||
|
Response createGroup(ScimGroup group, UriInfo uriInfo, SecurityContext securityContext);
|
||||||
|
|
||||||
|
Response updateGroup(
|
||||||
|
String id, ScimGroup group, UriInfo uriInfo, SecurityContext securityContext);
|
||||||
|
|
||||||
|
Response deleteGroup(String id, UriInfo uriInfo, SecurityContext securityContext);
|
||||||
|
|
||||||
|
Response getGroup(String id, UriInfo uriInfo);
|
||||||
|
|
||||||
|
Response patchGroup(
|
||||||
|
String id, ScimPatchOp request, UriInfo uriInfo, SecurityContext securityContext);
|
||||||
|
|
||||||
|
Response getSchemas();
|
||||||
|
|
||||||
|
Response getServiceProviderConfig();
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package org.openmetadata.service.scim.impl;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import jakarta.ws.rs.core.SecurityContext;
|
||||||
|
import jakarta.ws.rs.core.UriInfo;
|
||||||
|
import org.openmetadata.schema.api.scim.ScimGroup;
|
||||||
|
import org.openmetadata.schema.api.scim.ScimPatchOp;
|
||||||
|
import org.openmetadata.schema.api.scim.ScimUser;
|
||||||
|
import org.openmetadata.service.scim.ScimProvisioningService;
|
||||||
|
|
||||||
|
public class DefaultScimProvisioningService implements ScimProvisioningService {
|
||||||
|
|
||||||
|
private static final String MSG = "SCIM is not implemented in OpenMetadata.";
|
||||||
|
|
||||||
|
private Response notImplemented() {
|
||||||
|
return Response.status(Response.Status.NOT_IMPLEMENTED).entity(MSG).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response listUsers(UriInfo uriInfo) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response createUser(ScimUser user, UriInfo uriInfo, SecurityContext securityContext) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response getUser(String id, UriInfo uriInfo) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response patchUser(
|
||||||
|
String id, ScimPatchOp request, UriInfo uriInfo, SecurityContext securityContext) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response updateUser(String id, ScimUser user, UriInfo uriInfo) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response deleteUser(String id, UriInfo uriInfo, SecurityContext securityContext) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response listGroups(UriInfo uriInfo) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response createGroup(ScimGroup group, UriInfo uriInfo, SecurityContext securityContext) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response updateGroup(
|
||||||
|
String id, ScimGroup group, UriInfo uriInfo, SecurityContext securityContext) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response deleteGroup(String id, UriInfo uriInfo, SecurityContext securityContext) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response getGroup(String id, UriInfo uriInfo) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response patchGroup(
|
||||||
|
String id, ScimPatchOp request, UriInfo uriInfo, SecurityContext securityContext) {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response getSchemas() {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response getServiceProviderConfig() {
|
||||||
|
return notImplemented();
|
||||||
|
}
|
||||||
|
}
|
@ -100,7 +100,8 @@ public final class SecurityUtil {
|
|||||||
List<String> jwtPrincipalClaimsOrder,
|
List<String> jwtPrincipalClaimsOrder,
|
||||||
Map<String, ?> claims) {
|
Map<String, ?> claims) {
|
||||||
String userName;
|
String userName;
|
||||||
if (!nullOrEmpty(jwtPrincipalClaimsMapping)) {
|
|
||||||
|
if (!nullOrEmpty(jwtPrincipalClaimsMapping) && !isBotW(claims)) {
|
||||||
// We have a mapping available so we will use that
|
// We have a mapping available so we will use that
|
||||||
String usernameClaim = jwtPrincipalClaimsMapping.get(USERNAME_CLAIM_KEY);
|
String usernameClaim = jwtPrincipalClaimsMapping.get(USERNAME_CLAIM_KEY);
|
||||||
String userNameClaimValue = getClaimOrObject(claims.get(usernameClaim));
|
String userNameClaimValue = getClaimOrObject(claims.get(usernameClaim));
|
||||||
@ -122,7 +123,8 @@ public final class SecurityUtil {
|
|||||||
Map<String, ?> claims,
|
Map<String, ?> claims,
|
||||||
String defaulPrincipalClaim) {
|
String defaulPrincipalClaim) {
|
||||||
String email;
|
String email;
|
||||||
if (!nullOrEmpty(jwtPrincipalClaimsMapping)) {
|
|
||||||
|
if (!nullOrEmpty(jwtPrincipalClaimsMapping) && !isBotW(claims)) {
|
||||||
// We have a mapping available so we will use that
|
// We have a mapping available so we will use that
|
||||||
String emailClaim = jwtPrincipalClaimsMapping.get(EMAIL_CLAIM_KEY);
|
String emailClaim = jwtPrincipalClaimsMapping.get(EMAIL_CLAIM_KEY);
|
||||||
String emailClaimValue = getClaimOrObject(claims.get(emailClaim));
|
String emailClaimValue = getClaimOrObject(claims.get(emailClaim));
|
||||||
@ -192,7 +194,8 @@ public final class SecurityUtil {
|
|||||||
Set<String> allowedDomains,
|
Set<String> allowedDomains,
|
||||||
boolean enforcePrincipalDomain) {
|
boolean enforcePrincipalDomain) {
|
||||||
String domain = StringUtils.EMPTY;
|
String domain = StringUtils.EMPTY;
|
||||||
if (!nullOrEmpty(jwtPrincipalClaimsMapping)) {
|
|
||||||
|
if (!nullOrEmpty(jwtPrincipalClaimsMapping) && !isBotW(claims)) {
|
||||||
// We have a mapping available so we will use that
|
// We have a mapping available so we will use that
|
||||||
String emailClaim = jwtPrincipalClaimsMapping.get(EMAIL_CLAIM_KEY);
|
String emailClaim = jwtPrincipalClaimsMapping.get(EMAIL_CLAIM_KEY);
|
||||||
String emailClaimValue = getClaimOrObject(claims.get(emailClaim));
|
String emailClaimValue = getClaimOrObject(claims.get(emailClaim));
|
||||||
@ -241,4 +244,9 @@ public final class SecurityUtil {
|
|||||||
public static boolean isBot(Map<String, Claim> claims) {
|
public static boolean isBot(Map<String, Claim> claims) {
|
||||||
return claims.containsKey(BOT_CLAIM) && Boolean.TRUE.equals(claims.get(BOT_CLAIM).asBoolean());
|
return claims.containsKey(BOT_CLAIM) && Boolean.TRUE.equals(claims.get(BOT_CLAIM).asBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isBotW(Map<String, ?> claims) {
|
||||||
|
Claim isBotClaim = (Claim) claims.get("isBot");
|
||||||
|
return isBotClaim != null && Boolean.TRUE.equals(isBotClaim.asBoolean());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,6 +355,8 @@ public final class UserUtil {
|
|||||||
.withUpdatedAt(System.currentTimeMillis())
|
.withUpdatedAt(System.currentTimeMillis())
|
||||||
.withTeams(EntityUtil.toEntityReferences(create.getTeams(), Entity.TEAM))
|
.withTeams(EntityUtil.toEntityReferences(create.getTeams(), Entity.TEAM))
|
||||||
.withRoles(EntityUtil.toEntityReferences(create.getRoles(), Entity.ROLE))
|
.withRoles(EntityUtil.toEntityReferences(create.getRoles(), Entity.ROLE))
|
||||||
.withDomains(EntityUtil.getEntityReferences(Entity.DOMAIN, create.getDomains()));
|
.withDomains(EntityUtil.getEntityReferences(Entity.DOMAIN, create.getDomains()))
|
||||||
|
.withExternalId(create.getExternalId())
|
||||||
|
.withScimUserName(create.getScimUserName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "scim-bot",
|
||||||
|
"displayName": "SCIM Bot",
|
||||||
|
"description": "Bot with SCIM-only access",
|
||||||
|
"fullyQualifiedName": "scim-bot",
|
||||||
|
"botUser": {
|
||||||
|
"name" : "scim-bot",
|
||||||
|
"type" : "user"
|
||||||
|
},
|
||||||
|
"provider": "system"
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "scim-bot",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"name": "ScimBotRole",
|
||||||
|
"type": "role"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "ScimBotPolicy",
|
||||||
|
"displayName": "SCIM Bot Policy",
|
||||||
|
"fullyQualifiedName": "ScimBotPolicy",
|
||||||
|
"description": "Policy to allow SCIM bot access only to SCIM APIs and block all others.",
|
||||||
|
"enabled": true,
|
||||||
|
"allowDelete": false,
|
||||||
|
"provider": "system",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"name": "Allow-Scim-Endpoints",
|
||||||
|
"description": "Allow access to SCIM endpoints",
|
||||||
|
"resources": ["scim"],
|
||||||
|
"operations": ["CreateScim", "EditScim", "ViewScim", "DeleteScim"],
|
||||||
|
"effect": "allow"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "ScimBotRole",
|
||||||
|
"displayName": "SCIM bot role",
|
||||||
|
"description": "Role corresponding to the SCIM bot, with SCIM-only access.",
|
||||||
|
"allowDelete": false,
|
||||||
|
"provider": "system",
|
||||||
|
"policies": [
|
||||||
|
{
|
||||||
|
"type": "policy",
|
||||||
|
"name": "ScimBotPolicy"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"$id": "https://open-metadata.org/schema/api/scimGroup.json",
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"title": "ScimGroup",
|
||||||
|
"description": "SCIM-compliant Group object",
|
||||||
|
"type": "object",
|
||||||
|
"javaType": "org.openmetadata.schema.api.scim.ScimGroup",
|
||||||
|
"properties": {
|
||||||
|
"schemas": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "SCIM schemas used for this resource",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"default": ["urn:ietf:params:scim:schemas:core:2.0:Group"]
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Unique identifier for the group"
|
||||||
|
},
|
||||||
|
"displayName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Human-readable name of the group"
|
||||||
|
},
|
||||||
|
"externalId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "External system identifier"
|
||||||
|
},
|
||||||
|
"active": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the group is active"
|
||||||
|
},
|
||||||
|
"members": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Members of the group",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"value": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "ID of the member (user)"
|
||||||
|
},
|
||||||
|
"display": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Display name of the member"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Type of member - typically 'User'"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["value"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Metadata about the group",
|
||||||
|
"properties": {
|
||||||
|
"resourceType": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"created": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"lastModified": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["schemas", "displayName"],
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"$id": "https://open-metadata.org/schema/api/scimPatchOp.json",
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"title": "ScimPatchOp",
|
||||||
|
"description": "SCIM PatchOp request as per RFC 7644",
|
||||||
|
"type": "object",
|
||||||
|
"javaType": "org.openmetadata.schema.api.scim.ScimPatchOp",
|
||||||
|
"properties": {
|
||||||
|
"schemas": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"default": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]
|
||||||
|
},
|
||||||
|
"Operations": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"op": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["add", "replace", "remove"],
|
||||||
|
"javaType": "java.lang.String"
|
||||||
|
},
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": ["object", "array", "string", "boolean", "number"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["op"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["schemas", "Operations"],
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"$id": "https://open-metadata.org/schema/api/scimUser.json",
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"title": "ScimUser",
|
||||||
|
"description": "SCIM-compliant User object",
|
||||||
|
"type": "object",
|
||||||
|
"javaType": "org.openmetadata.schema.api.scim.ScimUser",
|
||||||
|
"properties": {
|
||||||
|
"schemas": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": { "type": "string" },
|
||||||
|
"externalId": { "type": "string" },
|
||||||
|
"userName": { "type": "string" },
|
||||||
|
"displayName": { "type": "string" },
|
||||||
|
"active": { "type": "boolean", "default": true },
|
||||||
|
"title": { "type": "string" },
|
||||||
|
"preferredLanguage": { "type": "string" },
|
||||||
|
"emails": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"value": { "type": "string", "format": "email" },
|
||||||
|
"type": { "type": "string" },
|
||||||
|
"primary": { "type": "boolean" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"phoneNumbers": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"value": { "type": "string" },
|
||||||
|
"type": { "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"addresses": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"type": { "type": "string" },
|
||||||
|
"formatted": { "type": "string" },
|
||||||
|
"streetAddress": { "type": "string" },
|
||||||
|
"locality": { "type": "string" },
|
||||||
|
"region": { "type": "string" },
|
||||||
|
"postalCode": { "type": "string" },
|
||||||
|
"country": { "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"givenName": { "type": "string" },
|
||||||
|
"familyName": { "type": "string" },
|
||||||
|
"formatted": { "type": "string" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"resourceType": { "type": "string" },
|
||||||
|
"created": { "type": "string", "format": "date-time" },
|
||||||
|
"lastModified": { "type": "string", "format": "date-time" },
|
||||||
|
"location": { "type": "string" }
|
||||||
|
},
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
|
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"employeeId": { "type": "string" },
|
||||||
|
"department": { "type": "string" },
|
||||||
|
"manager": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"value": { "type": "string" },
|
||||||
|
"displayName": { "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
@ -23,6 +23,10 @@
|
|||||||
"description": "Optional name used for display purposes. Example 'Marketing Team'.",
|
"description": "Optional name used for display purposes. Example 'Marketing Team'.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"externalId": {
|
||||||
|
"description": "External identifier for the team from an external identity provider (e.g., Azure AD group ID).",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Optional description of the team.",
|
"description": "Optional description of the team.",
|
||||||
"$ref": "../../type/basic.json#/definitions/markdown"
|
"$ref": "../../type/basic.json#/definitions/markdown"
|
||||||
|
@ -18,6 +18,14 @@
|
|||||||
"description": "Name used for display purposes. Example 'FirstName LastName'",
|
"description": "Name used for display purposes. Example 'FirstName LastName'",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"externalId": {
|
||||||
|
"description": "External identifier from identity provider (used for SCIM).",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"scimUserName": {
|
||||||
|
"description": "Raw user name from SCIM.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"email": {
|
"email": {
|
||||||
"$ref": "../../type/basic.json#/definitions/email"
|
"$ref": "../../type/basic.json#/definitions/email"
|
||||||
},
|
},
|
||||||
|
@ -53,7 +53,11 @@
|
|||||||
"Deploy",
|
"Deploy",
|
||||||
"Trigger",
|
"Trigger",
|
||||||
"Kill",
|
"Kill",
|
||||||
"GenerateToken"
|
"GenerateToken",
|
||||||
|
"EditScim",
|
||||||
|
"CreateScim",
|
||||||
|
"DeleteScim",
|
||||||
|
"ViewScim"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -44,6 +44,10 @@
|
|||||||
"description": "Name used for display purposes. Example 'Data Science team'.",
|
"description": "Name used for display purposes. Example 'Data Science team'.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"externalId": {
|
||||||
|
"description": "External identifier for the team from an external identity provider (e.g., Azure AD group ID).",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"description": "Description of the team.",
|
"description": "Description of the team.",
|
||||||
"$ref": "../../type/basic.json#/definitions/markdown"
|
"$ref": "../../type/basic.json#/definitions/markdown"
|
||||||
|
@ -49,6 +49,14 @@
|
|||||||
"description": "Used for user biography.",
|
"description": "Used for user biography.",
|
||||||
"$ref": "../../type/basic.json#/definitions/markdown"
|
"$ref": "../../type/basic.json#/definitions/markdown"
|
||||||
},
|
},
|
||||||
|
"externalId": {
|
||||||
|
"description": "External identifier from identity provider (used for SCIM).",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"scimUserName": {
|
||||||
|
"description": "Raw user name from SCIM.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"displayName": {
|
"displayName": {
|
||||||
"description": "Name used for display purposes. Example 'FirstName LastName'.",
|
"description": "Name used for display purposes. Example 'FirstName LastName'.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"$id": "https://open-metadata.org/schema/security/scim/scimConfiguration.json",
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"title": "SCIM Configuration",
|
||||||
|
"description": "SCIM configuration for automatic provisioning through identity providers like Azure AD or Okta.",
|
||||||
|
"type": "object",
|
||||||
|
"javaType": "org.openmetadata.schema.security.scim.ScimConfiguration",
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"title": "Enabled",
|
||||||
|
"description": "Whether SCIM provisioning is enabled.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"identityProvider": {
|
||||||
|
"title": "Identity Provider",
|
||||||
|
"description": "The name of the identity provider for SCIM (e.g., azure, okta).",
|
||||||
|
"type": "string",
|
||||||
|
"default": "azure"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
@ -34,7 +34,8 @@
|
|||||||
"searchSettings",
|
"searchSettings",
|
||||||
"assetCertificationSettings",
|
"assetCertificationSettings",
|
||||||
"lineageSettings",
|
"lineageSettings",
|
||||||
"workflowSettings"
|
"workflowSettings",
|
||||||
|
"scimConfiguration"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 Collate.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* SCIM-compliant Group object
|
||||||
|
*/
|
||||||
|
export interface ScimGroup {
|
||||||
|
/**
|
||||||
|
* Whether the group is active
|
||||||
|
*/
|
||||||
|
active?: boolean;
|
||||||
|
/**
|
||||||
|
* Human-readable name of the group
|
||||||
|
*/
|
||||||
|
displayName: string;
|
||||||
|
/**
|
||||||
|
* External system identifier
|
||||||
|
*/
|
||||||
|
externalId?: string;
|
||||||
|
/**
|
||||||
|
* Unique identifier for the group
|
||||||
|
*/
|
||||||
|
id?: string;
|
||||||
|
/**
|
||||||
|
* Members of the group
|
||||||
|
*/
|
||||||
|
members?: Member[];
|
||||||
|
/**
|
||||||
|
* Metadata about the group
|
||||||
|
*/
|
||||||
|
meta?: Meta;
|
||||||
|
/**
|
||||||
|
* SCIM schemas used for this resource
|
||||||
|
*/
|
||||||
|
schemas: string[];
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Member {
|
||||||
|
/**
|
||||||
|
* Display name of the member
|
||||||
|
*/
|
||||||
|
display?: string;
|
||||||
|
/**
|
||||||
|
* Type of member - typically 'User'
|
||||||
|
*/
|
||||||
|
type?: string;
|
||||||
|
/**
|
||||||
|
* ID of the member (user)
|
||||||
|
*/
|
||||||
|
value: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata about the group
|
||||||
|
*/
|
||||||
|
export interface Meta {
|
||||||
|
created?: Date;
|
||||||
|
lastModified?: Date;
|
||||||
|
location?: string;
|
||||||
|
resourceType?: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 Collate.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* SCIM PatchOp request as per RFC 7644
|
||||||
|
*/
|
||||||
|
export interface ScimPatchOp {
|
||||||
|
Operations: Operation[];
|
||||||
|
schemas: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Operation {
|
||||||
|
op: Op;
|
||||||
|
path?: string;
|
||||||
|
value?: any[] | boolean | number | { [key: string]: any } | string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Op {
|
||||||
|
Add = "add",
|
||||||
|
Remove = "remove",
|
||||||
|
Replace = "replace",
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 Collate.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* SCIM-compliant User object
|
||||||
|
*/
|
||||||
|
export interface ScimUser {
|
||||||
|
active?: boolean;
|
||||||
|
addresses?: Address[];
|
||||||
|
displayName?: string;
|
||||||
|
emails?: Email[];
|
||||||
|
externalId?: string;
|
||||||
|
id?: string;
|
||||||
|
meta?: Meta;
|
||||||
|
name?: Name;
|
||||||
|
phoneNumbers?: PhoneNumber[];
|
||||||
|
preferredLanguage?: string;
|
||||||
|
schemas?: string[];
|
||||||
|
title?: string;
|
||||||
|
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"?: UrnIETFParamsScimSchemasExtensionEnterprise20User;
|
||||||
|
userName?: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Address {
|
||||||
|
country?: string;
|
||||||
|
formatted?: string;
|
||||||
|
locality?: string;
|
||||||
|
postalCode?: string;
|
||||||
|
region?: string;
|
||||||
|
streetAddress?: string;
|
||||||
|
type?: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Email {
|
||||||
|
primary?: boolean;
|
||||||
|
type?: string;
|
||||||
|
value?: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Meta {
|
||||||
|
created?: Date;
|
||||||
|
lastModified?: Date;
|
||||||
|
location?: string;
|
||||||
|
resourceType?: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Name {
|
||||||
|
familyName?: string;
|
||||||
|
formatted?: string;
|
||||||
|
givenName?: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PhoneNumber {
|
||||||
|
type?: string;
|
||||||
|
value?: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UrnIETFParamsScimSchemasExtensionEnterprise20User {
|
||||||
|
department?: string;
|
||||||
|
employeeId?: string;
|
||||||
|
manager?: Manager;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Manager {
|
||||||
|
displayName?: string;
|
||||||
|
value?: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
@ -41,6 +41,11 @@ export interface CreateTeam {
|
|||||||
* Email address of the team.
|
* Email address of the team.
|
||||||
*/
|
*/
|
||||||
email?: string;
|
email?: string;
|
||||||
|
/**
|
||||||
|
* External identifier for the team from an external identity provider (e.g., Azure AD group
|
||||||
|
* ID).
|
||||||
|
*/
|
||||||
|
externalId?: string;
|
||||||
/**
|
/**
|
||||||
* Can any user join this team during sign up? Value of true indicates yes, and false no.
|
* Can any user join this team during sign up? Value of true indicates yes, and false no.
|
||||||
*/
|
*/
|
||||||
|
@ -47,6 +47,10 @@ export interface CreateUser {
|
|||||||
*/
|
*/
|
||||||
domains?: string[];
|
domains?: string[];
|
||||||
email: string;
|
email: string;
|
||||||
|
/**
|
||||||
|
* External identifier from identity provider (used for SCIM).
|
||||||
|
*/
|
||||||
|
externalId?: string;
|
||||||
/**
|
/**
|
||||||
* When true indicates user is an administrator for the system with superuser privileges
|
* When true indicates user is an administrator for the system with superuser privileges
|
||||||
*/
|
*/
|
||||||
@ -72,6 +76,10 @@ export interface CreateUser {
|
|||||||
* Roles that the user has been assigned
|
* Roles that the user has been assigned
|
||||||
*/
|
*/
|
||||||
roles?: string[];
|
roles?: string[];
|
||||||
|
/**
|
||||||
|
* Raw user name from SCIM.
|
||||||
|
*/
|
||||||
|
scimUserName?: string;
|
||||||
/**
|
/**
|
||||||
* Teams that the user belongs to
|
* Teams that the user belongs to
|
||||||
*/
|
*/
|
||||||
|
@ -32,7 +32,9 @@ export enum Operation {
|
|||||||
All = "All",
|
All = "All",
|
||||||
Create = "Create",
|
Create = "Create",
|
||||||
CreateIngestionPipelineAutomator = "CreateIngestionPipelineAutomator",
|
CreateIngestionPipelineAutomator = "CreateIngestionPipelineAutomator",
|
||||||
|
CreateScim = "CreateScim",
|
||||||
Delete = "Delete",
|
Delete = "Delete",
|
||||||
|
DeleteScim = "DeleteScim",
|
||||||
DeleteTestCaseFailedRowsSample = "DeleteTestCaseFailedRowsSample",
|
DeleteTestCaseFailedRowsSample = "DeleteTestCaseFailedRowsSample",
|
||||||
Deploy = "Deploy",
|
Deploy = "Deploy",
|
||||||
EditAll = "EditAll",
|
EditAll = "EditAll",
|
||||||
@ -53,6 +55,7 @@ export enum Operation {
|
|||||||
EditReviewers = "EditReviewers",
|
EditReviewers = "EditReviewers",
|
||||||
EditRole = "EditRole",
|
EditRole = "EditRole",
|
||||||
EditSampleData = "EditSampleData",
|
EditSampleData = "EditSampleData",
|
||||||
|
EditScim = "EditScim",
|
||||||
EditStatus = "EditStatus",
|
EditStatus = "EditStatus",
|
||||||
EditTags = "EditTags",
|
EditTags = "EditTags",
|
||||||
EditTeams = "EditTeams",
|
EditTeams = "EditTeams",
|
||||||
@ -69,6 +72,7 @@ export enum Operation {
|
|||||||
ViewProfilerGlobalConfiguration = "ViewProfilerGlobalConfiguration",
|
ViewProfilerGlobalConfiguration = "ViewProfilerGlobalConfiguration",
|
||||||
ViewQueries = "ViewQueries",
|
ViewQueries = "ViewQueries",
|
||||||
ViewSampleData = "ViewSampleData",
|
ViewSampleData = "ViewSampleData",
|
||||||
|
ViewScim = "ViewScim",
|
||||||
ViewTestCaseFailedRowsSample = "ViewTestCaseFailedRowsSample",
|
ViewTestCaseFailedRowsSample = "ViewTestCaseFailedRowsSample",
|
||||||
ViewTests = "ViewTests",
|
ViewTests = "ViewTests",
|
||||||
ViewUsage = "ViewUsage",
|
ViewUsage = "ViewUsage",
|
||||||
|
@ -56,6 +56,11 @@ export interface Team {
|
|||||||
* Email address of the team.
|
* Email address of the team.
|
||||||
*/
|
*/
|
||||||
email?: string;
|
email?: string;
|
||||||
|
/**
|
||||||
|
* External identifier for the team from an external identity provider (e.g., Azure AD group
|
||||||
|
* ID).
|
||||||
|
*/
|
||||||
|
externalId?: string;
|
||||||
/**
|
/**
|
||||||
* FullyQualifiedName same as `name`.
|
* FullyQualifiedName same as `name`.
|
||||||
*/
|
*/
|
||||||
|
@ -45,6 +45,10 @@ export interface User {
|
|||||||
* Email address of the user.
|
* Email address of the user.
|
||||||
*/
|
*/
|
||||||
email: string;
|
email: string;
|
||||||
|
/**
|
||||||
|
* External identifier from identity provider (used for SCIM).
|
||||||
|
*/
|
||||||
|
externalId?: string;
|
||||||
/**
|
/**
|
||||||
* List of entities followed by the user.
|
* List of entities followed by the user.
|
||||||
*/
|
*/
|
||||||
@ -107,6 +111,10 @@ export interface User {
|
|||||||
* Roles that the user has been assigned.
|
* Roles that the user has been assigned.
|
||||||
*/
|
*/
|
||||||
roles?: EntityReference[];
|
roles?: EntityReference[];
|
||||||
|
/**
|
||||||
|
* Raw user name from SCIM.
|
||||||
|
*/
|
||||||
|
scimUserName?: string;
|
||||||
/**
|
/**
|
||||||
* Teams that the user belongs to.
|
* Teams that the user belongs to.
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 Collate.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* SCIM configuration for automatic provisioning through identity providers like Azure AD or
|
||||||
|
* Okta.
|
||||||
|
*/
|
||||||
|
export interface ScimConfiguration {
|
||||||
|
/**
|
||||||
|
* Whether SCIM provisioning is enabled.
|
||||||
|
*/
|
||||||
|
enabled?: boolean;
|
||||||
|
/**
|
||||||
|
* The name of the identity provider for SCIM (e.g., azure, okta).
|
||||||
|
*/
|
||||||
|
identityProvider?: string;
|
||||||
|
}
|
@ -43,6 +43,7 @@ export enum SettingType {
|
|||||||
OpenMetadataBaseURLConfiguration = "openMetadataBaseUrlConfiguration",
|
OpenMetadataBaseURLConfiguration = "openMetadataBaseUrlConfiguration",
|
||||||
ProfilerConfiguration = "profilerConfiguration",
|
ProfilerConfiguration = "profilerConfiguration",
|
||||||
SandboxModeEnabled = "sandboxModeEnabled",
|
SandboxModeEnabled = "sandboxModeEnabled",
|
||||||
|
ScimConfiguration = "scimConfiguration",
|
||||||
SearchSettings = "searchSettings",
|
SearchSettings = "searchSettings",
|
||||||
SecretsManagerConfiguration = "secretsManagerConfiguration",
|
SecretsManagerConfiguration = "secretsManagerConfiguration",
|
||||||
SlackAppConfiguration = "slackAppConfiguration",
|
SlackAppConfiguration = "slackAppConfiguration",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user