mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-03 12:53:53 +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.jwt.JWTTokenConfiguration;
|
||||
import org.openmetadata.schema.configuration.LimitsConfiguration;
|
||||
import org.openmetadata.schema.security.scim.ScimConfiguration;
|
||||
import org.openmetadata.schema.security.secrets.SecretsManagerConfiguration;
|
||||
import org.openmetadata.schema.service.configuration.elasticsearch.ElasticSearchConfiguration;
|
||||
import org.openmetadata.service.config.OMWebConfiguration;
|
||||
@ -142,6 +143,9 @@ public class OpenMetadataApplicationConfig extends Configuration {
|
||||
@Valid
|
||||
private ObjectStorageConfiguration objectStorage;
|
||||
|
||||
@JsonProperty("scimConfiguration")
|
||||
private ScimConfiguration scimConfiguration;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
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,
|
||||
Map<String, ?> claims) {
|
||||
String userName;
|
||||
if (!nullOrEmpty(jwtPrincipalClaimsMapping)) {
|
||||
|
||||
if (!nullOrEmpty(jwtPrincipalClaimsMapping) && !isBotW(claims)) {
|
||||
// We have a mapping available so we will use that
|
||||
String usernameClaim = jwtPrincipalClaimsMapping.get(USERNAME_CLAIM_KEY);
|
||||
String userNameClaimValue = getClaimOrObject(claims.get(usernameClaim));
|
||||
@ -122,7 +123,8 @@ public final class SecurityUtil {
|
||||
Map<String, ?> claims,
|
||||
String defaulPrincipalClaim) {
|
||||
String email;
|
||||
if (!nullOrEmpty(jwtPrincipalClaimsMapping)) {
|
||||
|
||||
if (!nullOrEmpty(jwtPrincipalClaimsMapping) && !isBotW(claims)) {
|
||||
// We have a mapping available so we will use that
|
||||
String emailClaim = jwtPrincipalClaimsMapping.get(EMAIL_CLAIM_KEY);
|
||||
String emailClaimValue = getClaimOrObject(claims.get(emailClaim));
|
||||
@ -192,7 +194,8 @@ public final class SecurityUtil {
|
||||
Set<String> allowedDomains,
|
||||
boolean enforcePrincipalDomain) {
|
||||
String domain = StringUtils.EMPTY;
|
||||
if (!nullOrEmpty(jwtPrincipalClaimsMapping)) {
|
||||
|
||||
if (!nullOrEmpty(jwtPrincipalClaimsMapping) && !isBotW(claims)) {
|
||||
// We have a mapping available so we will use that
|
||||
String emailClaim = jwtPrincipalClaimsMapping.get(EMAIL_CLAIM_KEY);
|
||||
String emailClaimValue = getClaimOrObject(claims.get(emailClaim));
|
||||
@ -241,4 +244,9 @@ public final class SecurityUtil {
|
||||
public static boolean isBot(Map<String, Claim> claims) {
|
||||
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())
|
||||
.withTeams(EntityUtil.toEntityReferences(create.getTeams(), Entity.TEAM))
|
||||
.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'.",
|
||||
"type": "string"
|
||||
},
|
||||
"externalId": {
|
||||
"description": "External identifier for the team from an external identity provider (e.g., Azure AD group ID).",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Optional description of the team.",
|
||||
"$ref": "../../type/basic.json#/definitions/markdown"
|
||||
|
@ -18,6 +18,14 @@
|
||||
"description": "Name used for display purposes. Example 'FirstName LastName'",
|
||||
"type": "string"
|
||||
},
|
||||
"externalId": {
|
||||
"description": "External identifier from identity provider (used for SCIM).",
|
||||
"type": "string"
|
||||
},
|
||||
"scimUserName": {
|
||||
"description": "Raw user name from SCIM.",
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"$ref": "../../type/basic.json#/definitions/email"
|
||||
},
|
||||
|
@ -53,7 +53,11 @@
|
||||
"Deploy",
|
||||
"Trigger",
|
||||
"Kill",
|
||||
"GenerateToken"
|
||||
"GenerateToken",
|
||||
"EditScim",
|
||||
"CreateScim",
|
||||
"DeleteScim",
|
||||
"ViewScim"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -44,6 +44,10 @@
|
||||
"description": "Name used for display purposes. Example 'Data Science team'.",
|
||||
"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 of the team.",
|
||||
"$ref": "../../type/basic.json#/definitions/markdown"
|
||||
|
@ -49,6 +49,14 @@
|
||||
"description": "Used for user biography.",
|
||||
"$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": {
|
||||
"description": "Name used for display purposes. Example 'FirstName LastName'.",
|
||||
"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",
|
||||
"assetCertificationSettings",
|
||||
"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?: 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.
|
||||
*/
|
||||
|
@ -47,6 +47,10 @@ export interface CreateUser {
|
||||
*/
|
||||
domains?: 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
|
||||
*/
|
||||
@ -72,6 +76,10 @@ export interface CreateUser {
|
||||
* Roles that the user has been assigned
|
||||
*/
|
||||
roles?: string[];
|
||||
/**
|
||||
* Raw user name from SCIM.
|
||||
*/
|
||||
scimUserName?: string;
|
||||
/**
|
||||
* Teams that the user belongs to
|
||||
*/
|
||||
|
@ -32,7 +32,9 @@ export enum Operation {
|
||||
All = "All",
|
||||
Create = "Create",
|
||||
CreateIngestionPipelineAutomator = "CreateIngestionPipelineAutomator",
|
||||
CreateScim = "CreateScim",
|
||||
Delete = "Delete",
|
||||
DeleteScim = "DeleteScim",
|
||||
DeleteTestCaseFailedRowsSample = "DeleteTestCaseFailedRowsSample",
|
||||
Deploy = "Deploy",
|
||||
EditAll = "EditAll",
|
||||
@ -53,6 +55,7 @@ export enum Operation {
|
||||
EditReviewers = "EditReviewers",
|
||||
EditRole = "EditRole",
|
||||
EditSampleData = "EditSampleData",
|
||||
EditScim = "EditScim",
|
||||
EditStatus = "EditStatus",
|
||||
EditTags = "EditTags",
|
||||
EditTeams = "EditTeams",
|
||||
@ -69,6 +72,7 @@ export enum Operation {
|
||||
ViewProfilerGlobalConfiguration = "ViewProfilerGlobalConfiguration",
|
||||
ViewQueries = "ViewQueries",
|
||||
ViewSampleData = "ViewSampleData",
|
||||
ViewScim = "ViewScim",
|
||||
ViewTestCaseFailedRowsSample = "ViewTestCaseFailedRowsSample",
|
||||
ViewTests = "ViewTests",
|
||||
ViewUsage = "ViewUsage",
|
||||
|
@ -56,6 +56,11 @@ export interface Team {
|
||||
* Email address of the team.
|
||||
*/
|
||||
email?: string;
|
||||
/**
|
||||
* External identifier for the team from an external identity provider (e.g., Azure AD group
|
||||
* ID).
|
||||
*/
|
||||
externalId?: string;
|
||||
/**
|
||||
* FullyQualifiedName same as `name`.
|
||||
*/
|
||||
|
@ -45,6 +45,10 @@ export interface User {
|
||||
* Email address of the user.
|
||||
*/
|
||||
email: string;
|
||||
/**
|
||||
* External identifier from identity provider (used for SCIM).
|
||||
*/
|
||||
externalId?: string;
|
||||
/**
|
||||
* List of entities followed by the user.
|
||||
*/
|
||||
@ -107,6 +111,10 @@ export interface User {
|
||||
* Roles that the user has been assigned.
|
||||
*/
|
||||
roles?: EntityReference[];
|
||||
/**
|
||||
* Raw user name from SCIM.
|
||||
*/
|
||||
scimUserName?: string;
|
||||
/**
|
||||
* 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",
|
||||
ProfilerConfiguration = "profilerConfiguration",
|
||||
SandboxModeEnabled = "sandboxModeEnabled",
|
||||
ScimConfiguration = "scimConfiguration",
|
||||
SearchSettings = "searchSettings",
|
||||
SecretsManagerConfiguration = "secretsManagerConfiguration",
|
||||
SlackAppConfiguration = "slackAppConfiguration",
|
||||
|
Loading…
x
Reference in New Issue
Block a user