Search in sources :

Example 16 with PermissionTicketStore

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);
}
Also used : OTPPolicy(org.keycloak.models.OTPPolicy) Policy(org.keycloak.authorization.model.Policy) PermissionTicket(org.keycloak.authorization.model.PermissionTicket) AuthorizationProvider(org.keycloak.authorization.AuthorizationProvider) RealmsResource(org.keycloak.services.resources.RealmsResource) Resource(org.keycloak.authorization.model.Resource) ArrayList(java.util.ArrayList) Scope(org.keycloak.authorization.model.Scope) PermissionTicketStore(org.keycloak.authorization.store.PermissionTicketStore) PolicyStore(org.keycloak.authorization.store.PolicyStore) EnumMap(java.util.EnumMap) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Example 17 with PermissionTicketStore

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;
}
Also used : PermissionTicket(org.keycloak.authorization.model.PermissionTicket) ArrayList(java.util.ArrayList) PermissionTicketStore(org.keycloak.authorization.store.PermissionTicketStore) EnumMap(java.util.EnumMap)

Example 18 with PermissionTicketStore

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;
}
Also used : PermissionTicket(org.keycloak.authorization.model.PermissionTicket) PermissionTicketStore(org.keycloak.authorization.store.PermissionTicketStore) LinkedList(java.util.LinkedList)

Example 19 with PermissionTicketStore

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();
}
Also used : PermissionTicket(org.keycloak.authorization.model.PermissionTicket) Resource(org.keycloak.authorization.model.Resource) ScopeStore(org.keycloak.authorization.store.ScopeStore) ResourceStore(org.keycloak.authorization.store.ResourceStore) UserModel(org.keycloak.models.UserModel) Scope(org.keycloak.authorization.model.Scope) PermissionTicketStore(org.keycloak.authorization.store.PermissionTicketStore) ErrorResponseException(org.keycloak.services.ErrorResponseException) EnumMap(java.util.EnumMap) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Example 20 with PermissionTicketStore

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();
}
Also used : Scope(org.keycloak.authorization.model.Scope) PathParam(javax.ws.rs.PathParam) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) StoreFactory(org.keycloak.authorization.store.StoreFactory) Constants(org.keycloak.models.Constants) Path(javax.ws.rs.Path) PermissionTicket(org.keycloak.authorization.model.PermissionTicket) RepresentationToModel(org.keycloak.models.utils.RepresentationToModel) OAuthErrorException(org.keycloak.OAuthErrorException) UserModel(org.keycloak.models.UserModel) QueryParam(javax.ws.rs.QueryParam) Consumes(javax.ws.rs.Consumes) ErrorResponseException(org.keycloak.services.ErrorResponseException) Map(java.util.Map) AuthorizationProvider(org.keycloak.authorization.AuthorizationProvider) DELETE(javax.ws.rs.DELETE) ResourceServer(org.keycloak.authorization.model.ResourceServer) RealmModel(org.keycloak.models.RealmModel) POST(javax.ws.rs.POST) EnumMap(java.util.EnumMap) ResourceStore(org.keycloak.authorization.store.ResourceStore) Collectors(java.util.stream.Collectors) KeycloakIdentity(org.keycloak.authorization.common.KeycloakIdentity) PermissionTicketRepresentation(org.keycloak.representations.idm.authorization.PermissionTicketRepresentation) UserProvider(org.keycloak.models.UserProvider) ScopeStore(org.keycloak.authorization.store.ScopeStore) ModelToRepresentation(org.keycloak.models.utils.ModelToRepresentation) Response(javax.ws.rs.core.Response) PermissionTicketStore(org.keycloak.authorization.store.PermissionTicketStore) PUT(javax.ws.rs.PUT) Resource(org.keycloak.authorization.model.Resource) PermissionTicketStore(org.keycloak.authorization.store.PermissionTicketStore) StoreFactory(org.keycloak.authorization.store.StoreFactory) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Aggregations

PermissionTicketStore (org.keycloak.authorization.store.PermissionTicketStore)21 PermissionTicket (org.keycloak.authorization.model.PermissionTicket)19 EnumMap (java.util.EnumMap)8 Resource (org.keycloak.authorization.model.Resource)7 Path (javax.ws.rs.Path)6 Scope (org.keycloak.authorization.model.Scope)6 LinkedList (java.util.LinkedList)5 POST (javax.ws.rs.POST)5 Consumes (javax.ws.rs.Consumes)4 AuthorizationProvider (org.keycloak.authorization.AuthorizationProvider)4 ResourceServer (org.keycloak.authorization.model.ResourceServer)4 PolicyStore (org.keycloak.authorization.store.PolicyStore)4 ResourceStore (org.keycloak.authorization.store.ResourceStore)4 ScopeStore (org.keycloak.authorization.store.ScopeStore)4 StoreFactory (org.keycloak.authorization.store.StoreFactory)4 UserModel (org.keycloak.models.UserModel)4 ErrorResponseException (org.keycloak.services.ErrorResponseException)4 ArrayList (java.util.ArrayList)3 Map (java.util.Map)3 Produces (javax.ws.rs.Produces)3