use of org.eclipse.vorto.repository.web.core.exceptions.NotAuthorizedException in project vorto by eclipse.
the class ModelRepository method getAttachmentContent.
@Override
public Optional<FileContent> getAttachmentContent(ModelId modelId, String fileName) {
return doInSession(session -> {
try {
ModelIdHelper modelIdHelper = new ModelIdHelper(modelId);
Node modelFolderNode = session.getNode(modelIdHelper.getFullPath());
if (modelFolderNode.hasNode(ATTACHMENTS_NODE)) {
Node attachmentFolderNode = modelFolderNode.getNode(ATTACHMENTS_NODE);
if (attachmentFolderNode.hasNode(fileName)) {
Node attachment = (Node) attachmentFolderNode.getNode(fileName).getPrimaryItem();
return Optional.of(new FileContent(fileName, IOUtils.toByteArray(attachment.getProperty(JCR_DATA).getBinary().getStream())));
}
}
return Optional.empty();
} catch (PathNotFoundException e) {
return Optional.empty();
} catch (AccessDeniedException e) {
throw new NotAuthorizedException(modelId);
} catch (IOException | RepositoryException e) {
throw new FatalModelRepositoryException("Something went wrong accessing the repository", e);
}
});
}
use of org.eclipse.vorto.repository.web.core.exceptions.NotAuthorizedException in project vorto by eclipse.
the class ModelRepositoryController method getModelForUI.
/**
* Fetches all data required to populate the returned {@link ModelFullDetailsDTO} (see class docs
* for details), in addition the model's "file" contents as file added to the response.<br/>
* Following error cases apply:
* <ul>
* <li>
* If {@link ModelId#fromPrettyFormat(String)} fails throwing {@link IllegalArgumentException},
* returns {@code null} with status {@link HttpStatus#NOT_FOUND}.
* </li>
* <li>
* If {@link ModelRepositoryController#getWorkspaceId(String)} fails throwing
* {@link FatalModelRepositoryException}, returns {@code null} with status
* {@link HttpStatus#NOT_FOUND}.
* </li>
* <li>
* If any operation such as:
* <ul>
* <li>
* {@link IModelRepository#getByIdWithPlatformMappings(ModelId)}
* </li>
* <li>
* {@link IModelRepository#getAttachments(ModelId)}
* </li>
* <li>
* {@link IModelPolicyManager#getPolicyEntries(ModelId)}
* </li>
* </ul>
* ... fails throwing {@link NotAuthorizedException}, returns {@code null} with status
* {@link HttpStatus#FORBIDDEN};
* </li>
* </ul>
*
* @param modelId
* @return
*/
@GetMapping("/ui/{modelId:.+}")
public ResponseEntity<ModelFullDetailsDTO> getModelForUI(@PathVariable String modelId, final HttpServletResponse response) {
try {
// resolve user
Authentication user = SecurityContextHolder.getContext().getAuthentication();
// resolve model ID
ModelId modelID = ModelId.fromPrettyFormat(modelId);
// resolve ModeShape workspace ID
String workspaceId = getWorkspaceId(modelId);
// fetches model info
ModelInfo modelInfo = getModelRepository(modelID).getByIdWithPlatformMappings(modelID);
if (Objects.isNull(modelInfo)) {
LOGGER.warn(String.format("Model resource with id [%s] not found. ", modelId));
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
// starts spawning threads to retrieve models etc.
final ExecutorService executor = Executors.newCachedThreadPool();
// fetches mappings
Collection<ModelMinimalInfoDTO> mappings = ConcurrentHashMap.newKeySet();
modelInfo.getPlatformMappings().entrySet().stream().forEach(e -> {
executor.submit(new AsyncModelMappingsFetcher(mappings, e).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory()));
});
// fetches references from model ids built with the root ModelInfo
Collection<ModelMinimalInfoDTO> references = ConcurrentHashMap.newKeySet();
modelInfo.getReferences().stream().forEach(id -> executor.submit(new AsyncModelReferenceFetcher(references, id).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory())));
// fetches referenced by
Collection<ModelMinimalInfoDTO> referencedBy = ConcurrentHashMap.newKeySet();
modelInfo.getReferencedBy().stream().forEach(id -> executor.submit(new AsyncModelReferenceFetcher(referencedBy, id).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory())));
// fetches attachments
Collection<Attachment> attachments = ConcurrentHashMap.newKeySet();
executor.submit(new AsyncModelAttachmentsFetcher(attachments, modelID, userRepositoryRoleService.isSysadmin(user.getName())).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory()));
// fetches links
Collection<ModelLink> links = ConcurrentHashMap.newKeySet();
executor.submit(new AsyncModelLinksFetcher(modelID, links).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()).with(getModelRepositoryFactory()));
// fetches available workflow actions
Collection<String> actions = ConcurrentHashMap.newKeySet();
executor.submit(new AsyncWorkflowActionsFetcher(workflowService, actions, modelID, UserContext.user(user, workspaceId)).with(SecurityContextHolder.getContext()).with(RequestContextHolder.getRequestAttributes()));
// fetches model syntax
Future<String> encodedSyntaxFuture = executor.submit(new AsyncModelSyntaxFetcher(modelID, SecurityContextHolder.getContext(), RequestContextHolder.getRequestAttributes(), getModelRepositoryFactory()));
// shuts down executor and waits for completion of tasks until configured timeout
// also retrieves callable content
executor.shutdown();
// single-threaded calls
// fetches policies in this thread
Collection<PolicyEntry> policies = getPolicyManager(workspaceId).getPolicyEntries(modelID).stream().filter(p -> userHasPolicyEntry(p, user, workspaceId)).collect(Collectors.toList());
// getting callables and setting executor timeout
String encodedSyntax = null;
try {
// callable content
encodedSyntax = encodedSyntaxFuture.get();
// timeout
if (!executor.awaitTermination(requestTimeoutInSeconds, TimeUnit.SECONDS)) {
LOGGER.warn(String.format("Requesting UI data for model ID [%s] took over [%d] seconds and programmatically timed out.", modelID, requestTimeoutInSeconds));
return new ResponseEntity<>(null, HttpStatus.GATEWAY_TIMEOUT);
}
} catch (InterruptedException ie) {
LOGGER.error("Awaiting executor termination was interrupted.");
return new ResponseEntity<>(null, HttpStatus.SERVICE_UNAVAILABLE);
} catch (ExecutionException ee) {
LOGGER.error("Failed to retrieve and encode model syntax asynchronously");
return new ResponseEntity<>(null, HttpStatus.SERVICE_UNAVAILABLE);
}
// builds DTO
ModelFullDetailsDTO dto = new ModelFullDetailsDTO().withModelInfo(modelInfo).withMappings(mappings).withReferences(references).withReferencedBy(referencedBy).withAttachments(attachments).withLinks(links).withActions(actions).withEncodedModelSyntax(encodedSyntax).withPolicies(policies);
return new ResponseEntity<>(dto, HttpStatus.OK);
}// could not resolve "pretty format" for given model ID
catch (IllegalArgumentException iae) {
LOGGER.warn(String.format("Could not resolve given model ID [%s]", modelId), iae);
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}// could not find namespace to resolve workspace ID from
catch (FatalModelRepositoryException fmre) {
LOGGER.warn(String.format("Could not resolve workspace ID from namespace inferred by model ID [%s]", modelId), fmre);
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
} catch (NotAuthorizedException nae) {
LOGGER.warn(String.format("Could not authorize fetching data from given model ID [%s] for calling user", modelId), nae);
return new ResponseEntity<>(null, HttpStatus.FORBIDDEN);
}
}
use of org.eclipse.vorto.repository.web.core.exceptions.NotAuthorizedException in project vorto by eclipse.
the class HasPermissionEvaluator method hasPermission.
@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object targetPermission) {
final String username = authentication.getName();
if (targetDomainObject instanceof ModelId) {
if (targetPermission instanceof String) {
try {
ModelId modelId = (ModelId) targetDomainObject;
String workspaceId = namespaceService.resolveWorkspaceIdForNamespace(modelId.getNamespace()).orElseThrow(() -> new ModelNotFoundException("Model '" + modelId.getPrettyFormat() + "' can't be found in any workspace."));
String permission = (String) targetPermission;
ModelInfo modelInfo = repositoryFactory.getRepository(workspaceId, authentication).getById(modelId);
if (modelInfo != null) {
if ("model:delete".equalsIgnoreCase(permission)) {
return modelInfo.getAuthor().equalsIgnoreCase(username);
} else if ("model:get".equalsIgnoreCase(permission)) {
return modelInfo.getState().equals(SimpleWorkflowModel.STATE_RELEASED.getName()) || modelInfo.getState().equals(SimpleWorkflowModel.STATE_DEPRECATED.getName()) || modelInfo.getAuthor().equals(username);
} else if ("model:owner".equalsIgnoreCase(permission)) {
return modelInfo.getAuthor().equals(username);
}
}
} catch (NotAuthorizedException ex) {
return false;
}
} else if (targetPermission instanceof Permission) {
ModelId modelId = (ModelId) targetDomainObject;
Permission permission = (Permission) targetPermission;
String workspaceId = namespaceService.resolveWorkspaceIdForNamespace(modelId.getNamespace()).orElseThrow(() -> new ModelNotFoundException("The workspace for '" + modelId.getPrettyFormat() + "' could not be found."));
return repositoryFactory.getPolicyManager(workspaceId, authentication).hasPermission(modelId, permission);
}
} else if (targetDomainObject instanceof String) {
return username.equalsIgnoreCase((String) targetDomainObject);
}
return false;
}
use of org.eclipse.vorto.repository.web.core.exceptions.NotAuthorizedException in project vorto by eclipse.
the class ModelRepositoryController method getUserPolicy.
@PreAuthorize("isAuthenticated() or hasAuthority('model_viewer')")
@GetMapping("/{modelId:.+}/policy")
public ResponseEntity<PolicyEntry> getUserPolicy(@PathVariable final String modelId) {
Objects.requireNonNull(modelId, "model ID must not be null");
Authentication user = SecurityContextHolder.getContext().getAuthentication();
ModelId modelID = ModelId.fromPrettyFormat(modelId);
String tenantId = getWorkspaceId(modelId);
try {
List<PolicyEntry> policyEntries = getPolicyManager(tenantId).getPolicyEntries(modelID).stream().filter(p -> userHasPolicyEntry(p, user, tenantId)).collect(Collectors.toList());
return getBestPolicyEntryForUser(policyEntries).map(p -> new ResponseEntity<>(p, HttpStatus.OK)).orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
} catch (NotAuthorizedException ex) {
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
}
use of org.eclipse.vorto.repository.web.core.exceptions.NotAuthorizedException in project vorto by eclipse.
the class ModelRepositoryController method getPolicies.
@PreAuthorize("isAuthenticated() or hasAuthority('model_viewer')")
@GetMapping("/{modelId:.+}/policies")
public ResponseEntity<Collection<PolicyEntry>> getPolicies(@PathVariable final String modelId) {
Objects.requireNonNull(modelId, "model ID must not be null");
try {
ModelId modelID = ModelId.fromPrettyFormat(modelId);
String workspaceId = getWorkspaceId(modelId);
Authentication user = SecurityContextHolder.getContext().getAuthentication();
return new ResponseEntity<>(getPolicyManager(workspaceId).getPolicyEntries(modelID).stream().filter(p -> userHasPolicyEntry(p, user, workspaceId)).collect(Collectors.toList()), HttpStatus.OK);
} catch (FatalModelRepositoryException ex) {
LOGGER.error(ex);
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
} catch (NotAuthorizedException ex) {
LOGGER.warn(ex);
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
}
Aggregations