Skip to content

Commit

Permalink
temp implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
cgeorgilakis committed Sep 7, 2023
1 parent 83493fb commit bcdaebf
Show file tree
Hide file tree
Showing 15 changed files with 259 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package org.keycloak.representations.idm;

import javax.persistence.Column;

import org.hibernate.annotations.Nationalized;

public class FederatedIdentityAttributeRepresentation {

private String id;
private String name;
private String value;

public FederatedIdentityAttributeRepresentation(){

}

public FederatedIdentityAttributeRepresentation(String name, String value){
this.name = name;
this.value = value;
}

public String getId() {
return id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.models.jpa.entities.CredentialEntity;
import org.keycloak.models.jpa.entities.FederatedIdentityAttributeEntity;
import org.keycloak.models.jpa.entities.FederatedIdentityEntity;
import org.keycloak.models.jpa.entities.UserAttributeEntity;
import org.keycloak.models.jpa.entities.UserConsentClientScopeEntity;
import org.keycloak.models.jpa.entities.UserConsentEntity;
import org.keycloak.models.jpa.entities.UserEntity;
import org.keycloak.models.jpa.entities.UserGroupMembershipEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.FederatedIdentityAttributeRepresentation;
import org.keycloak.storage.StorageId;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.client.ClientStorageProvider;
Expand All @@ -69,6 +71,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
Expand Down Expand Up @@ -165,10 +168,19 @@ public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIden
entity.setToken(identity.getToken());
UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
entity.setUser(userEntity);
entity.setAttributes(identity.getAttributes() == null ? null : identity.getAttributes().stream().map(this::convert).collect(Collectors.toList()));
em.persist(entity);
em.flush();
}

private FederatedIdentityAttributeEntity convert(FederatedIdentityAttributeRepresentation rep){
FederatedIdentityAttributeEntity entity = new FederatedIdentityAttributeEntity();
entity.setId(rep.getId() != null ? rep.getId() : KeycloakModelUtils.generateId());
entity.setName(rep.getName());
entity.setValue(rep.getValue());
return entity;
}

@Override
public void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel) {
FederatedIdentityEntity federatedIdentity = findFederatedIdentity(federatedUser, federatedIdentityModel.getIdentityProvider(), LockModeType.PESSIMISTIC_WRITE);
Expand All @@ -179,6 +191,16 @@ public void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, F
em.flush();
}

@Override
public void updateFederatedIdentityAttributes(RealmModel realm, UserModel federatedUser, String identityProvider, Stream<FederatedIdentityAttributeRepresentation> attributesRepStream) {
FederatedIdentityEntity federatedIdentity = findFederatedIdentity(federatedUser, identityProvider, LockModeType.PESSIMISTIC_WRITE);

federatedIdentity.setAttributes(attributesRepStream.map(this::convert).collect(Collectors.toList()));

em.persist(federatedIdentity);
em.flush();
}

@Override
public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String identityProvider) {
FederatedIdentityEntity entity = findFederatedIdentity(user, identityProvider, LockModeType.PESSIMISTIC_WRITE);
Expand Down Expand Up @@ -939,13 +961,21 @@ public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel re
query.setParameter("user", userEntity);

return closing(query.getResultStream().map(entity -> new FederatedIdentityModel(entity.getIdentityProvider(),
entity.getUserId(), entity.getUserName(), entity.getToken())).distinct());
entity.getUserId(), entity.getUserName(), entity.getToken(), entity.getAttributes() == null ? null : entity.getAttributes().stream().map(this::convert).collect(Collectors.toList()))).distinct());
}

@Override
public FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String identityProvider) {
FederatedIdentityEntity entity = findFederatedIdentity(user, identityProvider, LockModeType.NONE);
return (entity != null) ? new FederatedIdentityModel(entity.getIdentityProvider(), entity.getUserId(), entity.getUserName(), entity.getToken()) : null;
return (entity != null) ? new FederatedIdentityModel(entity.getIdentityProvider(), entity.getUserId(), entity.getUserName(), entity.getToken(),entity.getAttributes() == null ? null : entity.getAttributes().stream().map(this::convert).collect(Collectors.toList())) : null;
}

