TSK-714 - Improve all workbasket access items for a user screen
This commit is contained in:
parent
b7aee393ae
commit
3d1a921394
|
@ -288,8 +288,8 @@ public class LdapCacheTestImpl implements LdapCache {
|
|||
new AccessIdResource("team_4", "cn=team_4" + ",ou=groups,o=TaskanaTest")));
|
||||
|
||||
@Override
|
||||
public List<AccessIdResource> findMatchingAccessId(String searchFor, int maxNumerOfReturnedAccessIds) {
|
||||
return findAccessIdResource(searchFor, maxNumerOfReturnedAccessIds, false);
|
||||
public List<AccessIdResource> findMatchingAccessId(String searchFor, int maxNumberOfReturnedAccessIds) {
|
||||
return findAcessIdResource(searchFor, maxNumberOfReturnedAccessIds, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -297,10 +297,17 @@ public class LdapCacheTestImpl implements LdapCache {
|
|||
if (users == null) {
|
||||
addUsersToGroups();
|
||||
}
|
||||
return findAccessIdResource(searchFor, maxNumberOfReturnedAccessIds, true);
|
||||
return findAcessIdResource(searchFor, maxNumberOfReturnedAccessIds, true);
|
||||
}
|
||||
|
||||
private List<AccessIdResource> findAccessIdResource(String searchFor, int maxNumerOfReturnedAccessIds,
|
||||
@Override
|
||||
public List<AccessIdResource> validateAccessId(String accessId) {
|
||||
return accessIds.stream()
|
||||
.filter(t -> (t.getAccessId().equalsIgnoreCase(accessId.toLowerCase())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<AccessIdResource> findAcessIdResource(String searchFor, int maxNumberOfReturnedAccessIds,
|
||||
boolean groupMember) {
|
||||
List<AccessIdResource> usersAndGroups = accessIds.stream()
|
||||
.filter(t -> (t.getName().toLowerCase().contains(searchFor.toLowerCase())
|
||||
|
@ -321,7 +328,7 @@ public class LdapCacheTestImpl implements LdapCache {
|
|||
});
|
||||
|
||||
List<AccessIdResource> result = usersAndGroups.subList(0,
|
||||
Math.min(usersAndGroups.size(), maxNumerOfReturnedAccessIds));
|
||||
Math.min(usersAndGroups.size(), maxNumberOfReturnedAccessIds));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class AccessIdValidationControllerTest {
|
|||
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
|
||||
HttpEntity<String> request = new HttpEntity<String>(headers);
|
||||
ResponseEntity<List<AccessIdResource>> response = template.exchange(
|
||||
"http://127.0.0.1:" + port + "/v1/access-ids?searchFor=ali", HttpMethod.GET, request,
|
||||
"http://127.0.0.1:" + port + "/v1/access-ids?search-for=ali", HttpMethod.GET, request,
|
||||
new ParameterizedTypeReference<List<AccessIdResource>>() {
|
||||
|
||||
});
|
||||
|
@ -73,7 +73,7 @@ public class AccessIdValidationControllerTest {
|
|||
HttpEntity<String> request = new HttpEntity<String>(headers);
|
||||
try {
|
||||
template.exchange(
|
||||
"http://127.0.0.1:" + port + "/v1/access-ids?searchFor=al", HttpMethod.GET, request,
|
||||
"http://127.0.0.1:" + port + "/v1/access-ids?search-for=al", HttpMethod.GET, request,
|
||||
new ParameterizedTypeReference<List<AccessIdResource>>() {
|
||||
|
||||
});
|
||||
|
|
|
@ -90,7 +90,7 @@ public class GenenalExceptionHandlingTest {
|
|||
|
||||
AccessIdController.setLdapCache(new LdapCacheTestImpl());
|
||||
template.exchange(
|
||||
server + port + "/v1/access-ids?searchFor=al", HttpMethod.GET, request,
|
||||
server + port + "/v1/access-ids?search-for=al", HttpMethod.GET, request,
|
||||
new ParameterizedTypeReference<List<AccessIdResource>>() {
|
||||
|
||||
});
|
||||
|
|
|
@ -16,17 +16,24 @@ public interface LdapCache {
|
|||
*
|
||||
* @param searchFor
|
||||
* the search string. The search is performed over names and ids of users and groups.
|
||||
* @param maxNumerOfReturnedAccessIds
|
||||
* @param maxNumberOfReturnedAccessIds
|
||||
* the maximum number of results to return.
|
||||
* @return a List of access ids for users and group where the name or id contains the search string.
|
||||
*/
|
||||
List<AccessIdResource> findMatchingAccessId(String searchFor, int maxNumerOfReturnedAccessIds);
|
||||
List<AccessIdResource> findMatchingAccessId(String searchFor, int maxNumberOfReturnedAccessIds);
|
||||
|
||||
/**
|
||||
*
|
||||
* Find the groups belong to a user.
|
||||
* @param searchFor the search string. The search is performed over names and ids of group .
|
||||
* @param maxNumerOfReturnedAccessIds
|
||||
* @param maxNumberOfReturnedAccessIds the maximum number of results to return.
|
||||
* @return
|
||||
*/
|
||||
List<AccessIdResource> findGroupsOfUser(String searchFor, int maxNumerOfReturnedAccessIds);
|
||||
List<AccessIdResource> findGroupsOfUser(String searchFor, int maxNumberOfReturnedAccessIds);
|
||||
|
||||
/**
|
||||
* Validate a access id.
|
||||
* @param accessId the search string.
|
||||
* @return the corresponding access id.
|
||||
*/
|
||||
List<AccessIdResource> validateAccessId(String accessId);
|
||||
}
|
||||
|
|
|
@ -35,28 +35,40 @@ public class AccessIdController {
|
|||
|
||||
@GetMapping
|
||||
public ResponseEntity<List<AccessIdResource>> validateAccessIds(
|
||||
@RequestParam String searchFor, @RequestParam(required = false) boolean searchInGroups) throws InvalidArgumentException {
|
||||
@RequestParam("search-for") String searchFor) throws InvalidArgumentException {
|
||||
if (searchFor.length() < ldapClient.getMinSearchForLength()) {
|
||||
throw new InvalidArgumentException("searchFor string '" + searchFor + "' is too short. Minimum searchFor length = "
|
||||
throw new InvalidArgumentException(
|
||||
"searchFor string '" + searchFor + "' is too short. Minimum searchFor length = "
|
||||
+ ldapClient.getMinSearchForLength());
|
||||
}
|
||||
if (ldapClient.useLdap()) {
|
||||
List<AccessIdResource> accessIdUsers = ldapClient.searchUsersAndGroups(searchFor);
|
||||
if (searchInGroups) {
|
||||
List<AccessIdResource> accessIdGroups = ldapClient.searchGroupsofUsersIsMember(searchFor);
|
||||
accessIdUsers.addAll(accessIdGroups);
|
||||
}
|
||||
return new ResponseEntity<>(accessIdUsers, HttpStatus.OK);
|
||||
} else if (ldapCache != null) {
|
||||
if (searchInGroups) {
|
||||
return new ResponseEntity<>(
|
||||
ldapCache.findGroupsOfUser(searchFor, ldapClient.getMaxNumberOfReturnedAccessIds()),
|
||||
HttpStatus.OK);
|
||||
} else {
|
||||
return new ResponseEntity<>(
|
||||
ldapCache.findMatchingAccessId(searchFor, ldapClient.getMaxNumberOfReturnedAccessIds()),
|
||||
HttpStatus.OK);
|
||||
} else {
|
||||
return new ResponseEntity<>(new ArrayList<>(), HttpStatus.NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(path = "/groups")
|
||||
public ResponseEntity<List<AccessIdResource>> getGroupsByAccessId(
|
||||
@RequestParam("access-id") String accessId) throws InvalidArgumentException {
|
||||
if (ldapClient.useLdap() || ldapCache != null) {
|
||||
if (!validateAccessId(accessId)) {
|
||||
throw new InvalidArgumentException("The accessId is invalid");
|
||||
}
|
||||
}
|
||||
List<AccessIdResource> accessIdUsers;
|
||||
if (ldapClient.useLdap()) {
|
||||
accessIdUsers = ldapClient.searchUsersAndGroups(accessId);
|
||||
accessIdUsers.addAll(ldapClient.searchGroupsofUsersIsMember(accessId));
|
||||
return new ResponseEntity<>(accessIdUsers, HttpStatus.OK);
|
||||
} else if (ldapCache != null) {
|
||||
accessIdUsers = ldapCache.findGroupsOfUser(accessId, ldapClient.getMaxNumberOfReturnedAccessIds());
|
||||
return new ResponseEntity<>(accessIdUsers, HttpStatus.OK);
|
||||
} else {
|
||||
return new ResponseEntity<>(new ArrayList<>(), HttpStatus.NOT_FOUND);
|
||||
}
|
||||
|
@ -66,4 +78,9 @@ public class AccessIdController {
|
|||
ldapCache = cache;
|
||||
}
|
||||
|
||||
private boolean validateAccessId(String accessId) throws InvalidArgumentException {
|
||||
return (ldapClient.useLdap() && ldapClient.searchUsersAndGroups(accessId).size() == 1) || (!ldapClient.useLdap()
|
||||
&& ldapCache.validateAccessId(accessId).size() == 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="pull-right btn-group">
|
||||
<button *ngIf="AccessItemsForm" type="button" (click)="revokeAccess()" class="btn btn-default" data-toggle="tooltip" title="Revoke access">
|
||||
<span class="glyphicon glyphicon-remove red" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<h4 class="panel-header">Acces items management</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
@ -50,7 +45,8 @@
|
|||
<th class="text-align"><input type="text" formControlName="accessIdFilter" (keyup.enter)="searchForAccessItemsWorkbaskets()"
|
||||
class="form-control" placeholder="Access id filter"></th>
|
||||
<th>
|
||||
<button type="button" (click)="searchForAccessItemsWorkbaskets()" class="btn btn-default" data-toggle="tooltip" title="Search">
|
||||
<button type="button" (click)="searchForAccessItemsWorkbaskets()" class="btn btn-default" data-toggle="tooltip"
|
||||
title="Search">
|
||||
<span class="glyphicon glyphicon-search blue" aria-hidden="true"></span>
|
||||
</button>
|
||||
</th>
|
||||
|
@ -80,8 +76,9 @@
|
|||
</td>
|
||||
<td *ngIf="accessIdField.lookupField else accessIdInput" colspan="2" class="text-align text-width taskana-type-ahead">
|
||||
<div>
|
||||
<taskana-type-ahead formControlName="accessId" placeHolderMessage="* Access id is required" [validationValue]="toogleValidationAccessIdMap.get(index)"
|
||||
[displayError]="!isFieldValid('accessItem.value.accessId', index)" [disable]=true></taskana-type-ahead>
|
||||
<taskana-type-ahead formControlName="accessId" placeHolderMessage="* Access id is required"
|
||||
[validationValue]="toogleValidationAccessIdMap.get(index)" [displayError]="!isFieldValid('accessItem.value.accessId', index)"
|
||||
[disable]=true></taskana-type-ahead>
|
||||
</div>
|
||||
</td>
|
||||
<ng-template #accessIdInput>
|
||||
|
@ -163,6 +160,41 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<button *ngIf="!isGroup" class="pull-left btn-group" type="button" class="btn btn-primary" data-toggle="modal"
|
||||
data-target="#myModal">
|
||||
Belonging groups
|
||||
</button>
|
||||
|
||||
<div class="modal" id="myModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Belonging groups</h4>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<ul *ngIf="belongingGroups !== undefined && belongingGroups.length > 0 " class="list-group">
|
||||
<li *ngFor="let group of belongingGroups" class="list-group-item">{{group.name}}</li>
|
||||
</ul>
|
||||
<p *ngIf="belongingGroups === undefined || belongingGroups.length === 0">The user is not associated to any groups</p>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pull-right btn-group">
|
||||
<button *ngIf="AccessItemsForm" type="button" class="btn btn-default" data-toggle="tooltip" title="Revoke access"
|
||||
[disabled]=isGroup>
|
||||
<span class="glyphicon glyphicon-remove red" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -31,3 +31,8 @@ td {
|
|||
word-wrap:break-word;
|
||||
}
|
||||
.min-width{ min-width: 135px;}
|
||||
|
||||
.modal-title {
|
||||
font-weight: bold;
|
||||
display: inline;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,11 @@ export class AccessItemsManagementComponent implements OnInit, OnDestroy {
|
|||
accessItemPermissionsSubscription: Subscription;
|
||||
accessItemInformationsubscription: Subscription;
|
||||
accessIdsWithGroups: Array<AccessIdDefinition>;
|
||||
belongingGroups: Array<AccessIdDefinition>;
|
||||
sortingFields = new Map([['workbasket-key', 'Workbasket Key'], ['access-id', 'Access id']]);
|
||||
sortModel: SortingModel;
|
||||
isGroup: boolean;
|
||||
groupsKey = 'ou=groups';
|
||||
|
||||
|
||||
accessIdField = this.customFieldsService.getCustomField('Owner', 'workbaskets.access-items.accessId');
|
||||
|
@ -89,11 +92,13 @@ export class AccessItemsManagementComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
if (!this.AccessItemsForm || this.accessIdPrevious !== selected.accessId) {
|
||||
this.accessIdPrevious = selected.accessId
|
||||
this.isGroup = selected.accessId.includes(this.groupsKey);
|
||||
|
||||
this.unSubscribe(this.accessItemInformationsubscription)
|
||||
this.accessItemInformationsubscription = this.accessIdsService.getAccessItemsInformation(selected.accessId, true)
|
||||
.subscribe((accessIdsWithGroups: Array<AccessIdDefinition>) => {
|
||||
this.accessIdsWithGroups = accessIdsWithGroups;
|
||||
this.belongingGroups = accessIdsWithGroups.filter(item => item.accessId.includes(this.groupsKey));
|
||||
this.searchForAccessItemsWorkbaskets();
|
||||
},
|
||||
error => {
|
||||
|
|
|
@ -21,7 +21,11 @@ export class AccessIdsService {
|
|||
if (!token || token.length < 3) {
|
||||
return of([]);
|
||||
}
|
||||
return this.httpClient.get<Array<AccessIdDefinition>>(`${this.url}?searchFor=${token}&searchInGroups=${searchInGroups}`);
|
||||
if (searchInGroups) {
|
||||
return this.httpClient.get<Array<AccessIdDefinition>>(`${this.url}/groups?access-id=${token}`);
|
||||
} else {
|
||||
return this.httpClient.get<Array<AccessIdDefinition>>(`${this.url}?search-for=${token}`);
|
||||
}
|
||||
};
|
||||
|
||||
getAccessItemsPermissions(
|
||||
|
|
|
@ -6,3 +6,7 @@
|
|||
.sortby-dropdown {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
</span>
|
||||
|
||||
<div class="input-group">
|
||||
<input #inputTypeAhead class=" form-control input-text" (blur)="typeaheadOnSelect({'item':dataSource.selected})" name="accessItem-{{index}}"
|
||||
<input #inputTypeAhead class=" form-control input-text" [ngClass]="{'invalid': dataSource.length == null}" (blur)="typeaheadOnSelect({'item':dataSource.selected})" name="accessItem-{{index}}"
|
||||
required #accessItemName="ngModel" [(ngModel)]="value" [typeahead]="dataSource" typeaheadOptionField="name" [typeaheadItemTemplate]="customItemTemplate"
|
||||
(typeaheadOnSelect)="typeaheadOnSelect($event, index)" [typeaheadScrollable]="true" [typeaheadOptionsInScrollableView]="typeaheadOptionsInScrollableView"
|
||||
[typeaheadMinLength]="typeaheadMinLength" [typeaheadWaitMs]="typeaheadWaitMs" (typeaheadLoading)="changeTypeaheadLoading($event)"
|
||||
|
|
|
@ -91,3 +91,7 @@
|
|||
.disable {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.invalid {
|
||||
color: $invalid;
|
||||
}
|
||||
|
|
|
@ -9,3 +9,4 @@ $invalid: #d82626;
|
|||
$aquamarine: #22a39f;
|
||||
$pallete-blue: #36bcee;
|
||||
$pallete-green: #5fbca1;
|
||||
$transparent-grey: rgba(192, 192, 192, 0.65);
|
||||
|
|
|
@ -353,3 +353,7 @@ li.list-group-item:hover {
|
|||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-backdrop.show {
|
||||
background-color: $transparent-grey;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue