Skip to content

Commit

Permalink
Add selection of Role in the User Group wizard #5285
Browse files Browse the repository at this point in the history
Added ability to create and update groups with memberships.
  • Loading branch information
edloidas committed Jul 29, 2017
1 parent 6fbd90c commit 8233a3b
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 40 deletions.
Expand Up @@ -362,7 +362,15 @@ public GroupJson createGroup( final CreateGroupJson params )
securityService.addRelationship( rel );
}

return new GroupJson( group, members );
for ( final PrincipalKey membershipToAdd : params.toMembershipKeys() )
{
final PrincipalRelationship rel = PrincipalRelationship.from( membershipToAdd ).to( groupKey );
this.securityService.addRelationship( rel );
}

final Principals memberships = this.securityService.getPrincipals( this.securityService.getMemberships( groupKey ) );

return new GroupJson( group, members, memberships );
}

@POST
Expand All @@ -389,16 +397,8 @@ public UserJson updateUser( final UpdateUserJson params )
final User user = securityService.updateUser( params.getUpdateUserParams() );

final PrincipalKey userKey = user.getKey();
for ( PrincipalKey membershipToAdd : params.getAddMemberships() )
{
final PrincipalRelationship rel = PrincipalRelationship.from( membershipToAdd ).to( userKey );
securityService.addRelationship( rel );
}
for ( PrincipalKey membershipToRemove : params.getRemoveMemberships() )
{
final PrincipalRelationship rel = PrincipalRelationship.from( membershipToRemove ).to( userKey );
securityService.removeRelationship( rel );
}

updateMemberships( userKey, params.getAddMemberships(), params.getRemoveMemberships() );

final Principals memberships = securityService.getPrincipals( securityService.getMemberships( userKey ) );
return new UserJson( user, memberships );
Expand Down Expand Up @@ -426,10 +426,14 @@ public GroupJson updateGroup( final UpdateGroupJson params )
final Group group = securityService.updateGroup( params.getUpdateGroupParams() );
final PrincipalKey groupKey = group.getKey();

updateMemberships( groupKey, params.getRemoveMembers(), params.getAddMembers() );
updateMembers( groupKey, params.getAddMembers(), params.getRemoveMembers() );

updateMemberships( groupKey, params.getAddMemberships(), params.getRemoveMemberships() );

final Principals memberships = securityService.getPrincipals( securityService.getMemberships( groupKey ) );

final PrincipalKeys groupMembers = getMembers( groupKey );
return new GroupJson( group, groupMembers );
return new GroupJson( group, groupMembers, memberships );
}

@POST
Expand All @@ -439,7 +443,7 @@ public RoleJson updateRole( final UpdateRoleJson params )
final Role role = securityService.updateRole( params.getUpdateRoleParams() );
final PrincipalKey roleKey = role.getKey();

updateMemberships( roleKey, params.getRemoveMembers(), params.getAddMembers() );
updateMembers( roleKey, params.getAddMembers(), params.getRemoveMembers() );

final PrincipalKeys roleMembers = getMembers( roleKey );
return new RoleJson( role, roleMembers );
Expand All @@ -464,7 +468,7 @@ public DeletePrincipalsResultJson deletePrincipals( final DeletePrincipalJson pr
return resultsJson;
}

