Merge pull request #3329 from mposolda/master
KEYCLOAK-3626 - CreatedDate and lastUpdatedDate on user consent
This commit is contained in:
commit
dc13c701f5
16 changed files with 134 additions and 2 deletions
|
@ -35,6 +35,10 @@ public class UserConsentRepresentation {
|
|||
// Key is clientId, Value is list of granted roles of this client
|
||||
protected Map<String, List<String>> grantedClientRoles;
|
||||
|
||||
private Long createdDate;
|
||||
|
||||
private Long lastUpdatedDate;
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
@ -66,4 +70,20 @@ public class UserConsentRepresentation {
|
|||
public void setGrantedClientRoles(Map<String, List<String>> grantedClientRoles) {
|
||||
this.grantedClientRoles = grantedClientRoles;
|
||||
}
|
||||
|
||||
public void setCreatedDate(Long createdDate) {
|
||||
this.createdDate = createdDate;
|
||||
}
|
||||
|
||||
public Long getCreatedDate() {
|
||||
return createdDate;
|
||||
}
|
||||
|
||||
public void setLastUpdatedDate(Long lastUpdatedDate) {
|
||||
this.lastUpdatedDate = lastUpdatedDate;
|
||||
}
|
||||
|
||||
public Long getLastUpdatedDate() {
|
||||
return lastUpdatedDate;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -555,6 +555,8 @@ public class UserCacheSession implements UserCache {
|
|||
}
|
||||
|
||||
UserConsentModel consentModel = new UserConsentModel(client);
|
||||
consentModel.setCreatedDate(cachedConsent.getCreatedDate());
|
||||
consentModel.setLastUpdatedDate(cachedConsent.getLastUpdatedDate());
|
||||
|
||||
for (String roleId : cachedConsent.getRoleIds()) {
|
||||
RoleModel role = session.realms().getRoleById(roleId, realm);
|
||||
|
|
|
@ -32,6 +32,8 @@ public class CachedUserConsent {
|
|||
private final String clientDbId;
|
||||
private final Set<ProtocolMapperModel> protocolMappers = new HashSet<>();
|
||||
private final Set<String> roleIds = new HashSet<>();
|
||||
private final Long createdDate;
|
||||
private final Long lastUpdatedDate;
|
||||
|
||||
public CachedUserConsent(UserConsentModel consentModel) {
|
||||
this.clientDbId = consentModel.getClient().getId();
|
||||
|
@ -39,6 +41,8 @@ public class CachedUserConsent {
|
|||
for (RoleModel role : consentModel.getGrantedRoles()) {
|
||||
this.roleIds.add(role.getId());
|
||||
}
|
||||
this.createdDate = consentModel.getCreatedDate();
|
||||
this.lastUpdatedDate = consentModel.getLastUpdatedDate();
|
||||
}
|
||||
|
||||
public String getClientDbId() {
|
||||
|
@ -52,4 +56,12 @@ public class CachedUserConsent {
|
|||
public Set<String> getRoleIds() {
|
||||
return roleIds;
|
||||
}
|
||||
|
||||
public Long getCreatedDate() {
|
||||
return createdDate;
|
||||
}
|
||||
|
||||
public Long getLastUpdatedDate() {
|
||||
return lastUpdatedDate;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.keycloak.models.jpa;
|
||||
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.credential.UserCredentialStore;
|
||||
|
@ -201,10 +202,14 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
throw new ModelDuplicateException("Consent already exists for client [" + clientId + "] and user [" + user.getId() + "]");
|
||||
}
|
||||
|
||||
long currentTime = Time.currentTimeMillis();
|
||||
|
||||
consentEntity = new UserConsentEntity();
|
||||
consentEntity.setId(KeycloakModelUtils.generateId());
|
||||
consentEntity.setUser(em.getReference(UserEntity.class, user.getId()));
|
||||
consentEntity.setClientId(clientId);
|
||||
consentEntity.setCreatedDate(currentTime);
|
||||
consentEntity.setLastUpdatedDate(currentTime);
|
||||
em.persist(consentEntity);
|
||||
em.flush();
|
||||
|
||||
|
@ -277,6 +282,8 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
throw new ModelException("Client with id " + entity.getClientId() + " is not available");
|
||||
}
|
||||
UserConsentModel model = new UserConsentModel(client);
|
||||
model.setCreatedDate(entity.getCreatedDate());
|
||||
model.setLastUpdatedDate(entity.getLastUpdatedDate());
|
||||
|
||||
Collection<UserConsentRoleEntity> grantedRoleEntities = entity.getGrantedRoles();
|
||||
if (grantedRoleEntities != null) {
|
||||
|
@ -346,6 +353,8 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
em.remove(toRemove);
|
||||
}
|
||||
|
||||
consentEntity.setLastUpdatedDate(Time.currentTimeMillis());
|
||||
|
||||
em.flush();
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,12 @@ public class UserConsentEntity {
|
|||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "userConsent")
|
||||
Collection<UserConsentProtocolMapperEntity> grantedProtocolMappers = new ArrayList<UserConsentProtocolMapperEntity>();
|
||||
|
||||
@Column(name = "CREATED_DATE")
|
||||
private Long createdDate;
|
||||
|
||||
@Column(name = "LAST_UPDATED_DATE")
|
||||
private Long lastUpdatedDate;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -108,6 +114,22 @@ public class UserConsentEntity {
|
|||
this.grantedProtocolMappers = grantedProtocolMappers;
|
||||
}
|
||||
|
||||
public Long getCreatedDate() {
|
||||
return createdDate;
|
||||
}
|
||||
|
||||
public void setCreatedDate(Long createdDate) {
|
||||
this.createdDate = createdDate;
|
||||
}
|
||||
|
||||
public Long getLastUpdatedDate() {
|
||||
return lastUpdatedDate;
|
||||
}
|
||||
|
||||
public void setLastUpdatedDate(Long lastUpdatedDate) {
|
||||
this.lastUpdatedDate = lastUpdatedDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
@ -125,5 +147,4 @@ public class UserConsentEntity {
|
|||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,7 +47,11 @@
|
|||
<dropColumn tableName="REALM" columnName="PUBLIC_KEY" />
|
||||
<dropColumn tableName="REALM" columnName="CERTIFICATE" />
|
||||
|
||||
<addColumn tableName="USER_CONSENT">
|
||||
<column name="CREATED_DATE" type="BIGINT"/>
|
||||
<column name="LAST_UPDATED_DATE" type="BIGINT"/>
|
||||
</addColumn>
|
||||
|
||||
</changeSet>
|
||||
|
||||
|
||||
</databaseChangeLog>
|
|
@ -21,6 +21,7 @@ import com.mongodb.BasicDBObject;
|
|||
import com.mongodb.DBObject;
|
||||
import com.mongodb.QueryBuilder;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.connections.mongo.api.MongoStore;
|
||||
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
||||
|
@ -524,9 +525,13 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
|
|||
throw new ModelDuplicateException("Consent already exists for client [" + clientId + "] and user [" + user.getId() + "]");
|
||||
}
|
||||
|
||||
long currentTime = Time.currentTimeMillis();
|
||||
|
||||
MongoUserConsentEntity consentEntity = new MongoUserConsentEntity();
|
||||
consentEntity.setUserId(user.getId());
|
||||
consentEntity.setClientId(clientId);
|
||||
consentEntity.setCreatedDate(currentTime);
|
||||
consentEntity.setLastUpdatedDate(currentTime);
|
||||
fillEntityFromModel(consent, consentEntity);
|
||||
getMongoStore().insertEntity(consentEntity, invocationContext);
|
||||
}
|
||||
|
@ -568,6 +573,8 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
|
|||
throw new ModelException("Client with id " + entity.getClientId() + " is not available");
|
||||
}
|
||||
UserConsentModel model = new UserConsentModel(client);
|
||||
model.setCreatedDate(entity.getCreatedDate());
|
||||
model.setLastUpdatedDate(entity.getLastUpdatedDate());
|
||||
|
||||
for (String roleId : entity.getGrantedRoles()) {
|
||||
RoleModel roleModel = realm.getRoleById(roleId);
|
||||
|
@ -596,6 +603,7 @@ public class MongoUserProvider implements UserProvider, UserCredentialStore {
|
|||
protMapperIds.add(protMapperModel.getId());
|
||||
}
|
||||
consentEntity.setGrantedProtocolMappers(protMapperIds);
|
||||
consentEntity.setLastUpdatedDate(Time.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,6 +29,8 @@ public class UserConsentEntity extends AbstractIdentifiableEntity {
|
|||
private String clientId;
|
||||
private List<String> grantedRoles = new ArrayList<String>();
|
||||
private List<String> grantedProtocolMappers = new ArrayList<String>();
|
||||
private Long createdDate;
|
||||
private Long lastUpdatedDate;
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
|
@ -61,4 +63,20 @@ public class UserConsentEntity extends AbstractIdentifiableEntity {
|
|||
public void setGrantedProtocolMappers(List<String> grantedProtocolMappers) {
|
||||
this.grantedProtocolMappers = grantedProtocolMappers;
|
||||
}
|
||||
|
||||
public Long getCreatedDate() {
|
||||
return createdDate;
|
||||
}
|
||||
|
||||
public void setCreatedDate(Long createdDate) {
|
||||
this.createdDate = createdDate;
|
||||
}
|
||||
|
||||
public Long getLastUpdatedDate() {
|
||||
return lastUpdatedDate;
|
||||
}
|
||||
|
||||
public void setLastUpdatedDate(Long lastUpdatedDate) {
|
||||
this.lastUpdatedDate = lastUpdatedDate;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ public class UserConsentModel {
|
|||
private final ClientModel client;
|
||||
private Set<ProtocolMapperModel> protocolMappers = new HashSet<ProtocolMapperModel>();
|
||||
private Set<RoleModel> roles = new HashSet<RoleModel>();
|
||||
private Long createdDate;
|
||||
private Long lastUpdatedDate;
|
||||
|
||||
public UserConsentModel(ClientModel client) {
|
||||
this.client = client;
|
||||
|
@ -67,4 +69,19 @@ public class UserConsentModel {
|
|||
return false;
|
||||
}
|
||||
|
||||
public Long getCreatedDate() {
|
||||
return createdDate;
|
||||
}
|
||||
|
||||
public void setCreatedDate(Long createdDate) {
|
||||
this.createdDate = createdDate;
|
||||
}
|
||||
|
||||
public Long getLastUpdatedDate() {
|
||||
return lastUpdatedDate;
|
||||
}
|
||||
|
||||
public void setLastUpdatedDate(Long lastUpdatedDate) {
|
||||
this.lastUpdatedDate = lastUpdatedDate;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -710,6 +710,8 @@ public class ModelToRepresentation {
|
|||
consentRep.setGrantedProtocolMappers(grantedProtocolMappers);
|
||||
consentRep.setGrantedRealmRoles(grantedRealmRoles);
|
||||
consentRep.setGrantedClientRoles(grantedClientRoles);
|
||||
consentRep.setCreatedDate(model.getCreatedDate());
|
||||
consentRep.setLastUpdatedDate(model.getLastUpdatedDate());
|
||||
return consentRep;
|
||||
}
|
||||
|
||||
|
|
|
@ -1571,6 +1571,8 @@ public class RepresentationToModel {
|
|||
}
|
||||
|
||||
UserConsentModel consentModel = new UserConsentModel(client);
|
||||
consentModel.setCreatedDate(consentRep.getCreatedDate());
|
||||
consentModel.setLastUpdatedDate(consentRep.getLastUpdatedDate());
|
||||
|
||||
if (consentRep.getGrantedRealmRoles() != null) {
|
||||
for (String roleName : consentRep.getGrantedRealmRoles()) {
|
||||
|
|
|
@ -538,6 +538,8 @@ public class UsersResource {
|
|||
currentRep.put("grantedProtocolMappers", (rep==null ? Collections.emptyMap() : rep.getGrantedProtocolMappers()));
|
||||
currentRep.put("grantedRealmRoles", (rep==null ? Collections.emptyList() : rep.getGrantedRealmRoles()));
|
||||
currentRep.put("grantedClientRoles", (rep==null ? Collections.emptyMap() : rep.getGrantedClientRoles()));
|
||||
currentRep.put("createdDate", (rep==null ? null : rep.getCreatedDate()));
|
||||
currentRep.put("lastUpdatedDate", (rep==null ? null : rep.getLastUpdatedDate()));
|
||||
|
||||
List<Map<String, String>> additionalGrants = new LinkedList<>();
|
||||
if (hasOfflineToken) {
|
||||
|
|
|
@ -105,12 +105,16 @@ public class UserConsentModelTest extends AbstractModelTest {
|
|||
Assert.assertTrue(isRoleGranted(realm, "realm-role", johnFooConsent));
|
||||
Assert.assertTrue(isRoleGranted(barClient, "bar-client-role", johnFooConsent));
|
||||
Assert.assertTrue(isMapperGranted(fooClient, "foo", johnFooConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel johnBarConsent = realmManager.getSession().users().getConsentByClient(realm, john, barClient.getId());
|
||||
Assert.assertEquals(johnBarConsent.getGrantedRoles().size(), 1);
|
||||
Assert.assertEquals(johnBarConsent.getGrantedProtocolMappers().size(), 1);
|
||||
Assert.assertTrue(isRoleGranted(realm, "realm-role", johnBarConsent));
|
||||
Assert.assertTrue(isMapperGranted(barClient, "bar", johnBarConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel maryConsent = realmManager.getSession().users().getConsentByClient(realm, mary, fooClient.getId());
|
||||
Assert.assertEquals(maryConsent.getGrantedRoles().size(), 1);
|
||||
|
@ -118,6 +122,8 @@ public class UserConsentModelTest extends AbstractModelTest {
|
|||
Assert.assertTrue(isRoleGranted(realm, "realm-role", maryConsent));
|
||||
Assert.assertFalse(isRoleGranted(barClient, "bar-client-role", maryConsent));
|
||||
Assert.assertTrue(isMapperGranted(fooClient, "foo", maryConsent));
|
||||
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
|
||||
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary, barClient.getId()));
|
||||
}
|
||||
|
@ -176,6 +182,7 @@ public class UserConsentModelTest extends AbstractModelTest {
|
|||
Assert.assertFalse(isRoleGranted(realm, "realm-role", johnConsent));
|
||||
Assert.assertTrue(isRoleGranted(realm, "new-realm-role", johnConsent));
|
||||
Assert.assertFalse(isMapperGranted(fooClient, "foo", johnConsent));
|
||||
Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -896,6 +896,8 @@ spi=SPI
|
|||
granted-roles=Granted Roles
|
||||
granted-protocol-mappers=Granted Protocol Mappers
|
||||
additional-grants=Additional Grants
|
||||
consent-created-date=Created
|
||||
consent-last-updated-date=Last updated
|
||||
revoke=Revoke
|
||||
new-password=New Password
|
||||
password-confirmation=Password Confirmation
|
||||
|
|
|
@ -863,6 +863,8 @@ spi=SPI
|
|||
granted-roles=Tildelte roller
|
||||
granted-protocol-mappers=Innvilgede protokollmappere
|
||||
additional-grants=Tillegsrettigheter
|
||||
consent-created-date=Opprettet
|
||||
consent-last-updated-date=Sist oppdatert
|
||||
revoke=Opphev
|
||||
new-password=Nytt passord
|
||||
password-confirmation=Passord bekreftelse
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
<th>{{:: 'granted-roles' | translate}}</th>
|
||||
<th>{{:: 'granted-protocol-mappers' | translate}}</th>
|
||||
<th>{{:: 'additional-grants' | translate}}</th>
|
||||
<th>{{:: 'consent-created-date' | translate}}</th>
|
||||
<th>{{:: 'consent-last-updated-date' | translate}}</th>
|
||||
<th>{{:: 'action' | translate}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -41,6 +43,8 @@
|
|||
<span ng-if="!$first">, </span><a href="#/realms/{{realm.realm}}/users/{{user.id}}/offline-sessions/{{additionalGrant.client}}">{{additionalGrant.key}}</a>
|
||||
</span>
|
||||
</td>
|
||||
<td>{{consent.createdDate | date :'short'}}</td>
|
||||
<td>{{consent.lastUpdatedDate | date :'short'}}</td>
|
||||
<td class="kc-action-cell" ng-click="revokeConsent(consent.clientId)">{{:: 'revoke' | translate}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
Loading…
Reference in a new issue