Skip to content

Commit

Permalink
Pull request #392: Role pages
Browse files Browse the repository at this point in the history
Merge in WALTZ/waltz from WALTZ/waltz-dw:CTCTOWALTZ-3275-roles-7118 to db-feature/waltz-7118-roles

* commit 'd5f0b8effaf7f2202363ed08e6755d2e2a27012d':
  Role pages
  • Loading branch information
db-waltz committed Jul 24, 2024
2 parents 0294d39 + d5f0b8e commit c0f9263
Show file tree
Hide file tree
Showing 30 changed files with 700 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.finos.waltz.schema.tables.Person;
import org.finos.waltz.schema.tables.PhysicalFlow;
import org.finos.waltz.schema.tables.PhysicalSpecification;
import org.finos.waltz.schema.tables.Role;
import org.finos.waltz.schema.tables.ServerInformation;
import org.finos.waltz.schema.tables.SoftwarePackage;
import org.finos.waltz.schema.tables.SurveyQuestion;
Expand Down Expand Up @@ -395,6 +396,18 @@ public static CommonTableFields<?> determineCommonTableFields(EntityKind kind, S
.externalIdField(ps.EXTERNAL_ID)
.lifecycleField(DSL.when(ps.IS_REMOVED.isTrue(), EntityLifecycleStatus.REMOVED.name()).otherwise(EntityLifecycleStatus.ACTIVE.name()))
.build();
case ROLE:
Role role = alias == null ? Tables.ROLE : Tables.ROLE.as(alias);
return ImmutableCommonTableFields
.builder()
.entityKind(EntityKind.ROLE)
.table(role)
.idField(role.ID)
.parentIdField(null)
.nameField(role.NAME)
.descriptionField(role.DESCRIPTION)
.externalIdField(role.KEY)
.build();
case SERVER:
ServerInformation srv = alias == null ? Tables.SERVER_INFORMATION : Tables.SERVER_INFORMATION.as(alias);
return ImmutableCommonTableFields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class InlineSelectFieldFactory {
EntityKind.PERSON,
EntityKind.PHYSICAL_FLOW,
EntityKind.PHYSICAL_SPECIFICATION,
EntityKind.ROLE,
EntityKind.SERVER,
EntityKind.SOFTWARE);

Expand Down Expand Up @@ -95,6 +96,7 @@ public class InlineSelectFieldFactory {
EntityKind.PERSON,
EntityKind.PHYSICAL_FLOW,
EntityKind.PHYSICAL_SPECIFICATION,
EntityKind.ROLE,
EntityKind.SERVER,
EntityKind.SOFTWARE);

Expand Down Expand Up @@ -123,6 +125,7 @@ public class InlineSelectFieldFactory {
EntityKind.PERSON,
EntityKind.PHYSICAL_FLOW,
EntityKind.PHYSICAL_SPECIFICATION,
EntityKind.ROLE,
EntityKind.SERVER,
EntityKind.SOFTWARE);

Expand Down
22 changes: 18 additions & 4 deletions waltz-data/src/main/java/org/finos/waltz/data/role/RoleDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ public RoleDao(DSLContext dsl) {
this.dsl = dsl;
}

public boolean create(RoleRecord role) {
int execute = dsl.insertInto(ROLE)
.set(role).execute();
return execute > 0;
public Long create(RoleRecord role) {
return dsl
.insertInto(ROLE)
.set(role)
.returning(ROLE.ID)
.fetchOne()
.getId();
}

public Set<Role> findAllRoles() {
Expand All @@ -58,10 +61,21 @@ public Set<Role> findAllRoles() {
.fetchSet(TO_ROLE_RECORD);
}


public Role getRoleById(Long id) {
return dsl
.select(ROLE.fields())
.from(ROLE)
.where(ROLE.ID.eq(id))
.fetchOne(TO_ROLE_RECORD);
}


private final static RecordMapper<Record, Role> TO_ROLE_RECORD = r -> {
RoleRecord record = r.into(ROLE);
return ImmutableRole.builder()
.key(record.getKey())
.id(record.getId())
.name(record.getName())
.description(record.getDescription())
.isCustom(record.getIsCustom())
Expand Down
74 changes: 44 additions & 30 deletions waltz-data/src/main/java/org/finos/waltz/data/user/UserRoleDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,30 @@
import org.finos.waltz.model.DiffResult;
import org.finos.waltz.model.user.ImmutableUser;
import org.finos.waltz.model.user.User;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.Record2;
import org.jooq.Result;
import org.jooq.impl.DSL;
import org.jooq.lambda.tuple.Tuple2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.HashSet;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
import static org.finos.waltz.common.Checks.checkNotNull;
import static org.finos.waltz.common.MapUtilities.groupBy;
import static org.finos.waltz.common.SetUtilities.map;
import static org.finos.waltz.data.JooqUtilities.summarizeResults;
import static org.finos.waltz.model.DiffResult.mkDiff;
import static org.finos.waltz.schema.tables.Role.ROLE;
import static org.finos.waltz.schema.tables.User.USER;
import static org.finos.waltz.schema.tables.UserRole.USER_ROLE;
import static org.jooq.lambda.tuple.Tuple.tuple;
Expand All @@ -52,9 +53,6 @@
@Repository
public class UserRoleDao {


private static final Logger LOG = LoggerFactory.getLogger(UserRoleDao.class);

private final DSLContext dsl;

@Autowired
Expand All @@ -66,35 +64,21 @@ public UserRoleDao(DSLContext dsl) {


public Set<String> getUserRoles(String userName) {
List<String> roles = dsl.select(USER_ROLE.ROLE)
return dsl
.select(USER_ROLE.ROLE)
.from(USER_ROLE)
.where(USER_ROLE.USER_NAME.equalIgnoreCase(userName))
.fetch(USER_ROLE.ROLE);

return new HashSet<String>(roles);
.fetchSet(USER_ROLE.ROLE);
}


public List<User> findAllUsers() {
Result<Record2<String, String>> records = dsl.select(USER.USER_NAME, USER_ROLE.ROLE)
.from(USER)
.leftOuterJoin(USER_ROLE)
.on(USER.USER_NAME.eq(USER_ROLE.USER_NAME))
.fetch();
public Set<User> findAllUsers() {
return findUsersByCondition(DSL.trueCondition());
}

Map<String, List<Record2<String, String>>> byUserName = records.stream()
.collect(groupingBy(r -> r.getValue(USER.USER_NAME)));

return byUserName.entrySet().stream()
.map( entry -> ImmutableUser.builder()
.userName(entry.getKey())
.roles(entry.getValue()
.stream()
.map(record -> record.getValue(USER_ROLE.ROLE))
.filter(Objects::nonNull)
.collect(Collectors.toList()))
.build())
.collect(toList());
public Set<User> findUsersForRole(Long roleId) {
return findUsersByCondition(ROLE.ID.eq(roleId));
}


Expand Down Expand Up @@ -171,4 +155,34 @@ private int removeRoles(DSLContext tx,

return summarizeResults(rc);
}


private Set<User> findUsersByCondition(Condition condition) {
Result<Record2<String, String>> records = dsl
.select(USER.USER_NAME, USER_ROLE.ROLE)
.from(USER)
.innerJoin(USER_ROLE)
.on(USER.USER_NAME.eq(USER_ROLE.USER_NAME))
.innerJoin(ROLE).on(ROLE.KEY.eq(USER_ROLE.ROLE))
.where(condition)
.fetch();

Map<String, Collection<Record2<String, String>>> byUserName = groupBy(
records,
r -> r.getValue(USER.USER_NAME));

return byUserName
.entrySet()
.stream()
.map( entry -> ImmutableUser.builder()
.userName(entry.getKey())
.roles(entry.getValue()
.stream()
.map(record -> record.getValue(USER_ROLE.ROLE))
.filter(Objects::nonNull)
.collect(Collectors.toList()))
.build())
.collect(toSet());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.finos.waltz.service.entity_hierarchy.EntityHierarchyService;
import org.h2.tools.Server;
import org.jooq.DSLContext;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.finos.waltz.integration_test.inmem.service;

import org.finos.waltz.common.SetUtilities;
import org.finos.waltz.integration_test.inmem.BaseInMemoryIntegrationTest;
import org.finos.waltz.model.user.ImmutableUpdateRolesCommand;
import org.finos.waltz.model.user.User;
Expand All @@ -8,11 +9,14 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

import static org.finos.waltz.common.SetUtilities.asSet;
import static org.finos.waltz.test_common.helpers.NameHelper.mkName;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.test.util.AssertionErrors.assertEquals;

public class UserRoleServiceTest extends BaseInMemoryIntegrationTest {

Expand Down Expand Up @@ -94,9 +98,33 @@ public void rolesCanBeAddedAndRemoved() {
svc.updateRoles("admin", userName, addRolesCmd3);
assertTrue(svc.hasRole(userName, asSet(role2Name)));
assertFalse(svc.hasRole(userName, asSet(role1Name)));

}

@Test
public void canFindAllUsersForAGivenRole() {
String user1Name = mkName("canFindAllUsersForAGivenRole_User1");
String user2Name = mkName("canFindAllUsersForAGivenRole_User2");
String roleName = mkName("canFindAllUsersForAGivenRole_Role1");

helper.createUser(user1Name);
helper.createUser(user2Name);
Long roleId = helper.createRole(roleName);

ImmutableUpdateRolesCommand addRolesCmd = ImmutableUpdateRolesCommand
.builder()
.roles(asSet(roleName))
.comment("test comment")
.build();
svc.updateRoles("admin", user1Name, addRolesCmd);
svc.updateRoles("admin", user2Name, addRolesCmd);

Set<User> users = svc.findUsersForRole(roleId);

assertEquals(
"Expect (only) user 1 and 2 to be associated to role ("+roleId+")",
SetUtilities.asSet(user1Name, user2Name),
SetUtilities.map(users, User::userName));

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.finos.waltz.model.IdProvider;
import org.immutables.value.Value;

@Value.Immutable
@JsonSerialize(as = ImmutableRole.class)
@JsonDeserialize(as = ImmutableRole.class)
public abstract class Role {
public abstract class Role implements IdProvider {
public abstract String key();
public abstract String name();
public abstract String description();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.finos.waltz.model.role.RoleView;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.finos.waltz.model.role.Role;
import org.immutables.value.Value;

import java.util.Set;

@Value.Immutable
@JsonSerialize(as = ImmutableRoleView.class)
public abstract class RoleView {

public abstract Role role();
public abstract Set<String> users();

}
11 changes: 11 additions & 0 deletions waltz-ng/client/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ export function randomPick(xs) {
}


export function simpleTermSearch(data = [], qry) {
if (_.isEmpty(qry)) return data;
if (_.isEmpty(data)) return [];
const terms = _.map(_.split(qry, " "), t => t.toLowerCase());

return _.filter(
data,
d => !_.isNil(d) && _.every(terms, t => d.toLowerCase().indexOf(t) > -1));
}


/**
*
* @param items - items to be searched
Expand Down
3 changes: 2 additions & 1 deletion waltz-ng/client/common/link-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ const stateKindTuples = [
{kind: "SOFTWARE", state: "main.software-package.view"},
{kind: "SOFTWARE_VERSION", state: "main.software-version.view"}, //todo: no separate view for this (for now), just a workaround for the entity-link tooltip
{kind: "SURVEY_INSTANCE", state: "main.survey.instance.view"},
{kind: "TAG", state: "main.tag.id.view"}
{kind: "TAG", state: "main.tag.id.view"},
{kind: "ROLE", state: "main.role.view"}
];


Expand Down
8 changes: 8 additions & 0 deletions waltz-ng/client/common/svelte/ViewLink.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@
"main.survey.template.list": {
path: () => `survey/template/list`,
title: "Survey Templates"
},
"main.role.list": {
path: () => `role/list`,
title: "Role List"
},
"main.role.view": {
path: (ctx) => `role/view/${ctx.id}`,
title: "Role View"
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,14 @@ const endUserApplicationSections = [
changeLogSection
];

const roleSections = [
assessmentRatingSection,
bookmarksSection,
entityNamedNotesSection,
involvedPeopleSection,
changeLogSection
]


export const dynamicSectionsByKind = {
"main.actor.view": actorSections,
Expand Down Expand Up @@ -946,6 +954,7 @@ export const dynamicSectionsByKind = {
"main.physical-flow.view": physicalFlowSections,
"main.physical-specification.view": physicalSpecificationSections,
"main.process-diagram.view": processDiagramSections,
"main.role.view": roleSections,
"main.scenario.view": scenarioSections,
"main.software-package.view": softwarePackageSections
};
Loading

0 comments on commit c0f9263

Please sign in to comment.