private void updateMemberships( final PrincipalKey target, PrincipalKeys membersToRemove, PrincipalKeys membersToAdd )
private void updateMembers( final PrincipalKey target, PrincipalKeys membersToAdd, PrincipalKeys membersToRemove )
{
for ( PrincipalKey memberToAdd : membersToAdd )
{
Expand All @@ -479,6 +483,21 @@ private void updateMemberships( final PrincipalKey target, PrincipalKeys members
}
}

private void updateMemberships( final PrincipalKey source, PrincipalKeys membershipsToAdd, PrincipalKeys membershipsToRemove )
{
for ( PrincipalKey membershipToAdd : membershipsToAdd )
{
final PrincipalRelationship rel = PrincipalRelationship.from( membershipToAdd ).to( source );
securityService.addRelationship( rel );
}

for ( PrincipalKey membershipToRemove : membershipsToRemove )
{
final PrincipalRelationship rel = PrincipalRelationship.from( membershipToRemove ).to( source );
securityService.removeRelationship( rel );
}
}

private PrincipalKeys getMembers( final PrincipalKey principal )
{
final PrincipalRelationships relationships = this.securityService.getRelationships( principal );
Expand Down
@@ -1,7 +1,9 @@
package com.enonic.xp.admin.impl.rest.resource.security.json;

import java.util.Collections;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

import com.enonic.xp.security.CreateGroupParams;
Expand All @@ -21,6 +23,9 @@ public final class CreateGroupJson
@JsonProperty("members")
public List<String> members;

@JsonProperty("memberships")
public List<String> memberships = Collections.emptyList();

@JsonProperty("description")
public String description;

Expand All @@ -34,8 +39,15 @@ public CreateGroupParams toCreateGroupParams()
build();
}

@JsonIgnore
public PrincipalKeys toMemberKeys()
{
return PrincipalKeys.from( this.members.stream().map( PrincipalKey::from ).collect( toList() ) );
}

@JsonIgnore
public PrincipalKeys toMembershipKeys()
{
return PrincipalKeys.from( this.memberships.stream().map( PrincipalKey::from ).collect( toList() ) );
}
}
Expand Up @@ -21,12 +21,18 @@ public final class UpdateGroupJson

private final PrincipalKeys removeMembers;

private final PrincipalKeys addMemberships;

private final PrincipalKeys removeMemberships;

private final String description;

@JsonCreator
public UpdateGroupJson( @JsonProperty("key") final String userKey, @JsonProperty("displayName") final String displayName,
@JsonProperty("addMembers") final List<String> addMembers,
@JsonProperty("removeMembers") final List<String> removeMembers,
@JsonProperty("addMemberships") final List<String> addMemberships,
@JsonProperty("removeMemberships") final List<String> removeMemberships,
@JsonProperty("description") final String description )
{
final PrincipalKey principalKey = PrincipalKey.from( userKey );
Expand All @@ -37,6 +43,8 @@ public UpdateGroupJson( @JsonProperty("key") final String userKey, @JsonProperty
build();
this.addMembers = PrincipalKeys.from( addMembers.stream().map( PrincipalKey::from ).collect( toList() ) );
this.removeMembers = PrincipalKeys.from( removeMembers.stream().map( PrincipalKey::from ).collect( toList() ) );
this.addMemberships = PrincipalKeys.from( addMemberships.stream().map( PrincipalKey::from ).collect( toList() ) );
this.removeMemberships = PrincipalKeys.from( removeMemberships.stream().map( PrincipalKey::from ).collect( toList() ) );
this.description = description;
}

Expand All @@ -57,4 +65,16 @@ public PrincipalKeys getRemoveMembers()
{
return removeMembers;
}

@JsonIgnore
public PrincipalKeys getAddMemberships()
{
return addMemberships;
}

@JsonIgnore
public PrincipalKeys getRemoveMemberships()
{
return removeMemberships;
}
}
Expand Up @@ -533,10 +533,10 @@ public void updateGroup()
build();

Mockito.when( securityService.updateGroup( Mockito.any( UpdateGroupParams.class ) ) ).thenReturn( group );
PrincipalRelationship membership1 = from( group.getKey() ).to( PrincipalKey.from( "user:system:user1" ) );
PrincipalRelationship membership2 = from( group.getKey() ).to( PrincipalKey.from( "user:system:user2" ) );
PrincipalRelationships memberships = PrincipalRelationships.from( membership1, membership2 );
Mockito.when( securityService.getRelationships( group.getKey() ) ).thenReturn( memberships );
PrincipalRelationship members1 = from( group.getKey() ).to( PrincipalKey.from( "user:system:user1" ) );
PrincipalRelationship members2 = from( group.getKey() ).to( PrincipalKey.from( "user:system:user2" ) );
PrincipalRelationships members = PrincipalRelationships.from( members1, members2 );
Mockito.when( securityService.getRelationships( group.getKey() ) ).thenReturn( members );

