use of com.b2international.snowowl.core.identity.User in project snow-owl by b2ihealthcare.
the class CommitInfoRequestTest method searchCommitOnSubBranch.
@Test
public void searchCommitOnSubBranch() {
// Search with no branch filter, to test security filter for user with limited resources
final String oid = UUID.randomUUID().toString();
final String shortName = "Resource7";
final String comment = "Code system for commit info 7";
final String branchName = "Test7";
final String commitComment = "Create Description 7";
final String term = "Test Description 7";
// Commit on resource branch
createCodeSystem(shortName, oid, comment);
createDescription(ResourceURI.of(CodeSystem.RESOURCE_TYPE, shortName), term, commitComment);
// Commit on version branch
final String branchPath = createBranch(String.format("%s/%s", BRANCH, shortName), branchName);
createDescription(ResourceURI.branch(CodeSystem.RESOURCE_TYPE, shortName, branchName), term, commitComment);
// Commit on deeper branch
final String newBranchName = String.format("%s/%s", branchName, branchName);
createBranch(branchPath, branchName);
createDescription(ResourceURI.branch(CodeSystem.RESOURCE_TYPE, shortName, newBranchName), term, commitComment);
final Permission userPermission = Permission.requireAll(Permission.OPERATION_BROWSE, String.format("%s*", shortName));
final List<Role> roles = List.of(new Role("Editor", List.of(userPermission)));
final String userName = "User7";
final User user = new User(userName, roles);
final IEventBus authorizedBus = new AuthorizedEventBus(bus, ImmutableMap.of(AuthorizedRequest.AUTHORIZATION_HEADER, Services.service(JWTGenerator.class).generate(user)));
// Search as user with permission only to access the resource and one sub branch
assertEquals(2, RepositoryRequests.commitInfos().prepareSearchCommitInfo().filterByComment(commitComment).build(REPOSITORY_ID).execute(authorizedBus).getSync().getTotal());
// Search as admin user with permission to access all
assertEquals(3, RepositoryRequests.commitInfos().prepareSearchCommitInfo().filterByComment(commitComment).build(REPOSITORY_ID).execute(bus).getSync().getTotal());
}
use of com.b2international.snowowl.core.identity.User in project snow-owl by b2ihealthcare.
the class RateLimitingRequest method execute.
@Override
public R execute(ServiceProvider context) {
final User user = context.service(User.class);
if (user != User.SYSTEM) {
// rate limit only non-system user requests
final String username = user.getUsername();
final RateLimitConsumption consumption = context.service(RateLimiter.class).consume(username);
if (consumption.isConsumed()) {
context.service(ResponseHeaders.class).set("X-Rate-Limit-Remaining", Long.toString(consumption.getRemainingTokens()));
} else {
throw new TooManyRequestsException(consumption.getSecondsToWait());
}
}
return next(context);
}
use of com.b2international.snowowl.core.identity.User in project snow-owl by b2ihealthcare.
the class BaseResourceSearchRequest method addSecurityFilter.
/**
* Configures security filters to allow access to certain resources only. This method is no-op if the given {@link ServiceProvider context}'s {@link User} is an administrator or has read access to everything.
*
* @param context - the context where user information will be extracted
* @param queryBuilder - the query builder to append the clauses to
*/
protected final void addSecurityFilter(ServiceProvider context, ExpressionBuilder queryBuilder) {
final User user = context.service(User.class);
if (user.isAdministrator() || user.hasPermission(Permission.requireAll(Permission.OPERATION_BROWSE, Permission.ALL))) {
return;
}
// extract read permissions
final List<Permission> readPermissions = user.getPermissions().stream().filter(p -> Permission.ALL.equals(p.getOperation()) || Permission.OPERATION_BROWSE.equals(p.getOperation())).collect(Collectors.toList());
final Set<String> exactResourceIds = readPermissions.stream().flatMap(p -> p.getResources().stream()).filter(resource -> !resource.endsWith("*")).collect(Collectors.toSet());
final Set<String> resourceIdPrefixes = readPermissions.stream().flatMap(p -> p.getResources().stream()).filter(resource -> resource.endsWith("*")).map(resource -> resource.substring(0, resource.length() - 1)).collect(Collectors.toSet());
if (!exactResourceIds.isEmpty() || !resourceIdPrefixes.isEmpty()) {
context.log().info("Restricting user '{}' to resources exact: '{}', prefix: '{}'.", user.getUsername(), ImmutableSortedSet.copyOf(exactResourceIds), ImmutableSortedSet.copyOf(resourceIdPrefixes));
ExpressionBuilder bool = Expressions.builder();
// the permissions give access to either
if (!exactResourceIds.isEmpty()) {
// explicit IDs
bool.should(ResourceDocument.Expressions.ids(exactResourceIds));
// or the permitted resources are bundles which give access to all resources within it (recursively)
bool.should(ResourceDocument.Expressions.bundleIds(exactResourceIds));
bool.should(ResourceDocument.Expressions.bundleAncestorIds(exactResourceIds));
}
if (!resourceIdPrefixes.isEmpty()) {
// partial IDs, prefixes
bool.should(ResourceDocument.Expressions.idPrefixes(resourceIdPrefixes));
// or the permitted resources are bundle ID prefixes which give access to all resources within it (recursively)
bool.should(ResourceDocument.Expressions.bundleIdPrefixes(resourceIdPrefixes));
bool.should(ResourceDocument.Expressions.bundleAncestorIdPrefixes(resourceIdPrefixes));
}
queryBuilder.filter(bool.build());
} else {
throw new NoResultException();
}
}
use of com.b2international.snowowl.core.identity.User in project snow-owl by b2ihealthcare.
the class VersionCreateRequest method execute.
@Override
public Boolean execute(RepositoryContext context) {
final String user = context.service(User.class).getUsername();
if (!resource.isHead()) {
throw new BadRequestException("Version '%s' cannot be created on unassigned branch '%s'.", version, resource).withDeveloperMessage("Did you mean to version '%s'?", resource.withoutPath());
}
if (resourcesById == null) {
resourcesById = fetchResources(context);
}
if (!resourcesById.containsKey(resource)) {
context.log().warn("Resource cannot be found during versioning: " + resourcesById + ", uri: " + resource);
throw new NotFoundException("Resource", resource.getResourceId());
}
// validate new path
RevisionBranch.BranchNameValidator.DEFAULT.checkName(version);
TerminologyResource resourceToVersion = resourcesById.get(resource);
// TODO resurrect or eliminate tooling dependencies
final List<TerminologyResource> resourcesToVersion = List.of(resourcesById.get(resource));
// final List<CodeSystem> resourcesToVersion = codeSystem.getDependenciesAndSelf()
// .stream()
// .map(resourcesById::get)
// .collect(Collectors.toList());
resourcesToVersion.stream().filter(cs -> cs.getUpgradeOf() != null).findAny().ifPresent(cs -> {
throw new BadRequestException("Upgrade resource '%s' can not be versioned.", cs.getResourceURI());
});
for (TerminologyResource terminologyResource : resourcesToVersion) {
// check that the new versionId does not conflict with any other currently available branch
final String newVersionPath = String.join(Branch.SEPARATOR, terminologyResource.getBranchPath(), version);
final String repositoryId = terminologyResource.getToolingId();
if (!force) {
// branch needs checking in the non-force cases only
try {
Branch branch = RepositoryRequests.branching().prepareGet(newVersionPath).build(repositoryId).execute(context);
if (!branch.isDeleted()) {
throw new ConflictException("An existing version or branch with path '%s' conflicts with the specified version identifier.", newVersionPath);
}
} catch (NotFoundException e) {
// branch does not exist, ignore
}
} else {
// if there is no conflict, delete the branch (the request also ignores non-existent branches)
deleteBranch(context, newVersionPath, repositoryId);
}
}
acquireLocks(context, user, resourcesToVersion);
final IProgressMonitor monitor = SubMonitor.convert(context.service(IProgressMonitor.class), TASK_WORK_STEP);
try {
// resourcesToVersion.forEach(resourceToVersion -> {
// check that the specified effective time is valid in this code system
validateVersion(context, resourceToVersion);
// version components in the given repository
new RepositoryRequest<>(resourceToVersion.getToolingId(), new BranchRequest<>(resourceToVersion.getBranchPath(), new RevisionIndexReadRequest<CommitResult>(context.service(RepositoryManager.class).get(resourceToVersion.getToolingId()).service(VersioningRequestBuilder.class).build(new VersioningConfiguration(user, resourceToVersion.getResourceURI(), version, description, effectiveTime, force))))).execute(context);
// tag the repository
doTag(context, resourceToVersion, monitor);
// create a version for the resource
return new BranchRequest<>(Branch.MAIN_PATH, new ResourceRepositoryCommitRequestBuilder().setBody(tx -> {
tx.add(VersionDocument.builder().id(resource.withPath(version).withoutResourceType()).version(version).description(description).effectiveTime(EffectiveTimes.getEffectiveTime(effectiveTime)).resource(resource).branchPath(resourceToVersion.getRelativeBranchPath(version)).author(user).createdAt(Instant.now().toEpochMilli()).updatedAt(Instant.now().toEpochMilli()).toolingId(resourceToVersion.getToolingId()).url(buildVersionUrl(context, resourceToVersion)).build());
return Boolean.TRUE;
}).setCommitComment(CompareUtils.isEmpty(commitComment) ? String.format("Version '%s' as of '%s'", resource, version) : commitComment).build()).execute(context).getResultAs(Boolean.class);
} finally {
releaseLocks(context);
if (null != monitor) {
monitor.done();
}
}
}
Aggregations