Closes #2302 - Adds Permissions to Users
- Extends LDAP client to read permission attributes from users - Extends database schema with PERMISSION_INFO table and sets schema version to 6.4.0 - Exetends User models (Builder, Mapper,..) to have permission attribute - Determination of Domains is now able to be done via permissions defined on users Signed-off-by: Kálmán Képes <2853992+nyuuyn@users.noreply.github.com>
This commit is contained in:
parent
8cff46a969
commit
18c34d1dfd
|
@ -14,5 +14,6 @@ DELETE FROM OBJECT_REFERENCE;
|
|||
DELETE FROM SCHEDULED_JOB;
|
||||
DELETE FROM USER_INFO;
|
||||
DELETE FROM GROUP_INFO;
|
||||
DELETE FROM PERMISSION_INFO;
|
||||
INSERT INTO CONFIGURATION (NAME) VALUES ('MASTER');
|
||||
COMMIT;
|
||||
|
|
|
@ -14,6 +14,7 @@ DROP TABLE OBJECT_REFERENCE;
|
|||
DROP TABLE SCHEDULED_JOB;
|
||||
DROP TABLE USER_INFO;
|
||||
DROP TABLE GROUP_INFO;
|
||||
DROP TABLE PERMISSION_INFO;
|
||||
DROP SEQUENCE SCHEDULED_JOB_SEQ;
|
||||
DROP SEQUENCE TASKANA_SCHEMA_VERSION_ID_SEQ;
|
||||
COMMIT;
|
||||
|
|
|
@ -357,6 +357,13 @@ CREATE TABLE GROUP_INFO
|
|||
PRIMARY KEY (USER_ID, GROUP_ID)
|
||||
);
|
||||
|
||||
CREATE TABLE PERMISSION_INFO
|
||||
(
|
||||
USER_ID VARCHAR(32) NOT NUll,
|
||||
PERMISSION_ID VARCHAR(256) NOT NULL,
|
||||
PRIMARY KEY (USER_ID, PERMISSION_ID)
|
||||
);
|
||||
|
||||
CREATE SEQUENCE SCHEDULED_JOB_SEQ
|
||||
MINVALUE 1
|
||||
START WITH 1
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
-- this script updates the TASKANA database schema from version 6.2.0 to version 6.4.0.
|
||||
SET SCHEMA %schemaName%;
|
||||
|
||||
INSERT INTO TASKANA_SCHEMA_VERSION (ID, VERSION, CREATED)
|
||||
VALUES (nextval('TASKANA_SCHEMA_VERSION_ID_SEQ'), '6.4.0', CURRENT_TIMESTAMP);
|
||||
|
||||
CREATE TABLE PERMISSION_INFO
|
||||
(
|
||||
USER_ID VARCHAR(32) NOT NULL,
|
||||
PERMISSION_ID VARCHAR(256) NOT NULL,
|
||||
PRIMARY KEY (USER_ID, PERMISSION_ID)
|
||||
);
|
|
@ -363,6 +363,13 @@ CREATE TABLE GROUP_INFO
|
|||
PRIMARY KEY (USER_ID, GROUP_ID)
|
||||
);
|
||||
|
||||
CREATE TABLE PERMISSION_INFO
|
||||
(
|
||||
USER_ID VARCHAR(32) NOT NULL,
|
||||
PERMISSION_ID VARCHAR(256) NOT NULL,
|
||||
PRIMARY KEY (USER_ID, PERMISSION_ID)
|
||||
);
|
||||
|
||||
CREATE SEQUENCE SCHEDULED_JOB_SEQ
|
||||
MINVALUE 1
|
||||
START WITH 1
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
-- this script updates the TASKANA database schema from version 6.2.0 to version 6.4.0.
|
||||
|
||||
INSERT INTO TASKANA_SCHEMA_VERSION (ID, VERSION, CREATED)
|
||||
VALUES (nextval('TASKANA_SCHEMA_VERSION_ID_SEQ'), '6.4.0', CURRENT_TIMESTAMP);
|
||||
|
||||
CREATE TABLE PERMISSION_INFO
|
||||
(
|
||||
USER_ID VARCHAR(32) NOT NULL,
|
||||
PERMISSION_ID VARCHAR(256) NOT NULL,
|
||||
PRIMARY KEY (USER_ID, PERMISSION_ID)
|
||||
);
|
|
@ -356,6 +356,13 @@ CREATE TABLE GROUP_INFO
|
|||
CONSTRAINT GROUP_INFO_PKEY PRIMARY KEY (USER_ID, GROUP_ID)
|
||||
);
|
||||
|
||||
CREATE TABLE PERMISSION_INFO
|
||||
(
|
||||
USER_ID VARCHAR2(32) NOT NULL,
|
||||
PERMISSION_ID VARCHAR2(256) NOT NULL,
|
||||
CONSTRAINT PERMISSION_INFO_PKEY PRIMARY KEY (USER_ID, PERMISSION_ID)
|
||||
);
|
||||
|
||||
CREATE SEQUENCE SCHEDULED_JOB_SEQ
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
-- this script updates the TASKANA database schema from version 6.2.0 to version 6.4.0.
|
||||
ALTER SESSION SET CURRENT_SCHEMA = %schemaName%;
|
||||
|
||||
INSERT INTO TASKANA_SCHEMA_VERSION (ID, VERSION, CREATED)
|
||||
VALUES (nextval('TASKANA_SCHEMA_VERSION_ID_SEQ'), '6.4.0', CURRENT_TIMESTAMP);
|
||||
|
||||
CREATE TABLE PERMISSION_INFO
|
||||
(
|
||||
USER_ID VARCHAR2(32) NOT NULL,
|
||||
PERMISSION_ID VARCHAR2(256) NOT NULL,
|
||||
CONSTRAINT PERMISSION_INFO_PKEY PRIMARY KEY (USER_ID, PERMISSION_ID)
|
||||
);
|
|
@ -360,6 +360,13 @@ CREATE TABLE GROUP_INFO
|
|||
PRIMARY KEY (USER_ID, GROUP_ID)
|
||||
);
|
||||
|
||||
CREATE TABLE PERMISSION_INFO
|
||||
(
|
||||
USER_ID VARCHAR(32) NOT NULL,
|
||||
PERMISSION_ID VARCHAR(256) NOT NULL,
|
||||
PRIMARY KEY (USER_ID, PERMISSION_ID)
|
||||
);
|
||||
|
||||
CREATE SEQUENCE SCHEDULED_JOB_SEQ
|
||||
MINVALUE 1
|
||||
START WITH 1
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
-- this script updates the TASKANA database schema from version 6.2.0 to version 6.4.0.
|
||||
|
||||
SET search_path = %schemaName%;
|
||||
|
||||
INSERT INTO TASKANA_SCHEMA_VERSION (ID, VERSION, CREATED)
|
||||
VALUES (nextval('TASKANA_SCHEMA_VERSION_ID_SEQ'), '6.4.0', CURRENT_TIMESTAMP);
|
||||
|
||||
CREATE TABLE PERMISSION_INFO
|
||||
(
|
||||
USER_ID VARCHAR(32) NOT NULL,
|
||||
PERMISSION_ID VARCHAR(256) NOT NULL,
|
||||
PRIMARY KEY (USER_ID, PERMISSION_ID)
|
||||
);
|
|
@ -26,6 +26,7 @@ taskana.ldap.userOrglevel3Attribute=someDepartement
|
|||
taskana.ldap.userOrglevel4Attribute=orgLevel4
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=cn=groups
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -202,6 +202,59 @@ class UserServiceAccTest {
|
|||
domains -> Set.of(workbasketDomainB.getDomain()).equals(domains), "DOMAIN_B"));
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_DetermineDomains_When_WorkbasketPermissionsExistForUsersWithPermissions()
|
||||
throws Exception {
|
||||
Workbasket workbasketDomainA =
|
||||
defaultTestWorkbasket().buildAndStore(workbasketService, "businessadmin");
|
||||
createAccessItem(
|
||||
"permissions-domaina",
|
||||
workbasketDomainA,
|
||||
WorkbasketPermission.READ,
|
||||
WorkbasketPermission.OPEN);
|
||||
Workbasket workbasketDomainB =
|
||||
defaultTestWorkbasket()
|
||||
.domain("DOMAIN_B")
|
||||
.buildAndStore(workbasketService, "businessadmin");
|
||||
createAccessItem(
|
||||
"permissions-domainb",
|
||||
workbasketDomainB,
|
||||
WorkbasketPermission.READ,
|
||||
WorkbasketPermission.OPEN);
|
||||
Set<User> users = new HashSet<>();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
users.add(
|
||||
randomTestUser()
|
||||
.permissions(Set.of("test1", "test2", "permissions-domaina"))
|
||||
.buildAndStore(userService, "businessadmin"));
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
users.add(
|
||||
randomTestUser()
|
||||
.permissions(Set.of("test1", "test2", "permissions-domainb"))
|
||||
.buildAndStore(userService, "businessadmin"));
|
||||
}
|
||||
Set<String> userIds = users.stream().map(User::getId).collect(Collectors.toSet());
|
||||
|
||||
List<User> returnedUsers = userService.getUsers(userIds);
|
||||
|
||||
assertThat(returnedUsers)
|
||||
.extracting(User::getDomains)
|
||||
.areExactly(
|
||||
6,
|
||||
new Condition<>(
|
||||
domains ->
|
||||
Set.of(workbasketDomainA.getDomain())
|
||||
.equals(domains), "DOMAIN_A"))
|
||||
.areExactly(
|
||||
4,
|
||||
new Condition<>(
|
||||
domains ->
|
||||
Set.of(workbasketDomainB.getDomain())
|
||||
.equals(domains), "DOMAIN_B"));
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_ReturnAllUsers_When_TryingToGetUsersWithIdsExistingInCaps() throws Exception {
|
||||
|
@ -312,6 +365,20 @@ class UserServiceAccTest {
|
|||
assertThat(userToCreate).isNotSameAs(userInDatabase).isEqualTo(userInDatabase);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "businessadmin")
|
||||
@Test
|
||||
void should_InsertUserInDatabase_When_CreatingUserWithPermissions() throws Exception {
|
||||
User userToCreate = userService.newUser();
|
||||
userToCreate.setId("anton4");
|
||||
userToCreate.setFirstName("Anton");
|
||||
userToCreate.setLastName("Miller");
|
||||
userToCreate.setPermissions(Set.of("perm1", "perm2"));
|
||||
userService.createUser(userToCreate);
|
||||
|
||||
User userInDatabase = userService.getUser(userToCreate.getId());
|
||||
assertThat(userToCreate).isNotSameAs(userInDatabase).isEqualTo(userInDatabase);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "businessadmin")
|
||||
@TestFactory
|
||||
Stream<DynamicTest>
|
||||
|
@ -483,12 +550,15 @@ class UserServiceAccTest {
|
|||
userToCreate.setFirstName("firstName");
|
||||
userToCreate.setLastName("lastName");
|
||||
userToCreate.setGroups(Set.of("GROUP1-ID-WITH-CAPS", "Group2-Id-With-Caps"));
|
||||
userToCreate.setPermissions(Set.of("PERMISSION1-ID-WITH-CAPS", "Permission2-Id-With-Caps"));
|
||||
|
||||
User userInDatabase = userService.createUser(userToCreate);
|
||||
|
||||
assertThat(userInDatabase.getId()).isEqualTo("user-id-with-caps");
|
||||
assertThat(userInDatabase.getGroups())
|
||||
.containsExactlyInAnyOrder("group1-id-with-caps", "group2-id-with-caps");
|
||||
assertThat(userInDatabase.getPermissions())
|
||||
.containsExactlyInAnyOrder("permission1-id-with-caps", "permission2-id-with-caps");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -549,6 +619,36 @@ class UserServiceAccTest {
|
|||
return DynamicTest.stream(testCases, Triplet::getLeft, test);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "businessadmin")
|
||||
@TestFactory
|
||||
Stream<DynamicTest> should_UpdatePermissions() {
|
||||
Stream<Triplet<String, Set<String>, Set<String>>> testCases =
|
||||
Stream.of(
|
||||
Triplet.of(
|
||||
"User has no permissions before updating", Set.of(), Set.of("perm1", "perm2")),
|
||||
Triplet.of("new permissions differ all", Set.of("perm1"), Set.of("perm2", "perm3")),
|
||||
Triplet.of("some new permissions differ", Set.of("perm1"), Set.of("perm1", "perm2")),
|
||||
Triplet.of("new permissions are all the same", Set.of("perm1"), Set.of("perm1")));
|
||||
|
||||
ThrowingConsumer<Triplet<String, Set<String>, Set<String>>> test =
|
||||
t -> {
|
||||
Set<String> existingPerms = t.getMiddle();
|
||||
Set<String> newPerms = t.getMiddle();
|
||||
User userToUpdate = randomTestUser()
|
||||
.permissions(existingPerms)
|
||||
.buildAndStore(userService);
|
||||
|
||||
userToUpdate.setPermissions(newPerms);
|
||||
userService.updateUser(userToUpdate);
|
||||
|
||||
User userInDatabase = userService.getUser(userToUpdate.getId());
|
||||
assertThat(userInDatabase.getPermissions())
|
||||
.containsExactlyInAnyOrderElementsOf(newPerms);
|
||||
};
|
||||
|
||||
return DynamicTest.stream(testCases, Triplet::getLeft, test);
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_ThrowNotAuthorizedException_When_TryingToUpdateUserWithNoAdminRole()
|
||||
|
@ -722,6 +822,19 @@ class UserServiceAccTest {
|
|||
.containsExactlyInAnyOrder("group1-id-with-caps", "group2-id-with-caps");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "businessadmin")
|
||||
@Test
|
||||
void should_MakePermissionsIdsLowerCase_When_UpdatingUserWithUpperCasePermissions()
|
||||
throws Exception {
|
||||
User userToUpdate = randomTestUser().buildAndStore(userService);
|
||||
userToUpdate.setPermissions(Set.of("PERM1-ID-WITH-CAPS", "Permission2-Id-With-Caps"));
|
||||
|
||||
User updatedUser = userService.updateUser(userToUpdate);
|
||||
|
||||
assertThat(updatedUser.getPermissions())
|
||||
.containsExactlyInAnyOrder("perm1-id-with-caps", "permission2-id-with-caps");
|
||||
}
|
||||
|
||||
@WithAccessId(user = "businessadmin")
|
||||
@Test
|
||||
void should_ThrowInvalidArgumentException_When_TryingToUpdateUserWithFirstNameNull() {
|
||||
|
@ -826,6 +939,22 @@ class UserServiceAccTest {
|
|||
assertThat(userInDatabase.getGroups()).isEmpty();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "businessadmin")
|
||||
@Test
|
||||
void should_DeletePermissionsFromDatabase_When_UserHadPermissions() throws Exception {
|
||||
User userToDelete =
|
||||
randomTestUser()
|
||||
.permissions(Set.of("permission1", "permission2"))
|
||||
.buildAndStore(userService);
|
||||
|
||||
userService.deleteUser(userToDelete.getId());
|
||||
|
||||
// verify that groups are deleted by creating a new user with the same id and check its groups
|
||||
User newUserWithSameId = randomTestUser().id(userToDelete.getId()).buildAndStore(userService);
|
||||
User userInDatabase = userService.getUser(newUserWithSameId.getId());
|
||||
assertThat(userInDatabase.getPermissions()).isEmpty();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "businessadmin")
|
||||
@Test
|
||||
void should_ThrowUserNotFoundException_When_TryingToDeleteUserWithNonExistingId() {
|
||||
|
@ -913,6 +1042,25 @@ class UserServiceAccTest {
|
|||
assertThat(userInDatabase.getDomains()).containsExactly(workbasket.getDomain());
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_ReturnOneDomain_When_PermissionHasSufficientMinimalPermissionsToAssignDomains()
|
||||
throws Exception {
|
||||
String permissionsId = UUID.randomUUID().toString();
|
||||
User user =
|
||||
randomTestUser()
|
||||
.permissions(Set.of(permissionsId))
|
||||
.buildAndStore(userService, "businessadmin");
|
||||
Workbasket workbasket =
|
||||
defaultTestWorkbasket().buildAndStore(workbasketService, "businessadmin");
|
||||
createAccessItem(permissionsId,
|
||||
workbasket, WorkbasketPermission.OPEN, WorkbasketPermission.READ);
|
||||
|
||||
User userInDatabase = userService.getUser(user.getId());
|
||||
|
||||
assertThat(userInDatabase.getDomains()).containsExactly(workbasket.getDomain());
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_ReturnEmptyDomains_When_UserHasSufficientPermissionsWhichThenGetRevoked()
|
||||
|
@ -961,6 +1109,29 @@ class UserServiceAccTest {
|
|||
assertThat(userInDatabase.getDomains()).isEmpty();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "businessadmin")
|
||||
@Test
|
||||
void should_ReturnEmptyDomains_When_GroupHasSufficientPermissionsAndThenPermissionIsUpdated()
|
||||
throws Exception {
|
||||
String groupId = UUID.randomUUID().toString();
|
||||
User user = randomTestUser().permissions(Set.of(groupId)).buildAndStore(userService);
|
||||
Workbasket workbasket = defaultTestWorkbasket().buildAndStore(workbasketService);
|
||||
createAccessItem(groupId, workbasket, WorkbasketPermission.OPEN, WorkbasketPermission.READ);
|
||||
|
||||
User userInDatabase = userService.getUser(user.getId());
|
||||
|
||||
assertThat(userInDatabase.getDomains()).containsExactly(workbasket.getDomain());
|
||||
|
||||
// then user is updated and other group is assigned
|
||||
|
||||
user.setPermissions(Set.of("new group"));
|
||||
userService.updateUser(user);
|
||||
|
||||
userInDatabase = userService.getUser(user.getId());
|
||||
|
||||
assertThat(userInDatabase.getDomains()).isEmpty();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_ReturnMultipleDomains_When_UserHasSufficientMinimalPermissionsForMultipleDomains()
|
||||
|
@ -1007,6 +1178,32 @@ class UserServiceAccTest {
|
|||
.containsExactlyInAnyOrder(workbasket1.getDomain(), workbasket2.getDomain());
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_ReturnMultipleDomains_When_UserAndPermHaveSufficientMinimalPermsForMultipleDomains()
|
||||
throws Exception {
|
||||
String permissionId = UUID.randomUUID().toString();
|
||||
User user =
|
||||
randomTestUser()
|
||||
.permissions(Set.of(permissionId))
|
||||
.buildAndStore(userService, "businessadmin");
|
||||
Workbasket workbasket1 =
|
||||
defaultTestWorkbasket().buildAndStore(workbasketService, "businessadmin");
|
||||
Workbasket workbasket2 =
|
||||
defaultTestWorkbasket()
|
||||
.domain("DOMAIN_B")
|
||||
.buildAndStore(workbasketService, "businessadmin");
|
||||
createAccessItem(
|
||||
user.getId(), workbasket1, WorkbasketPermission.OPEN, WorkbasketPermission.READ);
|
||||
createAccessItem(
|
||||
permissionId, workbasket2, WorkbasketPermission.OPEN, WorkbasketPermission.READ);
|
||||
|
||||
User userInDatabase = userService.getUser(user.getId());
|
||||
|
||||
assertThat(userInDatabase.getDomains())
|
||||
.containsExactlyInAnyOrder(workbasket1.getDomain(), workbasket2.getDomain());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class DifferentMinimalPermissionsToAssignDomains implements TaskanaConfigurationModifier {
|
||||
|
@ -1050,6 +1247,27 @@ class UserServiceAccTest {
|
|||
assertThat(userInDatabase.getDomains()).isEmpty();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_ReturnEmptyDomains_When_PermHasInsufficientMinimalPermissionsToAssignDomains()
|
||||
throws Exception {
|
||||
String permissionId = UUID.randomUUID().toString();
|
||||
User user =
|
||||
randomTestUser()
|
||||
.permissions(Set.of(permissionId))
|
||||
.buildAndStore(userService, "businessadmin");
|
||||
Workbasket workbasket =
|
||||
defaultTestWorkbasket().buildAndStore(workbasketService, "businessadmin");
|
||||
createAccessItem(permissionId,
|
||||
workbasket,
|
||||
WorkbasketPermission.OPEN,
|
||||
WorkbasketPermission.READ);
|
||||
|
||||
User userInDatabase = userService.getUser(user.getId());
|
||||
|
||||
assertThat(userInDatabase.getDomains()).isEmpty();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_ReturnOneDomain_When_UserHasSufficientMinimalPermissionsToAssignDomains()
|
||||
|
@ -1081,6 +1299,7 @@ class UserServiceAccTest {
|
|||
|
||||
assertThat(userInDatabase.getDomains()).containsExactly(workbasket.getDomain());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
@ -1124,6 +1343,27 @@ class UserServiceAccTest {
|
|||
|
||||
assertThat(userInDatabase.getDomains()).isEmpty();
|
||||
}
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_ReturnEmptyDomains_When_PropertyIsNotSetAndPermission()
|
||||
throws Exception {
|
||||
String permissionId = UUID.randomUUID().toString();
|
||||
User user =
|
||||
randomTestUser()
|
||||
.permissions(Set.of(permissionId))
|
||||
.buildAndStore(userService, "businessadmin");
|
||||
Workbasket workbasket =
|
||||
defaultTestWorkbasket().buildAndStore(workbasketService, "businessadmin");
|
||||
createAccessItem(permissionId,
|
||||
workbasket,
|
||||
WorkbasketPermission.OPEN,
|
||||
WorkbasketPermission.READ);
|
||||
|
||||
User userInDatabase = userService.getUser(user.getId());
|
||||
|
||||
assertThat(userInDatabase.getDomains()).isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,20 @@ public interface User {
|
|||
*/
|
||||
void setGroups(Set<String> groups);
|
||||
|
||||
/**
|
||||
* Returns the permissions of the User.
|
||||
*
|
||||
* @return permissions
|
||||
*/
|
||||
Set<String> getPermissions();
|
||||
|
||||
/**
|
||||
* Sets the permissions of the User.
|
||||
*
|
||||
* @param permissions the permissions of the User
|
||||
*/
|
||||
void setPermissions(Set<String> permissions);
|
||||
|
||||
/**
|
||||
* Returns the first name of the User.
|
||||
*
|
||||
|
|
|
@ -16,6 +16,8 @@ public interface UserMapper {
|
|||
@SelectProvider(type = UserMapperSqlProvider.class, method = "findById")
|
||||
@Result(property = "id", column = "USER_ID")
|
||||
@Result(property = "groups", column = "USER_ID", many = @Many(select = "findGroupsById"))
|
||||
@Result(property = "permissions", column = "USER_ID",
|
||||
many = @Many(select = "findPermissionsById"))
|
||||
@Result(property = "firstName", column = "FIRST_NAME")
|
||||
@Result(property = "lastName", column = "LASTNAME")
|
||||
@Result(property = "fullName", column = "FULL_NAME")
|
||||
|
@ -32,6 +34,8 @@ public interface UserMapper {
|
|||
|
||||
@Result(property = "id", column = "USER_ID")
|
||||
@Result(property = "groups", column = "USER_ID", many = @Many(select = "findGroupsById"))
|
||||
@Result(property = "permissions", column = "USER_ID",
|
||||
many = @Many(select = "findPermissionsById"))
|
||||
@Result(property = "firstName", column = "FIRST_NAME")
|
||||
@Result(property = "lastName", column = "LASTNAME")
|
||||
@Result(property = "fullName", column = "FULL_NAME")
|
||||
|
@ -50,6 +54,9 @@ public interface UserMapper {
|
|||
@SelectProvider(type = UserMapperSqlProvider.class, method = "findGroupsById")
|
||||
Set<String> findGroupsById(String id);
|
||||
|
||||
@SelectProvider(type = UserMapperSqlProvider.class, method = "findPermissionsById")
|
||||
Set<String> findPermissionsById(String id);
|
||||
|
||||
@InsertProvider(type = UserMapperSqlProvider.class, method = "insert")
|
||||
void insert(User user);
|
||||
|
||||
|
@ -60,6 +67,13 @@ public interface UserMapper {
|
|||
@InsertProvider(type = UserMapperSqlProvider.class, method = "insertGroups")
|
||||
void insertGroups(User user);
|
||||
|
||||
@InsertProvider(
|
||||
type = UserMapperSqlProvider.class,
|
||||
method = "insertPermissionsOracle",
|
||||
databaseId = "oracle")
|
||||
@InsertProvider(type = UserMapperSqlProvider.class, method = "insertPermissions")
|
||||
void insertPermissions(User user);
|
||||
|
||||
@UpdateProvider(type = UserMapperSqlProvider.class, method = "update")
|
||||
void update(User user);
|
||||
|
||||
|
@ -68,4 +82,7 @@ public interface UserMapper {
|
|||
|
||||
@DeleteProvider(type = UserMapperSqlProvider.class, method = "deleteGroups")
|
||||
void deleteGroups(String id);
|
||||
|
||||
@DeleteProvider(type = UserMapperSqlProvider.class, method = "deletePermissions")
|
||||
void deletePermissions(String id);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,13 @@ public class UserMapperSqlProvider {
|
|||
+ CLOSING_SCRIPT_TAG;
|
||||
}
|
||||
|
||||
public static String findPermissionsById() {
|
||||
return OPENING_SCRIPT_TAG
|
||||
+ "SELECT PERMISSION_ID FROM PERMISSION_INFO WHERE USER_ID = #{id} "
|
||||
+ DB2_WITH_UR
|
||||
+ CLOSING_SCRIPT_TAG;
|
||||
}
|
||||
|
||||
public static String insert() {
|
||||
return "INSERT INTO USER_INFO ( " + USER_INFO_COLUMNS + ") VALUES(" + USER_INFO_VALUES + ")";
|
||||
}
|
||||
|
@ -65,6 +72,26 @@ public class UserMapperSqlProvider {
|
|||
+ CLOSING_SCRIPT_TAG;
|
||||
}
|
||||
|
||||
public static String insertPermissions() {
|
||||
return OPENING_SCRIPT_TAG
|
||||
+ "INSERT INTO PERMISSION_INFO (USER_ID, PERMISSION_ID) VALUES "
|
||||
+ "<foreach item='permission' collection='permissions' "
|
||||
+ "open='(' separator='),(' close=')'>"
|
||||
+ "#{id}, #{permission}"
|
||||
+ "</foreach> "
|
||||
+ CLOSING_SCRIPT_TAG;
|
||||
}
|
||||
|
||||
public static String insertPermissionsOracle() {
|
||||
return OPENING_SCRIPT_TAG
|
||||
+ "INSERT ALL "
|
||||
+ "<foreach item='permission' collection='permissions' separator='\n'>"
|
||||
+ "INTO PERMISSION_INFO (USER_ID, PERMISSION_ID) VALUES ( #{id}, #{permission} )"
|
||||
+ "</foreach> "
|
||||
+ "SELECT 1 FROM DUAL"
|
||||
+ CLOSING_SCRIPT_TAG;
|
||||
}
|
||||
|
||||
public static String update() {
|
||||
return "UPDATE USER_INFO "
|
||||
+ "SET FIRST_NAME = #{firstName}, "
|
||||
|
@ -82,4 +109,8 @@ public class UserMapperSqlProvider {
|
|||
public static String deleteGroups() {
|
||||
return "DELETE FROM GROUP_INFO WHERE USER_ID = #{id} ";
|
||||
}
|
||||
|
||||
public static String deletePermissions() {
|
||||
return "DELETE FROM PERMISSION_INFO WHERE USER_ID = #{id} ";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,11 +122,18 @@ public class UserServiceImpl implements UserService {
|
|||
|
||||
internalTaskanaEngine.executeInDatabaseConnection(() -> userMapper.update(userToUpdate));
|
||||
internalTaskanaEngine.executeInDatabaseConnection(
|
||||
() -> userMapper.deleteGroups(userToUpdate.getId()));
|
||||
() -> {
|
||||
userMapper.deleteGroups(userToUpdate.getId());
|
||||
userMapper.deletePermissions(userToUpdate.getId());
|
||||
});
|
||||
if (userToUpdate.getGroups() != null && !userToUpdate.getGroups().isEmpty()) {
|
||||
internalTaskanaEngine.executeInDatabaseConnection(
|
||||
() -> userMapper.insertGroups(userToUpdate));
|
||||
}
|
||||
if (userToUpdate.getPermissions() != null && !userToUpdate.getPermissions().isEmpty()) {
|
||||
internalTaskanaEngine.executeInDatabaseConnection(
|
||||
() -> userMapper.insertPermissions(userToUpdate));
|
||||
}
|
||||
((UserImpl) userToUpdate).setDomains(determineDomains(userToUpdate));
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
|
@ -150,6 +157,7 @@ public class UserServiceImpl implements UserService {
|
|||
() -> {
|
||||
userMapper.delete(id);
|
||||
userMapper.deleteGroups(id);
|
||||
userMapper.deletePermissions(id);
|
||||
});
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Method deleteUser() deleted User with id '{}'.", id);
|
||||
|
@ -158,6 +166,7 @@ public class UserServiceImpl implements UserService {
|
|||
|
||||
private Set<String> determineDomains(User user) {
|
||||
Set<String> accessIds = new HashSet<>(user.getGroups());
|
||||
accessIds.addAll(user.getPermissions());
|
||||
accessIds.add(user.getId());
|
||||
if (minimalWorkbasketPermissions != null && !minimalWorkbasketPermissions.isEmpty()) {
|
||||
// since WorkbasketService#accessIdsHavePermissions requires some role permissions we have to
|
||||
|
@ -186,6 +195,9 @@ public class UserServiceImpl implements UserService {
|
|||
if (userToCreate.getGroups() != null && !userToCreate.getGroups().isEmpty()) {
|
||||
userMapper.insertGroups(userToCreate);
|
||||
}
|
||||
if (userToCreate.getPermissions() != null && !userToCreate.getPermissions().isEmpty()) {
|
||||
userMapper.insertPermissions(userToCreate);
|
||||
}
|
||||
} catch (PersistenceException e) {
|
||||
throw new UserAlreadyExistException(userToCreate.getId(), e);
|
||||
} finally {
|
||||
|
@ -214,6 +226,8 @@ public class UserServiceImpl implements UserService {
|
|||
user.setId(user.getId().toLowerCase());
|
||||
user.setGroups(
|
||||
user.getGroups().stream().map((String::toLowerCase)).collect(Collectors.toSet()));
|
||||
user.setPermissions(
|
||||
user.getPermissions().stream().map((String::toLowerCase)).collect(Collectors.toSet()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,6 +249,8 @@ public class UserServiceImpl implements UserService {
|
|||
newUser.setId(newUser.getId().toLowerCase());
|
||||
newUser.setGroups(
|
||||
newUser.getGroups().stream().map((String::toLowerCase)).collect(Collectors.toSet()));
|
||||
newUser.setPermissions(
|
||||
newUser.getPermissions().stream().map((String::toLowerCase)).collect(Collectors.toSet()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import pro.taskana.user.api.models.User;
|
|||
public class UserImpl implements User {
|
||||
private String id;
|
||||
private Set<String> groups = Collections.emptySet();
|
||||
private Set<String> permissions = Collections.emptySet();
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String fullName;
|
||||
|
@ -27,6 +28,7 @@ public class UserImpl implements User {
|
|||
protected UserImpl(UserImpl copyFrom) {
|
||||
this.id = copyFrom.id;
|
||||
this.groups = copyFrom.groups;
|
||||
this.permissions = copyFrom.permissions;
|
||||
this.firstName = copyFrom.firstName;
|
||||
this.lastName = copyFrom.lastName;
|
||||
this.fullName = copyFrom.fullName;
|
||||
|
@ -62,6 +64,16 @@ public class UserImpl implements User {
|
|||
this.groups = groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermissions(Set<String> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
|
@ -201,6 +213,7 @@ public class UserImpl implements User {
|
|||
return Objects.hash(
|
||||
id,
|
||||
groups,
|
||||
permissions,
|
||||
firstName,
|
||||
lastName,
|
||||
fullName,
|
||||
|
@ -230,6 +243,7 @@ public class UserImpl implements User {
|
|||
UserImpl other = (UserImpl) obj;
|
||||
return Objects.equals(id, other.id)
|
||||
&& Objects.equals(groups, other.groups)
|
||||
&& Objects.equals(permissions, other.permissions)
|
||||
&& Objects.equals(firstName, other.firstName)
|
||||
&& Objects.equals(lastName, other.lastName)
|
||||
&& Objects.equals(fullName, other.fullName)
|
||||
|
@ -251,6 +265,8 @@ public class UserImpl implements User {
|
|||
+ id
|
||||
+ ", groups="
|
||||
+ groups
|
||||
+ ", permissions="
|
||||
+ permissions
|
||||
+ ", firstName="
|
||||
+ firstName
|
||||
+ ", lastName="
|
||||
|
|
|
@ -28,6 +28,11 @@ public class UserBuilder implements EntityBuilder<User, UserService> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder permissions(Set<String> permissions) {
|
||||
testUser.setPermissions(permissions);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder firstName(String firstName) {
|
||||
testUser.setFirstName(firstName);
|
||||
return this;
|
||||
|
|
|
@ -75,6 +75,8 @@ taskana.ldap.userOrglevel2Attribute=orgLevel2
|
|||
taskana.ldap.userOrglevel3Attribute=someDepartement
|
||||
taskana.ldap.userOrglevel4Attribute=orgLevel4
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=cn=groups
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -53,6 +53,8 @@ taskana.ldap.userOrglevel2Attribute=orgLevel2
|
|||
taskana.ldap.userOrglevel3Attribute=someDepartement
|
||||
taskana.ldap.userOrglevel4Attribute=orgLevel4
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=ou=groups
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -71,6 +71,7 @@ taskana.ldap.userOrglevel3Attribute=someDepartement
|
|||
taskana.ldap.userOrglevel4Attribute=orgLevel4
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupofuniquenames
|
||||
|
|
|
@ -16,6 +16,11 @@ cn: users
|
|||
objectclass: top
|
||||
objectclass: container
|
||||
|
||||
dn: cn=other-users,OU=Test,O=TASKANA
|
||||
cn: users
|
||||
objectclass: top
|
||||
objectclass: container
|
||||
|
||||
dn: cn=organisation,OU=Test,O=TASKANA
|
||||
cn: organisation
|
||||
objectclass: top
|
||||
|
@ -91,7 +96,7 @@ description: desc
|
|||
phoneNumber: 012345678
|
||||
mobileNumber: 09876554321
|
||||
email: Titus.Toll@taskana.de
|
||||
orgLevel1: QWERT
|
||||
orgLevel1: ABC
|
||||
orgLevel2: DEF/GHI
|
||||
someDepartement: JKL
|
||||
orgLevel4: MNO/PQR
|
||||
|
@ -104,6 +109,8 @@ sn: Toll
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 1
|
||||
cn: Titus Toll
|
||||
userPassword: teamlead-1
|
||||
permission: organize
|
||||
permission: inet
|
||||
|
||||
dn: uid=user-1-1,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -119,6 +126,8 @@ sn: Mustermann
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 1
|
||||
cn: Max Mustermann
|
||||
userPassword: user-1-1
|
||||
permission: organize
|
||||
permission: inet
|
||||
|
||||
dn: uid=user-1-2,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -134,6 +143,9 @@ sn: Eifrig
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 1
|
||||
cn: Elena Eifrig
|
||||
userPassword: user-1-2
|
||||
permission: organize
|
||||
permission: inet
|
||||
permission: program
|
||||
|
||||
dn: uid=user-1-3,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -211,6 +223,9 @@ sn: Bach
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 2
|
||||
cn: Thomas Bach
|
||||
userPassword: user-2-3
|
||||
permission: organize
|
||||
permission: inet
|
||||
permission: program
|
||||
|
||||
dn: uid=user-2-4,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -267,6 +282,9 @@ sn: Meyer
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 2
|
||||
cn: Wiebke Meyer
|
||||
userPassword: user-2-7
|
||||
permission: organize
|
||||
permission: inet
|
||||
permission: manage
|
||||
|
||||
dn: uid=user-2-8,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -352,6 +370,26 @@ sn: Bio
|
|||
ou: Organisationseinheit/Organisationseinheit B
|
||||
cn: Brunhilde Bio
|
||||
userPassword: user-b-2
|
||||
permission: organize
|
||||
permission: inet
|
||||
permission: siegen
|
||||
permission: frieden
|
||||
|
||||
########################
|
||||
# Users in other cn
|
||||
########################
|
||||
dn: uid=otheruser,cn=other-users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
objectclass: organizationalperson
|
||||
objectclass: person
|
||||
objectclass: top
|
||||
givenName: Other
|
||||
description: User in other cn than search root
|
||||
uid: otheruser
|
||||
sn: User
|
||||
ou: Other
|
||||
cn: Other User
|
||||
userPassword: otheruser
|
||||
|
||||
|
||||
########################
|
||||
|
|
|
@ -30,6 +30,7 @@ taskana.ldap.userOrglevel3Attribute=someDepartement
|
|||
taskana.ldap.userOrglevel4Attribute=orgLevel4
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=cn=groups
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -22,6 +22,7 @@ taskana.ldap.groupNameAttribute=cn
|
|||
taskana.ldap.minSearchForLength=3
|
||||
taskana.ldap.maxNumberOfReturnedAccessIds=50
|
||||
taskana.ldap.groupsOfUser=memberUid
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
|
||||
####### JobScheduler cron expression that specifies when the JobSchedler runs
|
||||
taskana.jobscheduler.async.cron=0 * * * * *
|
||||
|
|
|
@ -16,6 +16,7 @@ taskana.ldap.userLastnameAttribute=sn
|
|||
taskana.ldap.userFullnameAttribute=cn
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupofuniquenames
|
||||
|
|
|
@ -23,6 +23,7 @@ taskana.ldap.userOrglevel3Attribute=someDepartement
|
|||
taskana.ldap.userOrglevel4Attribute=orgLevel4
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -21,6 +21,7 @@ taskana.ldap.userOrglevel3Attribute=someDepartement
|
|||
taskana.ldap.userOrglevel4Attribute=orgLevel4
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -109,6 +109,8 @@ sn: Toll
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 1
|
||||
cn: Titus Toll
|
||||
userPassword: teamlead-1
|
||||
permission: organize
|
||||
permission: inet
|
||||
|
||||
dn: uid=user-1-1,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -124,6 +126,8 @@ sn: Mustermann
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 1
|
||||
cn: Max Mustermann
|
||||
userPassword: user-1-1
|
||||
permission: organize
|
||||
permission: inet
|
||||
|
||||
dn: uid=user-1-2,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -139,6 +143,9 @@ sn: Eifrig
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 1
|
||||
cn: Elena Eifrig
|
||||
userPassword: user-1-2
|
||||
permission: organize
|
||||
permission: inet
|
||||
permission: program
|
||||
|
||||
dn: uid=user-1-3,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -216,6 +223,9 @@ sn: Bach
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 2
|
||||
cn: Thomas Bach
|
||||
userPassword: user-2-3
|
||||
permission: organize
|
||||
permission: inet
|
||||
permission: program
|
||||
|
||||
dn: uid=user-2-4,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -272,6 +282,9 @@ sn: Meyer
|
|||
ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 2
|
||||
cn: Wiebke Meyer
|
||||
userPassword: user-2-7
|
||||
permission: organize
|
||||
permission: inet
|
||||
permission: manage
|
||||
|
||||
dn: uid=user-2-8,cn=users,OU=Test,O=TASKANA
|
||||
objectclass: inetorgperson
|
||||
|
@ -357,6 +370,10 @@ sn: Bio
|
|||
ou: Organisationseinheit/Organisationseinheit B
|
||||
cn: Brunhilde Bio
|
||||
userPassword: user-b-2
|
||||
permission: organize
|
||||
permission: inet
|
||||
permission: siegen
|
||||
permission: frieden
|
||||
|
||||
########################
|
||||
# Users in other cn
|
||||
|
|
|
@ -413,6 +413,10 @@ public class LdapClient {
|
|||
return LdapSettings.TASKANA_LDAP_USER_MEMBER_OF_GROUP_ATTRIBUTE.getValueFromEnv(env);
|
||||
}
|
||||
|
||||
public String getUserPermissionsAttribute() {
|
||||
return LdapSettings.TASKANA_LDAP_USER_PERMISSIONS_ATTRIBUTE.getValueFromEnv(env);
|
||||
}
|
||||
|
||||
public String getGroupSearchBase() {
|
||||
return LdapSettings.TASKANA_LDAP_GROUP_SEARCH_BASE.getValueFromEnv(env);
|
||||
}
|
||||
|
@ -538,6 +542,7 @@ public class LdapClient {
|
|||
return new String[] {
|
||||
getUserIdAttribute(),
|
||||
getUserMemberOfGroupAttribute(),
|
||||
getUserPermissionsAttribute(),
|
||||
getUserFirstnameAttribute(),
|
||||
getUserLastnameAttribute(),
|
||||
getUserFullnameAttribute(),
|
||||
|
@ -630,6 +635,20 @@ public class LdapClient {
|
|||
return groups;
|
||||
}
|
||||
|
||||
private Set<String> getPermissionIdsFromContext(final DirContextOperations context) {
|
||||
String[] permissionAttributes = context.getStringAttributes(getUserPermissionsAttribute());
|
||||
Set<String> permissions =
|
||||
permissionAttributes != null ? Set.of(permissionAttributes) : Collections.emptySet();
|
||||
if (useLowerCaseForAccessIds) {
|
||||
permissions =
|
||||
permissions.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/** Context Mapper for user entries. */
|
||||
class GroupContextMapper extends AbstractContextMapper<AccessIdRepresentationModel> {
|
||||
|
||||
|
@ -650,6 +669,7 @@ public class LdapClient {
|
|||
final User user = new UserImpl();
|
||||
user.setId(getUserIdFromContext(context));
|
||||
user.setGroups(getGroupIdsFromContext(context));
|
||||
user.setPermissions(getPermissionIdsFromContext(context));
|
||||
user.setFirstName(context.getStringAttribute(getUserFirstnameAttribute()));
|
||||
user.setLastName(context.getStringAttribute(getUserLastnameAttribute()));
|
||||
user.setFullName(context.getStringAttribute(getUserFullnameAttribute()));
|
||||
|
|
|
@ -19,6 +19,7 @@ enum LdapSettings {
|
|||
TASKANA_LDAP_USER_ORG_LEVEL_3_ATTRIBUTE("taskana.ldap.userOrglevel3Attribute"),
|
||||
TASKANA_LDAP_USER_ORG_LEVEL_4_ATTRIBUTE("taskana.ldap.userOrglevel4Attribute"),
|
||||
TASKANA_LDAP_USER_MEMBER_OF_GROUP_ATTRIBUTE("taskana.ldap.userMemberOfGroupAttribute"),
|
||||
TASKANA_LDAP_USER_PERMISSIONS_ATTRIBUTE("taskana.ldap.userPermissionsAttribute"),
|
||||
TASKANA_LDAP_GROUP_SEARCH_BASE("taskana.ldap.groupSearchBase"),
|
||||
TASKANA_LDAP_BASE_DN("taskana.ldap.baseDn"),
|
||||
TASKANA_LDAP_GROUP_SEARCH_FILTER_NAME("taskana.ldap.groupSearchFilterName"),
|
||||
|
|
|
@ -62,7 +62,7 @@ public class UserInfoRefreshJob extends AbstractTaskanaJob {
|
|||
.map(refreshUserPostprocessorManager::processUserAfterRefresh)
|
||||
.collect(Collectors.toList());
|
||||
addExistingConfigurationDataToUsers(usersAfterProcessing);
|
||||
clearExistingUsersAndGroups();
|
||||
clearExistingUsersAndGroupsAndPermissions();
|
||||
insertNewUsers(usersAfterProcessing);
|
||||
|
||||
LOGGER.info("Job to refresh all user info has finished.");
|
||||
|
@ -72,18 +72,18 @@ public class UserInfoRefreshJob extends AbstractTaskanaJob {
|
|||
}
|
||||
}
|
||||
|
||||
private void clearExistingUsersAndGroups() {
|
||||
private void clearExistingUsersAndGroupsAndPermissions() {
|
||||
|
||||
sqlConnectionRunner.runWithConnection(
|
||||
connection -> {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Trying to delete all users and groups");
|
||||
LOGGER.debug("Trying to delete all users, groups and permissions");
|
||||
}
|
||||
String sql = "DELETE FROM USER_INFO; DELETE FROM GROUP_INFO";
|
||||
String sql = "DELETE FROM USER_INFO; DELETE FROM GROUP_INFO; DELETE FROM PERMISSION_INFO";
|
||||
PreparedStatement statement = connection.prepareStatement(sql);
|
||||
statement.execute();
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Successfully deleted all users and groups");
|
||||
LOGGER.debug("Successfully deleted all users, groups and permissions");
|
||||
}
|
||||
|
||||
if (!connection.getAutoCommit()) {
|
||||
|
|
|
@ -22,6 +22,7 @@ public class UserRepresentationModelAssembler
|
|||
UserRepresentationModel repModel = new UserRepresentationModel();
|
||||
repModel.setUserId(entity.getId());
|
||||
repModel.setGroups(entity.getGroups());
|
||||
repModel.setPermissions(entity.getPermissions());
|
||||
repModel.setFirstName(entity.getFirstName());
|
||||
repModel.setLastName(entity.getLastName());
|
||||
repModel.setFullName(entity.getFullName());
|
||||
|
@ -43,6 +44,7 @@ public class UserRepresentationModelAssembler
|
|||
UserImpl user = new UserImpl();
|
||||
user.setId(repModel.getUserId());
|
||||
user.setGroups(repModel.getGroups());
|
||||
user.setPermissions(repModel.getPermissions());
|
||||
user.setFirstName(repModel.getFirstName());
|
||||
user.setLastName(repModel.getLastName());
|
||||
user.setFullName(repModel.getFullName());
|
||||
|
|
|
@ -14,6 +14,8 @@ public class UserRepresentationModel extends RepresentationModel<UserRepresentat
|
|||
@NotNull private String userId;
|
||||
/** The groups of the User. */
|
||||
private Set<String> groups;
|
||||
/** The permissions of the User. */
|
||||
private Set<String> permissions;
|
||||
/**
|
||||
* The domains of the User.
|
||||
*
|
||||
|
@ -62,6 +64,14 @@ public class UserRepresentationModel extends RepresentationModel<UserRepresentat
|
|||
this.groups = groups;
|
||||
}
|
||||
|
||||
public Set<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(Set<String> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
@ -172,6 +182,7 @@ public class UserRepresentationModel extends RepresentationModel<UserRepresentat
|
|||
super.hashCode(),
|
||||
userId,
|
||||
groups,
|
||||
permissions,
|
||||
domains,
|
||||
firstName,
|
||||
lastName,
|
||||
|
@ -201,6 +212,7 @@ public class UserRepresentationModel extends RepresentationModel<UserRepresentat
|
|||
UserRepresentationModel other = (UserRepresentationModel) obj;
|
||||
return Objects.equals(userId, other.userId)
|
||||
&& Objects.equals(groups, other.groups)
|
||||
&& Objects.equals(permissions, other.permissions)
|
||||
&& Objects.equals(domains, other.domains)
|
||||
&& Objects.equals(firstName, other.firstName)
|
||||
&& Objects.equals(lastName, other.lastName)
|
||||
|
|
|
@ -215,6 +215,7 @@ class LdapClientTest {
|
|||
{"taskana.ldap.userSearchFilterName", "objectclass"},
|
||||
{"taskana.ldap.groupsOfUser", "memberUid"},
|
||||
{"taskana.ldap.groupNameAttribute", "cn"},
|
||||
{"taskana.ldap.userPermissionsAttribute", "permission"},
|
||||
{"taskana.ldap.groupSearchFilterValue", "groupOfUniqueNames"},
|
||||
{"taskana.ldap.groupSearchFilterName", "objectclass"},
|
||||
{"taskana.ldap.groupSearchBase", "ou=groups"},
|
||||
|
@ -230,7 +231,7 @@ class LdapClientTest {
|
|||
{"taskana.ldap.userOrglevel1Attribute", "orgLevel1"},
|
||||
{"taskana.ldap.userOrglevel2Attribute", "orgLevel2"},
|
||||
{"taskana.ldap.userOrglevel3Attribute", "orgLevel3"},
|
||||
{"taskana.ldap.userOrglevel4Attribute", "orgLevel4"},
|
||||
{"taskana.ldap.userOrglevel4Attribute", "orgLevel4"}
|
||||
})
|
||||
.forEach(
|
||||
strings ->
|
||||
|
|
|
@ -91,6 +91,23 @@ class UserInfoRefreshJobIntTest {
|
|||
.hasSameSizeAs(ldapGroups)
|
||||
.containsExactlyElementsOf(ldapGroups);
|
||||
}
|
||||
|
||||
// validate permissions
|
||||
for (int i = 0; i < users.size(); i++) {
|
||||
User user = users.get(i);
|
||||
List<String> permissionIds = getPermissionInfo(connection, user.getId());
|
||||
permissionIds.sort(Comparator.naturalOrder());
|
||||
|
||||
User ldapUser = ldapusers.get(i);
|
||||
List<String> ldapPermissions =
|
||||
ldapUser.getPermissions().stream()
|
||||
.sorted(Comparator.naturalOrder())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(permissionIds)
|
||||
.hasSameSizeAs(ldapPermissions)
|
||||
.containsExactlyElementsOf(ldapPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,4 +159,19 @@ class UserInfoRefreshJobIntTest {
|
|||
}
|
||||
return groupIds;
|
||||
}
|
||||
|
||||
private List<String> getPermissionInfo(Connection connection, String userId) throws Exception {
|
||||
List<String> permissionIds = new ArrayList<>();
|
||||
PreparedStatement ps =
|
||||
connection.prepareStatement(
|
||||
"SELECT permission_id FROM "
|
||||
+ connection.getSchema()
|
||||
+ ".permission_info WHERE user_id = ?");
|
||||
ps.setString(1, userId);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
permissionIds.add(rs.getString(1));
|
||||
}
|
||||
return permissionIds;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,6 +184,7 @@ class UserControllerIntTest {
|
|||
UserRepresentationModel newUser = new UserRepresentationModel();
|
||||
newUser.setUserId("12345");
|
||||
newUser.setGroups(Set.of("group1", "group2"));
|
||||
newUser.setPermissions(Set.of("perm1", "perm2"));
|
||||
newUser.setFirstName("Hans");
|
||||
newUser.setLastName("Georg");
|
||||
newUser.setFullName("Georg, Hans");
|
||||
|
|
|
@ -29,6 +29,7 @@ class UserRepresentationModelAssemblerTest {
|
|||
UserImpl user = (UserImpl) userService.newUser();
|
||||
user.setId("user-1-2");
|
||||
user.setGroups(Set.of("group1", "group2"));
|
||||
user.setPermissions(Set.of("perm1", "perm2"));
|
||||
user.setFirstName("Hans");
|
||||
user.setLastName("Georg");
|
||||
user.setFullName("Hans Georg");
|
||||
|
@ -52,6 +53,7 @@ class UserRepresentationModelAssemblerTest {
|
|||
UserRepresentationModel repModel = new UserRepresentationModel();
|
||||
repModel.setUserId("user-1-2");
|
||||
repModel.setGroups(Set.of("group1", "group2"));
|
||||
repModel.setPermissions(Set.of("perm1", "perm2"));
|
||||
repModel.setFirstName("Hans");
|
||||
repModel.setLastName("Georg");
|
||||
repModel.setFullName("Hans Georg");
|
||||
|
@ -75,6 +77,7 @@ class UserRepresentationModelAssemblerTest {
|
|||
UserImpl user = (UserImpl) userService.newUser();
|
||||
user.setId("user-1-2");
|
||||
user.setGroups(Set.of("group1", "group2"));
|
||||
user.setPermissions(Set.of("perm1", "perm2"));
|
||||
user.setFirstName("Hans");
|
||||
user.setLastName("Georg");
|
||||
user.setFullName("Hans Georg");
|
||||
|
@ -104,6 +107,7 @@ class UserRepresentationModelAssemblerTest {
|
|||
|
||||
assertThat(entity.getId()).isEqualTo(repModel.getUserId());
|
||||
assertThat(entity.getGroups()).isEqualTo(repModel.getGroups());
|
||||
assertThat(entity.getPermissions()).isEqualTo(repModel.getPermissions());
|
||||
assertThat(entity.getFirstName()).isEqualTo(repModel.getFirstName());
|
||||
assertThat(entity.getLastName()).isEqualTo(repModel.getLastName());
|
||||
assertThat(entity.getFullName()).isEqualTo(repModel.getFullName());
|
||||
|
|
|
@ -28,6 +28,7 @@ taskana.ldap.userOrglevel3Attribute=someDepartement
|
|||
taskana.ldap.userOrglevel4Attribute=orgLevel4
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -34,6 +34,7 @@ taskana.ldap.userOrglevel3Attribute=someDepartement
|
|||
taskana.ldap.userOrglevel4Attribute=orgLevel4
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=memberOf
|
||||
taskana.ldap.userPermissionsAttribute=permission
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
Loading…
Reference in New Issue