use of org.keycloak.authorization.store.PermissionTicketStore in project keycloak by keycloak.
the class AccountFormService method grantPermission.
@Path("resource/{resource_id}/grant")
@POST
public Response grantPermission(@PathParam("resource_id") String resourceId, @FormParam("action") String action, @FormParam("permission_id") String[] permissionId, @FormParam("requester") String requester) {
MultivaluedMap<String, String> formData = request.getDecodedFormParameters();
if (auth == null) {
return login("resource");
}
auth.require(AccountRoles.MANAGE_ACCOUNT);
csrfCheck(formData);
AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class);
PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore();
Resource resource = authorization.getStoreFactory().getResourceStore().findById(resourceId, null);
if (resource == null) {
return ErrorResponse.error("Invalid resource", Response.Status.BAD_REQUEST);
}
if (action == null) {
return ErrorResponse.error("Invalid action", Response.Status.BAD_REQUEST);
}
boolean isGrant = "grant".equals(action);
boolean isDeny = "deny".equals(action);
boolean isRevoke = "revoke".equals(action);
boolean isRevokePolicy = "revokePolicy".equals(action);
boolean isRevokePolicyAll = "revokePolicyAll".equals(action);
if (isRevokePolicy || isRevokePolicyAll) {
List<String> ids = new ArrayList<>(Arrays.asList(permissionId));
Iterator<String> iterator = ids.iterator();
PolicyStore policyStore = authorization.getStoreFactory().getPolicyStore();
Policy policy = null;
while (iterator.hasNext()) {
String id = iterator.next();
if (!id.contains(":")) {
policy = policyStore.findById(id, client.getId());
iterator.remove();
break;
}
}
Set<Scope> scopesToKeep = new HashSet<>();
if (isRevokePolicyAll) {
for (Scope scope : policy.getScopes()) {
policy.removeScope(scope);
}
} else {
for (String id : ids) {
scopesToKeep.add(authorization.getStoreFactory().getScopeStore().findById(id.split(":")[1], client.getId()));
}
for (Scope scope : policy.getScopes()) {
if (!scopesToKeep.contains(scope)) {
policy.removeScope(scope);
}
}
}
if (policy.getScopes().isEmpty()) {
for (Policy associated : policy.getAssociatedPolicies()) {
policyStore.delete(associated.getId());
}
policyStore.delete(policy.getId());
}
} else {
Map<PermissionTicket.FilterOption, String> filters = new EnumMap<>(PermissionTicket.FilterOption.class);
filters.put(PermissionTicket.FilterOption.RESOURCE_ID, resource.getId());
filters.put(PermissionTicket.FilterOption.REQUESTER, session.users().getUserByUsername(realm, requester).getId());
if (isRevoke) {
filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.TRUE.toString());
} else {
filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.FALSE.toString());
}
List<PermissionTicket> tickets = ticketStore.find(filters, resource.getResourceServer(), -1, -1);
Iterator<PermissionTicket> iterator = tickets.iterator();
while (iterator.hasNext()) {
PermissionTicket ticket = iterator.next();
if (isGrant) {
if (permissionId != null && permissionId.length > 0 && !Arrays.asList(permissionId).contains(ticket.getId())) {
continue;
}
}
if (isGrant && !ticket.isGranted()) {
ticket.setGrantedTimestamp(System.currentTimeMillis());
iterator.remove();
} else if (isDeny || isRevoke) {
if (permissionId != null && permissionId.length > 0 && Arrays.asList(permissionId).contains(ticket.getId())) {
iterator.remove();
}
}
}
for (PermissionTicket ticket : tickets) {
ticketStore.delete(ticket.getId());
}
}
if (isRevoke || isRevokePolicy || isRevokePolicyAll) {
return forwardToPage("resource", AccountPages.RESOURCE_DETAIL);
}
return forwardToPage("resource", AccountPages.RESOURCES);
}
use of org.keycloak.authorization.store.PermissionTicketStore in project keycloak by keycloak.
the class ResourcesService method toPermissions.
private Collection<ResourcePermission> toPermissions(List<org.keycloak.authorization.model.Resource> resources, boolean withRequesters) {
Collection<ResourcePermission> permissions = new ArrayList<>();
PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore();
for (org.keycloak.authorization.model.Resource resource : resources) {
ResourcePermission permission = new ResourcePermission(resource, provider);
List<PermissionTicket> tickets;
if (withRequesters) {
Map<PermissionTicket.FilterOption, String> filters = new EnumMap<>(PermissionTicket.FilterOption.class);
filters.put(PermissionTicket.FilterOption.OWNER, user.getId());
filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.TRUE.toString());
filters.put(PermissionTicket.FilterOption.RESOURCE_ID, resource.getId());
tickets = ticketStore.find(filters, null, -1, -1);
} else {
tickets = ticketStore.findGranted(resource.getName(), user.getId(), null);
}
for (PermissionTicket ticket : tickets) {
if (resource.equals(ticket.getResource())) {
if (withRequesters) {
Permission user = permission.getPermission(ticket.getRequester());
if (user == null) {
permission.addPermission(ticket.getRequester(), user = new Permission(ticket.getRequester(), provider));
}
user.addScope(ticket.getScope().getName());
} else {
permission.addScope(new Scope(ticket.getScope()));
}
}
}
permissions.add(permission);
}
return permissions;
}
use of org.keycloak.authorization.store.PermissionTicketStore in project keycloak by keycloak.
the class JPAPermissionTicketStore method findByOwner.
@Override
public List<PermissionTicket> findByOwner(String owner, String resourceServerId) {
TypedQuery<String> query = entityManager.createNamedQuery("findPolicyIdByType", String.class);
query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("serverId", resourceServerId);
query.setParameter("owner", owner);
List<String> result = query.getResultList();
List<PermissionTicket> list = new LinkedList<>();
PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore();
for (String id : result) {
PermissionTicket ticket = ticketStore.findById(id, resourceServerId);
if (Objects.nonNull(ticket)) {
list.add(ticket);
}
}
return list;
}
use of org.keycloak.authorization.store.PermissionTicketStore in project keycloak by keycloak.
the class PermissionTicketService method create.
@POST
@Consumes("application/json")
@Produces("application/json")
public Response create(PermissionTicketRepresentation representation) {
PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore();
if (representation == null)
throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "invalid_permission", Response.Status.BAD_REQUEST);
if (representation.getId() != null)
throw new ErrorResponseException("invalid_permission", "created permissions should not have id", Response.Status.BAD_REQUEST);
if (representation.getResource() == null)
throw new ErrorResponseException("invalid_permission", "created permissions should have resource", Response.Status.BAD_REQUEST);
if (representation.getScope() == null && representation.getScopeName() == null)
throw new ErrorResponseException("invalid_permission", "created permissions should have scope or scopeName", Response.Status.BAD_REQUEST);
if (representation.getRequester() == null && representation.getRequesterName() == null)
throw new ErrorResponseException("invalid_permission", "created permissions should have requester or requesterName", Response.Status.BAD_REQUEST);
ResourceStore rstore = this.authorization.getStoreFactory().getResourceStore();
Resource resource = rstore.findById(representation.getResource(), resourceServer.getId());
if (resource == null)
throw new ErrorResponseException("invalid_resource_id", "Resource set with id [" + representation.getResource() + "] does not exists in this server.", Response.Status.BAD_REQUEST);
if (!resource.getOwner().equals(this.identity.getId()))
throw new ErrorResponseException("not_authorised", "permissions for [" + representation.getResource() + "] can be only created by the owner", Response.Status.FORBIDDEN);
UserModel user = null;
if (representation.getRequester() != null)
user = this.authorization.getKeycloakSession().userStorageManager().getUserById(this.authorization.getRealm(), representation.getRequester());
else
user = this.authorization.getKeycloakSession().userStorageManager().getUserByUsername(this.authorization.getRealm(), representation.getRequesterName());
if (user == null)
throw new ErrorResponseException("invalid_permission", "Requester does not exists in this server as user.", Response.Status.BAD_REQUEST);
Scope scope = null;
ScopeStore sstore = this.authorization.getStoreFactory().getScopeStore();
if (representation.getScopeName() != null)
scope = sstore.findByName(representation.getScopeName(), resourceServer.getId());
else
scope = sstore.findById(representation.getScope(), resourceServer.getId());
if (scope == null && representation.getScope() != null)
throw new ErrorResponseException("invalid_scope", "Scope [" + representation.getScope() + "] is invalid", Response.Status.BAD_REQUEST);
if (scope == null && representation.getScopeName() != null)
throw new ErrorResponseException("invalid_scope", "Scope [" + representation.getScopeName() + "] is invalid", Response.Status.BAD_REQUEST);
boolean match = resource.getScopes().contains(scope);
if (!match)
throw new ErrorResponseException("invalid_resource_id", "Resource set with id [" + representation.getResource() + "] does not have Scope [" + scope.getName() + "]", Response.Status.BAD_REQUEST);
Map<PermissionTicket.FilterOption, String> attributes = new EnumMap<>(PermissionTicket.FilterOption.class);
attributes.put(PermissionTicket.FilterOption.RESOURCE_ID, resource.getId());
attributes.put(PermissionTicket.FilterOption.SCOPE_ID, scope.getId());
attributes.put(PermissionTicket.FilterOption.REQUESTER, user.getId());
if (!ticketStore.find(attributes, resourceServer.getId(), -1, -1).isEmpty())
throw new ErrorResponseException("invalid_permission", "Permission already exists", Response.Status.BAD_REQUEST);
PermissionTicket ticket = ticketStore.create(resource.getId(), scope.getId(), user.getId(), resourceServer);
if (representation.isGranted())
ticket.setGrantedTimestamp(java.lang.System.currentTimeMillis());
representation = ModelToRepresentation.toRepresentation(ticket, authorization);
return Response.ok(representation).build();
}
use of org.keycloak.authorization.store.PermissionTicketStore in project keycloak by keycloak.
the class PermissionTicketService method find.
@GET
@Produces("application/json")
public Response find(@QueryParam("scopeId") String scopeId, @QueryParam("resourceId") String resourceId, @QueryParam("owner") String owner, @QueryParam("requester") String requester, @QueryParam("granted") Boolean granted, @QueryParam("returnNames") Boolean returnNames, @QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResult) {
StoreFactory storeFactory = authorization.getStoreFactory();
PermissionTicketStore permissionTicketStore = storeFactory.getPermissionTicketStore();
Map<PermissionTicket.FilterOption, String> filters = getFilters(storeFactory, resourceId, scopeId, owner, requester, granted);
return Response.ok().entity(permissionTicketStore.find(filters, resourceServer.getId(), firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS).stream().map(permissionTicket -> ModelToRepresentation.toRepresentation(permissionTicket, authorization, returnNames == null ? false : returnNames)).collect(Collectors.toList())).build();
}
Aggregations