cascade delete scim resource

This commit is contained in:
Hugo Renard 2022-02-16 17:07:19 +01:00
parent 5d1b780413
commit 95c6c5588f
Signed by: hougo
GPG key ID: 3A285FD470209C59
4 changed files with 54 additions and 50 deletions

View file

@ -23,6 +23,9 @@ import org.keycloak.component.ComponentModel;
import org.keycloak.connections.jpa.JpaConnectionProvider; import org.keycloak.connections.jpa.JpaConnectionProvider;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.jpa.entities.ComponentEntity;
import org.keycloak.models.jpa.entities.RealmEntity;
import sh.libre.scim.jpa.ScimResource; import sh.libre.scim.jpa.ScimResource;
public class ScimClient { public class ScimClient {
@ -31,22 +34,18 @@ public class ScimClient {
final private Client client = ResteasyClientBuilder.newClient(); final private Client client = ResteasyClientBuilder.newClient();
final private ScimService scimService; final private ScimService scimService;
final private RetryRegistry registry; final private RetryRegistry registry;
final private String name;
final private KeycloakSession session; final private KeycloakSession session;
final private String contentType; final private String contentType;
final private String authMode; final private ComponentModel model;
final private String bearerToken;
public ScimClient(ComponentModel model, KeycloakSession session) { public ScimClient(ComponentModel model, KeycloakSession session) {
this.name = model.getName(); this.model = model;
this.contentType = model.get("content-type"); this.contentType = model.get("content-type");
this.authMode = model.get("auth-mode");
this.bearerToken = model.get("auth-bearer-token");
this.session = session; this.session = session;
var target = client.target(model.get("endpoint")); var target = client.target(model.get("endpoint"));
if (this.authMode.equals("BEARER")) { if (model.get("auth-mode").equals("BEARER")) {
target = target.register(new BearerAuthentication(this.bearerToken)); target = target.register(new BearerAuthentication(model.get("auth-bearer-token")));
} }
scimService = new ScimService(target); scimService = new ScimService(target);
@ -66,6 +65,14 @@ public class ScimClient {
return session.getContext().getRealm().getId(); return session.getContext().getRealm().getId();
} }
private RealmEntity getRealmEntity() {
return getEM().getReference(RealmEntity.class, getRealmId());
}
private ComponentEntity getSPEntity() {
return getEM().getReference(ComponentEntity.class, this.model.getId());
}
public void createUser(UserModel kcUser) { public void createUser(UserModel kcUser) {
LOGGER.info("Create User"); LOGGER.info("Create User");
var user = toUser(kcUser); var user = toUser(kcUser);
@ -129,9 +136,9 @@ public class ScimClient {
private TypedQuery<ScimResource> queryUser(String query) { private TypedQuery<ScimResource> queryUser(String query) {
return getEM() return getEM()
.createNamedQuery(query, ScimResource.class) .createNamedQuery(query, ScimResource.class)
.setParameter("realmId", getRealmId()) .setParameter("realm", getRealmEntity())
.setParameter("type", "Users") .setParameter("type", "Users")
.setParameter("serviceProvider", name); .setParameter("serviceProvider", getSPEntity());
} }
private ScimResource querUserById(String id) { private ScimResource querUserById(String id) {
@ -141,8 +148,8 @@ public class ScimClient {
private ScimResource scimUser() { private ScimResource scimUser() {
var resource = new ScimResource(); var resource = new ScimResource();
resource.setType("Users"); resource.setType("Users");
resource.setRealmId(getRealmId()); resource.setRealm(getRealmEntity());
resource.setServiceProvider(name); resource.setServiceProvider(getSPEntity());
return resource; return resource;
} }

View file

@ -4,61 +4,56 @@ import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.IdClass; import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery; import javax.persistence.NamedQuery;
import javax.persistence.NamedQueries; import javax.persistence.NamedQueries;
import javax.persistence.Table; import javax.persistence.Table;
import org.keycloak.models.jpa.entities.ComponentEntity;
import org.keycloak.models.jpa.entities.RealmEntity;
@Entity @Entity
@IdClass(ScimResourceId.class) @IdClass(ScimResourceId.class)
@Table(name = "SCIM_RESOURCE") @Table(name = "SCIM_RESOURCE")
@NamedQueries({ @NamedQueries({
@NamedQuery(name = "findByLocalId", query = "from ScimResource where realmId = :realmId and type = :type and serviceProvider = :serviceProvider and localId = :id"), @NamedQuery(name = "findByLocalId", query = "from ScimResource where realm = :realm and type = :type and serviceProvider = :serviceProvider and localId = :id"),
@NamedQuery(name = "findByRemoteId", query = "from ScimResource where realmId = :realmId and type = :type and serviceProvider = :serviceProvider and remoteId = :id") }) @NamedQuery(name = "findByRemoteId", query = "from ScimResource where realm = :realm and type = :type and serviceProvider = :serviceProvider and remoteId = :id") })
public class ScimResource { public class ScimResource {
@Id
@ManyToOne
@JoinColumn(name = "REALM_ID", referencedColumnName = "ID")
private RealmEntity realm;
@Id @Id
@Column(name = "REALM_ID", nullable = false) @ManyToOne
private String realmId; @JoinColumn(name = "SERVICE_PROVIDER", referencedColumnName = "ID")
private ComponentEntity serviceProvider;
@Id
@Column(name = "SERVICE_PROVIDER", nullable = false)
private String serviceProvider;
@Id @Id
@Column(name = "TYPE", nullable = false) @Column(name = "TYPE", nullable = false)
private String type; private String type;
@Id @Id
@Column(name = "REMOTE_ID", nullable = false)
private String remoteId;
@Column(name = "LOCAL_ID", nullable = false) @Column(name = "LOCAL_ID", nullable = false)
private String localId; private String localId;
// public ScimResource() { @Column(name = "REMOTE_ID", nullable = false)
// } private String remoteId;
// public ScimResource(String realmId, String serviceProvider, String type, String remoteId, String localId) { public RealmEntity getRealm() {
// this.realmId = realmId; return realm;
// this.serviceProvider = serviceProvider;
// this.type = type;
// this.remoteId = remoteId;
// this.localId = localId;
// }
public String getRealmId() {
return realmId;
} }
public void setRealmId(String realmId) { public void setRealm(RealmEntity realm) {
this.realmId = realmId; this.realm = realm;
} }
public String getServiceProvider() { public ComponentEntity getServiceProvider() {
return serviceProvider; return serviceProvider;
} }
public void setServiceProvider(String serviceProvider) { public void setServiceProvider(ComponentEntity serviceProvider) {
this.serviceProvider = serviceProvider; this.serviceProvider = serviceProvider;
} }

View file

@ -4,7 +4,7 @@ import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
public class ScimResourceId implements Serializable { public class ScimResourceId implements Serializable {
private String realmId; private String realm;
private String serviceProvider; private String serviceProvider;
private String type; private String type;
private String remoteId; private String remoteId;
@ -12,19 +12,19 @@ public class ScimResourceId implements Serializable {
public ScimResourceId() { public ScimResourceId() {
} }
public ScimResourceId(String realmId, String serviceProvider, String type, String remoteId) { public ScimResourceId(String realm, String serviceProvider, String type, String remoteId) {
this.realmId = realmId; this.realm = realm;
this.serviceProvider = serviceProvider; this.serviceProvider = serviceProvider;
this.type = type; this.type = type;
this.remoteId = remoteId; this.remoteId = remoteId;
} }
public String getRealmId() { public String getRealm() {
return realmId; return realm;
} }
public void setRealmId(String realmId) { public void setRealm(String realm) {
this.realmId = realmId; this.realm = realm;
} }
public String getServiceProvider() { public String getServiceProvider() {
@ -44,7 +44,7 @@ public class ScimResourceId implements Serializable {
} }
public String getRemoteId() { public String getRemoteId() {
return realmId; return remoteId;
} }
public void setRemoteId(String remoteId) { public void setRemoteId(String remoteId) {
@ -58,7 +58,7 @@ public class ScimResourceId implements Serializable {
if (!(other instanceof ScimResourceId)) if (!(other instanceof ScimResourceId))
return false; return false;
var o = (ScimResourceId) other; var o = (ScimResourceId) other;
return (o.realmId == realmId && return (o.realm == realm &&
o.serviceProvider == serviceProvider && o.serviceProvider == serviceProvider &&
o.type == type && o.type == type &&
o.remoteId == remoteId); o.remoteId == remoteId);
@ -66,6 +66,6 @@ public class ScimResourceId implements Serializable {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(realmId, serviceProvider, type, remoteId); return Objects.hash(realm, serviceProvider, type, remoteId);
} }
} }

View file

@ -21,6 +21,8 @@
</createTable> </createTable>
<addPrimaryKey constraintName="PK_SCIM_RESOURCE" tableName="SCIM_RESOURCE" columnNames="REALM_ID,SERVICE_PROVIDER,TYPE,REMOTE_ID" /> <addPrimaryKey constraintName="PK_SCIM_RESOURCE" tableName="SCIM_RESOURCE" columnNames="REALM_ID,SERVICE_PROVIDER,TYPE,REMOTE_ID" />
<addForeignKeyConstraint baseTableName="SCIM_RESOURCE" baseColumnNames="REALM_ID" constraintName="FK_SCIM_RESOURCE_REALM" referencedTableName="REALM" referencedColumnNames="ID" onDelete="CASCADE" onUpdate="CASCADE" />
<addForeignKeyConstraint baseTableName="SCIM_RESOURCE" baseColumnNames="SERVICE_PROVIDER" constraintName="FK_SCIM_RESOURCE_COMPONENT" referencedTableName="COMPONENT" referencedColumnNames="ID" onDelete="CASCADE" onUpdate="CASCADE" />
</changeSet> </changeSet>