private FederatedIdentityAttributeRepresentation convert(FederatedIdentityAttributeEntity entity){
FederatedIdentityAttributeRepresentation rep = new FederatedIdentityAttributeRepresentation();
rep.setId(entity.getId());
rep.setName(entity.getName());
rep.setValue(entity.getValue());
return rep;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,6 @@ public String getServiceAccountClientLink() {
public void setServiceAccountClientLink(String clientInternalId) {
user.setServiceAccountClientLink(clientInternalId);
}

@Override
public void setFederatedIdentityAttributes(BrokeredIdentityContext brokerContext){}


@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,23 @@ public String getValue() {
public void setValue(String value) {
this.value = value;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
if (!(o instanceof ClientEntity)) return false;

ClientEntity that = (ClientEntity) o;

if (!id.equals(that.getId())) return false;

return true;
}

@Override
public int hashCode() {
return id.hashCode();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ public String getToken() {
return token;
}

public Collection<FederatedIdentityAttributeEntity> getAttributes() {
return attributes;
}

public void setAttributes(Collection<FederatedIdentityAttributeEntity> attributes) {
this.attributes = attributes;
}

public static class Key implements Serializable {

protected UserEntity user;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,14 @@
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.jpa.JpaUserCredentialStore;
import org.keycloak.models.jpa.entities.FederatedIdentityAttributeEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.FederatedIdentityAttributeRepresentation;
import org.keycloak.storage.StorageId;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.client.ClientStorageProvider;
import org.keycloak.storage.federated.UserFederatedStorageProvider;
import org.keycloak.storage.jpa.entity.BrokerLinkAttributeEntity;
import org.keycloak.storage.jpa.entity.BrokerLinkEntity;
import org.keycloak.storage.jpa.entity.FederatedUser;
import org.keycloak.storage.jpa.entity.FederatedUserAttributeEntity;
Expand Down Expand Up @@ -200,10 +203,19 @@ public void addFederatedIdentity(RealmModel realm, String userId, FederatedIdent
entity.setToken(link.getToken());
entity.setBrokerUserName(link.getUserName());
entity.setStorageProviderId(new StorageId(userId).getProviderId());
entity.setAttributes(link.getAttributes().stream().map(this::convert).collect(Collectors.toList()));
em.persist(entity);

}

private BrokerLinkAttributeEntity convert( FederatedIdentityAttributeRepresentation rep){
BrokerLinkAttributeEntity entity = new BrokerLinkAttributeEntity();
entity.setId(rep.getId() != null ? rep.getId() : KeycloakModelUtils.generateId());
entity.setName(rep.getName());
entity.setValue(rep.getValue());
return entity;
}

@Override
public boolean removeFederatedIdentity(RealmModel realm, String userId, String socialProvider) {
BrokerLinkEntity entity = getBrokerLinkEntity(realm, userId, socialProvider);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package org.keycloak.storage.jpa.entity;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Nationalized;

@Table(name="BROKER_LINK_ATTRIBUTE")
@Entity
public class BrokerLinkAttributeEntity {

@Id
@Column(name="ID", length = 36)
@Access(AccessType.PROPERTY) // we do this because relationships often fetch id, but not entity. This avoids an extra SQL
private String id;

@BatchSize(size = 50)
@ManyToOne(fetch= FetchType.LAZY)
@JoinColumn(name="USER_ID", referencedColumnName="USER_ID")
@JoinColumn(name="IDENTITY_PROVIDER", referencedColumnName="IDENTITY_PROVIDER")
private BrokerLinkEntity brokerLink;

@Column(name = "NAME")
private String name;
@Nationalized
@Column(name = "VALUE")
private String value;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public BrokerLinkEntity getBrokerLinkEntity() {
return brokerLink;
}

public void setBrokerLinkEntity(BrokerLinkEntity brokerLink) {
this.brokerLink = brokerLink;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
if (!(o instanceof BrokerLinkAttributeEntity)) return false;

BrokerLinkAttributeEntity that = (BrokerLinkAttributeEntity) o;

if (!id.equals(that.getId())) return false;

return true;
}

@Override
public int hashCode() {
return id.hashCode();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,23 @@

package org.keycloak.storage.jpa.entity;

import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.keycloak.models.jpa.entities.FederatedIdentityAttributeEntity;
import org.keycloak.storage.jpa.KeyUtils;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Collection;

/**
* @author <a href="mailto:[email protected]">Bill Burke</a>
Expand Down Expand Up @@ -69,6 +76,11 @@ public class BrokerLinkEntity {
@Column(name = "TOKEN")
protected String token;

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy="brokerLink")
@Fetch(FetchMode.SELECT)
@BatchSize(size = 20)
protected Collection<BrokerLinkAttributeEntity> attributes;

public String getUserId() {
return userId;
}
Expand Down Expand Up @@ -126,6 +138,14 @@ public String getToken() {
return token;
}

public Collection<BrokerLinkAttributeEntity> getAttributes() {
return attributes;
}

public void setAttributes(Collection<BrokerLinkAttributeEntity> attributes) {
this.attributes = attributes;
}

public static class Key implements Serializable {

protected String userId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,22 @@
</createTable>
<addPrimaryKey columnNames="ID" constraintName="FEDERATED_IDENTITY_ATTRIBUTE_PK" tableName="FEDERATED_IDENTITY_ATTRIBUTE" />
<addForeignKeyConstraint baseColumnNames="USER_ID,IDENTITY_PROVIDER" baseTableName="FEDERATED_IDENTITY_ATTRIBUTE" constraintName="FEDERATED_IDENTITY_ATTRIBUTE_FK" referencedColumnNames="USER_ID,IDENTITY_PROVIDER" referencedTableName="FEDERATED_IDENTITY" />
<createTable tableName="BROKER_LINK_ATTRIBUTE">
<column name="ID" type="VARCHAR(36)">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="USER_ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
<column name="IDENTITY_PROVIDER" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="NAME" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="VALUE" type="longvarchar"/>
</createTable>
<addPrimaryKey columnNames="ID" constraintName="BROKER_LINK_ATTRIBUTE_PK" tableName="BROKER_LINK_ATTRIBUTE" />
<addForeignKeyConstraint baseColumnNames="USER_ID,IDENTITY_PROVIDER" baseTableName="BROKER_LINK_ATTRIBUTE" constraintName="BROKER_LINK_ATTRIBUTE_FK" referencedColumnNames="USER_ID,IDENTITY_PROVIDER" referencedTableName="BROKER_LINK" />
</changeSet>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -1940,7 +1940,7 @@ public static void createGroups(UserRepresentation userRep, RealmModel newRealm,
public static void createFederatedIdentities(UserRepresentation userRep, KeycloakSession session, RealmModel realm, UserModel user) {
if (userRep.getFederatedIdentities() != null) {
for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName(), identity.getAttributes());
session.users().addFederatedIdentity(realm, user, mappingModel);
}
}
Expand Down Expand Up @@ -2925,7 +2925,7 @@ public static void importFederatedUser(KeycloakSession session, RealmModel newRe

if (userRep.getFederatedIdentities() != null) {
for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName(), identity.getAttributes());
federatedStorage.addFederatedIdentity(newRealm, userRep.getId(), mappingModel);
}
}
Expand Down
Loading

0 comments on commit bcdaebf

Please sign in to comment.