Skip to content

Commit

Permalink
check for hasRole before grantRole. also delete the mapping entity wh…
Browse files Browse the repository at this point in the history
…en revoking, which was the cause of #196. (#197)
  • Loading branch information
xgp authored Mar 7, 2024
1 parent 84fb941 commit 4c7099b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ public InvitationModel addInvitation(String email, UserModel inviter) {

@Override
public Stream<OrganizationRoleModel> getRolesStream() {
return org.getRoles().stream().map(r -> new OrganizationRoleAdapter(session, realm, em, r));
return org.getRoles().stream()
.map(r -> new OrganizationRoleAdapter(session, realm, em, this, r));
}

@Override
Expand All @@ -282,7 +283,7 @@ public OrganizationRoleModel addRole(String name) {
r.setOrganization(org);
em.persist(r);
org.getRoles().add(r);
return new OrganizationRoleAdapter(session, realm, em, r);
return new OrganizationRoleAdapter(session, realm, em, this, r);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.phasetwo.service.model.jpa;

import io.phasetwo.service.model.OrganizationModel;
import io.phasetwo.service.model.OrganizationRoleModel;
import io.phasetwo.service.model.jpa.entity.OrganizationRoleEntity;
import io.phasetwo.service.model.jpa.entity.UserOrganizationRoleMappingEntity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import java.util.stream.Stream;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
Expand All @@ -18,13 +20,19 @@ public class OrganizationRoleAdapter
protected final OrganizationRoleEntity role;
protected final EntityManager em;
protected final RealmModel realm;
protected final OrganizationModel org;

public OrganizationRoleAdapter(
KeycloakSession session, RealmModel realm, EntityManager em, OrganizationRoleEntity role) {
KeycloakSession session,
RealmModel realm,
EntityManager em,
OrganizationModel org,
OrganizationRoleEntity role) {
this.session = session;
this.em = em;
this.role = role;
this.realm = realm;
this.org = org;
}

@Override
Expand Down Expand Up @@ -66,8 +74,10 @@ public Stream<UserModel> getUserMappingsStream() {

@Override
public void grantRole(UserModel user) {
// todo must be a member
revokeRole(user);
// user must be a member
if (!org.hasMembership(user)) return;
// skip if they already have the role
if (hasRole(user)) return;
UserOrganizationRoleMappingEntity m = new UserOrganizationRoleMappingEntity();
m.setId(KeycloakModelUtils.generateId());
m.setUserId(user.getId());
Expand All @@ -78,11 +88,28 @@ public void grantRole(UserModel user) {

@Override
public void revokeRole(UserModel user) {
role.getUserMappings().removeIf(m -> m.getUserId().equals(user.getId()));
UserOrganizationRoleMappingEntity e = getByUser(user);
if (e != null) {
role.getUserMappings().remove(e);
em.remove(e);
em.flush();
}
}

@Override
public boolean hasRole(UserModel user) {
return role.getUserMappings().stream().anyMatch(m -> m.getUserId().equals(user.getId()));
return (getByUser(user) != null);
}

UserOrganizationRoleMappingEntity getByUser(UserModel user) {
TypedQuery<UserOrganizationRoleMappingEntity> query =
em.createNamedQuery("getMappingByRoleAndUser", UserOrganizationRoleMappingEntity.class);
query.setParameter("userId", user.getId());
query.setParameter("role", role);
try {
return query.getSingleResult();
} catch (Exception ignore) {
return null;
}
}
}

0 comments on commit 4c7099b

Please sign in to comment.