String jsonString = request().
path( "security/principals/updateGroup" ).
Expand Down
Expand Up @@ -7,5 +7,7 @@
],
"removeMembers": [
"user:system:user3"
]
],
"addMemberships": [],
"removeMemberships": []
}
Expand Up @@ -5,6 +5,7 @@ module api.security {
private key: PrincipalKey;
private displayName: string;
private members: PrincipalKey[] = [];
private memberships: PrincipalKey[] = [];
private description: string;

constructor() {
Expand All @@ -27,6 +28,11 @@ module api.security {
return this;
}

setMemberships(memberships: PrincipalKey[]): CreateGroupRequest {
this.memberships = memberships.slice(0);
return this;
}

setDescription(description: string): CreateGroupRequest {
this.description = description;
return this;
Expand All @@ -36,7 +42,8 @@ module api.security {
return {
key: this.key.toString(),
displayName: this.displayName,
members: this.members.map((memberKey) => memberKey.toString()),
members: this.members.map(key => key.toString()),
memberships: this.memberships.map(key => key.toString()),
description: this.description
};
}
Expand Down
Expand Up @@ -6,6 +6,8 @@ module api.security {
private displayName: string;
private membersToAdd: PrincipalKey[] = [];
private membersToRemove: PrincipalKey[] = [];
private membershipsToAdd: PrincipalKey[] = [];
private membershipsToRemove: PrincipalKey[] = [];
private description: string;

constructor() {
Expand Down Expand Up @@ -33,6 +35,16 @@ module api.security {
return this;
}

addMemberships(memberships: PrincipalKey[]): UpdateGroupRequest {
this.membershipsToAdd = memberships.slice(0);
return this;
}

removeMemberhips(memberships: PrincipalKey[]): UpdateGroupRequest {
this.membershipsToRemove = memberships.slice(0);
return this;
}

setDescription(description: string): UpdateGroupRequest {
this.description = description;
return this;
Expand All @@ -42,8 +54,10 @@ module api.security {
return {
key: this.key.toString(),
displayName: this.displayName,
addMembers: this.membersToAdd.map((memberKey) => memberKey.toString()),
removeMembers: this.membersToRemove.map((memberKey) => memberKey.toString()),
addMembers: this.membersToAdd.map(key => key.toString()),
removeMembers: this.membersToRemove.map(key => key.toString()),
addMemberships: this.membershipsToAdd.map(key => key.toString()),
removeMemberships: this.membershipsToRemove.map(key => key.toString()),
description: this.description
};
}
Expand Down
Expand Up @@ -38,6 +38,8 @@ module api.util {
});
}

// Non-symmetric difference of A and B
// Will return all values from A, that is absent in B
static difference<T>(left: T[], right: T[], equals: (valueLeft: T, valueRight: T) => boolean): T[] {
return left.filter((value) => {
for (let i = 0; i < right.length; i++) {
Expand Down
19 changes: 13 additions & 6 deletions modules/app/app-users/src/main/js/app/wizard/GroupWizardPanel.ts
Expand Up @@ -14,6 +14,7 @@ import PrincipalLoader = api.security.PrincipalLoader;
import WizardStep = api.app.wizard.WizardStep;

import i18n = api.util.i18n;
import ArrayHelper = api.util.ArrayHelper;

export class GroupWizardPanel extends GroupRoleWizardPanel {

Expand Down Expand Up @@ -74,8 +75,8 @@ export class GroupWizardPanel extends GroupRoleWizardPanel {
.setKey(key)
.setDisplayName(name)
.setMembers(members)
.setDescription(description);
// .setMemberships(memberships);
.setDescription(description)
.setMemberships(memberships);
}

updatePersistedItem(): wemQ.Promise<Principal> {
Expand All @@ -91,18 +92,24 @@ export class GroupWizardPanel extends GroupRoleWizardPanel {
const key = group.getKey();
const displayName = group.getDisplayName();
const description = group.getDescription();

const oldMembers = this.getPersistedItem().asGroup().getMembers();
const oldMembersIds = oldMembers.map(el => el.getId());
const newMembers = group.getMembers();
const newMembersIds = newMembers.map(el => el.getId());
const addMembers = newMembers.filter(el => oldMembersIds.indexOf(el.getId()) < 0);
const removeMembers = oldMembers.filter(el => newMembersIds.indexOf(el.getId()) < 0);
const addMembers = ArrayHelper.difference(newMembers, oldMembers, (a, b) => (a.getId() === b.getId()));
const removeMembers = ArrayHelper.difference(oldMembers, newMembers, (a, b) => (a.getId() === b.getId()));

const oldMemberships = this.getPersistedItem().asGroup().getMemberships().map(value => value.getKey());
const newMemberships = group.getMemberships().map(value => value.getKey());
const addMemberships = ArrayHelper.difference(newMemberships, oldMemberships, (a, b) => (a.getId() === b.getId()));
const removeMemberships = ArrayHelper.difference(oldMemberships, newMemberships, (a, b) => (a.getId() === b.getId()));

return new UpdateGroupRequest()
.setKey(key)
.setDisplayName(displayName)
.addMembers(addMembers)
.removeMembers(removeMembers)
.addMemberships(addMemberships)
.removeMemberhips(removeMemberships)
.setDescription(description);
}

Expand Down
22 changes: 11 additions & 11 deletions modules/app/app-users/src/main/js/app/wizard/UserWizardPanel.ts
Expand Up @@ -15,6 +15,7 @@ import UserStoreKey = api.security.UserStoreKey;
import ConfirmationDialog = api.ui.dialog.ConfirmationDialog;
import WizardStep = api.app.wizard.WizardStep;
import i18n = api.util.i18n;
import ArrayHelper = api.util.ArrayHelper;

export class UserWizardPanel extends PrincipalWizardPanel {

Expand Down Expand Up @@ -134,17 +135,16 @@ export class UserWizardPanel extends PrincipalWizardPanel {
}

produceUpdateRequest(viewedPrincipal: Principal): UpdateUserRequest {
let user = viewedPrincipal.asUser();
let key = user.getKey();
let displayName = user.getDisplayName();
let email = user.getEmail();
let login = user.getLogin();
let oldMemberships = this.getPersistedItem().asUser().getMemberships().map(el => el.getKey());
let oldMembershipsIds = oldMemberships.map(el => el.getId());
let newMemberships = user.getMemberships().map(el => el.getKey());
let newMembershipsIds = newMemberships.map(el => el.getId());
let addMemberships = newMemberships.filter(el => oldMembershipsIds.indexOf(el.getId()) < 0);
let removeMemberships = oldMemberships.filter(el => newMembershipsIds.indexOf(el.getId()) < 0);
const user = viewedPrincipal.asUser();
const key = user.getKey();
const displayName = user.getDisplayName();
const email = user.getEmail();
const login = user.getLogin();

const oldMemberships = this.getPersistedItem().asUser().getMemberships().map(value => value.getKey());
const newMemberships = user.getMemberships().map(value => value.getKey());
const addMemberships = ArrayHelper.difference(newMemberships, oldMemberships, (a, b) => (a.getId() === b.getId()));
const removeMemberships = ArrayHelper.difference(oldMemberships, newMemberships, (a, b) => (a.getId() === b.getId()));

return new UpdateUserRequest()
.setKey(key)
Expand Down

0 comments on commit 8233a3b

Please sign in to comment.