Search in sources :

Example 66 with Approval

use of org.cloudfoundry.identity.uaa.approval.Approval in project uaa by cloudfoundry.

the class AccessController method confirm.

@RequestMapping("/oauth/confirm_access")
public String confirm(Map<String, Object> model, final HttpServletRequest request, Principal principal, SessionStatus sessionStatus) {
    if (!(principal instanceof Authentication)) {
        sessionStatus.setComplete();
        throw new InsufficientAuthenticationException("User must be authenticated with before authorizing access.");
    }
    AuthorizationRequest clientAuthRequest = (AuthorizationRequest) model.remove(UaaAuthorizationEndpoint.AUTHORIZATION_REQUEST);
    if (clientAuthRequest == null) {
        model.put("error", "No authorization request is present, so we cannot confirm access (we don't know what you are asking for).");
    } else {
        String clientId = clientAuthRequest.getClientId();
        BaseClientDetails client = (BaseClientDetails) clientDetailsService.loadClientByClientId(clientId, IdentityZoneHolder.get().getId());
        BaseClientDetails modifiableClient = new BaseClientDetails(client);
        modifiableClient.setClientSecret(null);
        model.put("auth_request", clientAuthRequest);
        model.put("redirect_uri", getRedirectUri(modifiableClient, clientAuthRequest));
        Map<String, Object> additionalInfo = client.getAdditionalInformation();
        String clientDisplayName = (String) additionalInfo.get(ClientConstants.CLIENT_NAME);
        model.put("client_display_name", (clientDisplayName != null) ? clientDisplayName : clientId);
        // Find the auto approved scopes for this clients
        Set<String> autoApproved = client.getAutoApproveScopes();
        Set<String> autoApprovedScopes = new HashSet<>();
        if (autoApproved != null) {
            if (autoApproved.contains("true")) {
                autoApprovedScopes.addAll(client.getScope());
            } else {
                autoApprovedScopes.addAll(autoApproved);
            }
        }
        List<Approval> filteredApprovals = new ArrayList<Approval>();
        // Remove auto approved scopes
        List<Approval> approvals = approvalStore.getApprovals(Origin.getUserId((Authentication) principal), clientId, IdentityZoneHolder.get().getId());
        for (Approval approval : approvals) {
            if (!(autoApprovedScopes.contains(approval.getScope()))) {
                filteredApprovals.add(approval);
            }
        }
        ArrayList<String> approvedScopes = new ArrayList<String>();
        ArrayList<String> deniedScopes = new ArrayList<String>();
        for (Approval approval : filteredApprovals) {
            switch(approval.getStatus()) {
                case APPROVED:
                    approvedScopes.add(approval.getScope());
                    break;
                case DENIED:
                    deniedScopes.add(approval.getScope());
                    break;
                default:
                    logger.error("Encountered an unknown scope. This is not supposed to happen");
                    break;
            }
        }
        ArrayList<String> undecidedScopes = new ArrayList<String>();
        // Filter the scopes approved/denied from the ones requested
        for (String scope : clientAuthRequest.getScope()) {
            if (!approvedScopes.contains(scope) && !deniedScopes.contains(scope) && !autoApprovedScopes.contains(scope)) {
                undecidedScopes.add(scope);
            }
        }
        List<Map<String, String>> approvedScopeDetails = getScopes(approvedScopes);
        model.put("approved_scopes", approvedScopeDetails);
        List<Map<String, String>> undecidedScopeDetails = getScopes(undecidedScopes);
        model.put("undecided_scopes", undecidedScopeDetails);
        List<Map<String, String>> deniedScopeDetails = getScopes(deniedScopes);
        model.put("denied_scopes", deniedScopeDetails);
        List<Map<String, String>> allScopes = new ArrayList<>();
        allScopes.addAll(approvedScopeDetails);
        allScopes.addAll(undecidedScopeDetails);
        allScopes.addAll(deniedScopeDetails);
        model.put("scopes", allScopes);
        model.put("message", "To confirm or deny access POST to the following locations with the parameters requested.");
        Map<String, Object> options = new HashMap<String, Object>() {

            {
                put("confirm", new HashMap<String, String>() {

                    {
                        put("location", getLocation(request, "oauth/authorize"));
                        put("path", getPath(request, "oauth/authorize"));
                        put("key", OAuth2Utils.USER_OAUTH_APPROVAL);
                        put("value", "true");
                    }
                });
                put("deny", new HashMap<String, String>() {

                    {
                        put("location", getLocation(request, "oauth/authorize"));
                        put("path", getPath(request, "oauth/authorize"));
                        put("key", OAuth2Utils.USER_OAUTH_APPROVAL);
                        put("value", "false");
                    }
                });
            }
        };
        model.put("options", options);
    }
    return "access_confirmation";
}
Also used : BaseClientDetails(org.springframework.security.oauth2.provider.client.BaseClientDetails) AuthorizationRequest(org.springframework.security.oauth2.provider.AuthorizationRequest) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) InsufficientAuthenticationException(org.springframework.security.authentication.InsufficientAuthenticationException) Authentication(org.springframework.security.core.Authentication) Approval(org.cloudfoundry.identity.uaa.approval.Approval) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 67 with Approval

use of org.cloudfoundry.identity.uaa.approval.Approval in project uaa by cloudfoundry.

the class UserManagedAuthzApprovalHandler method isApproved.

@Override
public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) {
    String approvalParameter1 = OAuth2Utils.USER_OAUTH_APPROVAL;
    String flag = authorizationRequest.getApprovalParameters().get(approvalParameter1);
    boolean userApproval = flag != null && flag.toLowerCase().equals("true");
    if (logger.isDebugEnabled()) {
        StringBuilder builder = new StringBuilder("Looking up user approved authorizations for ");
        builder.append("client_id=").append(authorizationRequest.getClientId());
        builder.append(" and username=").append(userAuthentication.getName());
        logger.debug(builder.toString());
    }
    Collection<String> requestedScopes = authorizationRequest.getScope();
    // Factor in auto approved scopes
    Set<String> autoApprovedScopes = new HashSet<>();
    BaseClientDetails client = (BaseClientDetails) clientDetailsService.retrieve(authorizationRequest.getClientId(), identityZoneManager.getCurrentIdentityZoneId());
    if (client != null && requestedScopes != null) {
        autoApprovedScopes.addAll(client.getAutoApproveScopes());
        autoApprovedScopes = UaaTokenUtils.retainAutoApprovedScopes(requestedScopes, autoApprovedScopes);
    }
    // TODO: the "true" case is not tested
    if (userApproval) {
        // Store the scopes that have been approved / denied
        Date expiry = computeExpiry();
        // Get the approved scopes, calculate the denied scope
        Map<String, String> approvalParameters = authorizationRequest.getApprovalParameters();
        Set<String> approvedScopes = new HashSet<>(autoApprovedScopes);
        boolean foundUserApprovalParameter = false;
        for (String approvalParameter : approvalParameters.keySet()) {
            if (approvalParameter.startsWith(SCOPE_PREFIX)) {
                approvedScopes.add(approvalParameters.get(approvalParameter).substring(SCOPE_PREFIX.length()));
                foundUserApprovalParameter = true;
            }
        }
        if (foundUserApprovalParameter) {
            authorizationRequest.setScope(approvedScopes);
            for (String requestedScope : requestedScopes) {
                if (approvedScopes.contains(requestedScope)) {
                    Approval approval = new Approval().setUserId(getUserId(userAuthentication)).setClientId(authorizationRequest.getClientId()).setScope(requestedScope).setExpiresAt(expiry).setStatus(APPROVED);
                    approvalStore.addApproval(approval, identityZoneManager.getCurrentIdentityZoneId());
                } else {
                    Approval approval = new Approval().setUserId(getUserId(userAuthentication)).setClientId(authorizationRequest.getClientId()).setScope(requestedScope).setExpiresAt(expiry).setStatus(DENIED);
                    approvalStore.addApproval(approval, identityZoneManager.getCurrentIdentityZoneId());
                }
            }
        } else {
            // Deny all except auto approved scopes
            authorizationRequest.setScope(autoApprovedScopes);
            for (String requestedScope : requestedScopes) {
                if (!autoApprovedScopes.contains(requestedScope)) {
                    Approval approval = new Approval().setUserId(getUserId(userAuthentication)).setClientId(authorizationRequest.getClientId()).setScope(requestedScope).setExpiresAt(expiry).setStatus(DENIED);
                    approvalStore.addApproval(approval, identityZoneManager.getCurrentIdentityZoneId());
                }
            }
        }
        return userAuthentication.isAuthenticated();
    } else {
        // Find the stored approvals for that user and client
        List<Approval> userApprovals = approvalStore.getApprovals(getUserId(userAuthentication), authorizationRequest.getClientId(), identityZoneManager.getCurrentIdentityZoneId());
        // Look at the scopes and see if they have expired
        Set<String> approvedScopes = new HashSet<>(autoApprovedScopes);
        Set<String> validUserApprovedScopes = new HashSet<>(autoApprovedScopes);
        Date today = new Date();
        for (Approval approval : userApprovals) {
            if (approval.getExpiresAt().after(today)) {
                validUserApprovedScopes.add(approval.getScope());
                if (approval.getStatus() == APPROVED) {
                    approvedScopes.add(approval.getScope());
                }
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Valid user approved/denied scopes are " + validUserApprovedScopes);
        }
        // this request is approved
        if (validUserApprovedScopes.containsAll(requestedScopes) && userAuthentication.isAuthenticated()) {
            approvedScopes = UaaTokenUtils.retainAutoApprovedScopes(requestedScopes, approvedScopes);
            // Set only the scopes that have been approved by the user
            authorizationRequest.setScope(approvedScopes);
            return true;
        }
    }
    return false;
}
Also used : BaseClientDetails(org.springframework.security.oauth2.provider.client.BaseClientDetails) Approval(org.cloudfoundry.identity.uaa.approval.Approval)

Example 68 with Approval

use of org.cloudfoundry.identity.uaa.approval.Approval in project uaa by cloudfoundry.

the class ProfileController method getCurrentApprovalsForUser.

private Map<String, List<DescribedApproval>> getCurrentApprovalsForUser(String userId) {
    Map<String, List<DescribedApproval>> result = new HashMap<>();
    List<Approval> approvalsResponse = approvalsService.getApprovalsForUser(userId, identityZoneManager.getCurrentIdentityZoneId());
    List<DescribedApproval> approvals = new ArrayList<>();
    for (Approval approval : approvalsResponse) {
        DescribedApproval describedApproval = new DescribedApproval(approval);
        approvals.add(describedApproval);
    }
    for (DescribedApproval approval : approvals) {
        List<DescribedApproval> clientApprovals = result.computeIfAbsent(approval.getClientId(), k -> new ArrayList<>());
        String scope = approval.getScope();
        if (!scope.contains(".")) {
            approval.setDescription("Access your data with scope '" + scope + "'");
            clientApprovals.add(approval);
        } else {
            String resource = scope.substring(0, scope.lastIndexOf("."));
            String access = scope.substring(scope.lastIndexOf(".") + 1);
            approval.setDescription("Access your '" + resource + "' resources with scope '" + access + "'");
            clientApprovals.add(approval);
        }
    }
    for (List<DescribedApproval> approvalList : result.values()) {
        approvalList.sort(Comparator.comparing(Approval::getScope));
    }
    return result;
}
Also used : DescribedApproval(org.cloudfoundry.identity.uaa.approval.DescribedApproval) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) DescribedApproval(org.cloudfoundry.identity.uaa.approval.DescribedApproval) Approval(org.cloudfoundry.identity.uaa.approval.Approval)

Example 69 with Approval

use of org.cloudfoundry.identity.uaa.approval.Approval in project uaa by cloudfoundry.

the class ProfileController method post.

/**
 * Handle form post for revoking chosen approvals
 */
@RequestMapping(value = "/profile", method = RequestMethod.POST)
public String post(@RequestParam(required = false) Collection<String> checkedScopes, @RequestParam(required = false) String update, @RequestParam(required = false) String delete, @RequestParam(required = false) String clientId) {
    String userId = getCurrentUserId();
    if (null != update) {
        Map<String, List<DescribedApproval>> approvalsByClientId = getCurrentApprovalsForUser(userId);
        List<DescribedApproval> allApprovals = new ArrayList<>();
        for (List<DescribedApproval> clientApprovals : approvalsByClientId.values()) {
            allApprovals.addAll(clientApprovals);
        }
        if (hasText(clientId)) {
            allApprovals.removeIf(da -> !clientId.equals(da.getClientId()));
        }
        for (Approval approval : allApprovals) {
            String namespacedScope = approval.getClientId() + "-" + approval.getScope();
            if (checkedScopes != null && checkedScopes.contains(namespacedScope)) {
                approval.setStatus(Approval.ApprovalStatus.APPROVED);
            } else {
                approval.setStatus(Approval.ApprovalStatus.DENIED);
            }
        }
        updateApprovals(allApprovals);
    } else if (null != delete) {
        deleteApprovalsForClient(userId, clientId);
    }
    return "redirect:profile";
}
Also used : DescribedApproval(org.cloudfoundry.identity.uaa.approval.DescribedApproval) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) DescribedApproval(org.cloudfoundry.identity.uaa.approval.DescribedApproval) Approval(org.cloudfoundry.identity.uaa.approval.Approval) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 70 with Approval

use of org.cloudfoundry.identity.uaa.approval.Approval in project uaa by cloudfoundry.

the class ApprovalModifiedEventTest method testAuditEvent.

@Test
public void testAuditEvent() {
    Approval approval = new Approval().setUserId("mruser").setClientId("app").setScope("cloud_controller.read").setExpiresAt(Approval.timeFromNow(1000)).setStatus(Approval.ApprovalStatus.APPROVED);
    ApprovalModifiedEvent event = new ApprovalModifiedEvent(approval, null);
    AuditEvent auditEvent = event.getAuditEvent();
    Assert.assertEquals("{\"scope\":\"cloud_controller.read\",\"status\":\"APPROVED\"}", auditEvent.getData());
    Assert.assertEquals(AuditEventType.ApprovalModifiedEvent, auditEvent.getType());
}
Also used : AuditEvent(org.cloudfoundry.identity.uaa.audit.AuditEvent) Approval(org.cloudfoundry.identity.uaa.approval.Approval) Test(org.junit.Test)

Aggregations

Approval (org.cloudfoundry.identity.uaa.approval.Approval)80 Test (org.junit.jupiter.api.Test)34 AuthorizationRequest (org.springframework.security.oauth2.provider.AuthorizationRequest)29 Date (java.util.Date)26 OAuth2AccessToken (org.springframework.security.oauth2.common.OAuth2AccessToken)21 DefaultOAuth2AccessToken (org.springframework.security.oauth2.common.DefaultOAuth2AccessToken)19 BaseClientDetails (org.springframework.security.oauth2.provider.client.BaseClientDetails)18 Authentication (org.springframework.security.core.Authentication)17 OAuth2Authentication (org.springframework.security.oauth2.provider.OAuth2Authentication)17 IsEmptyString.isEmptyString (org.hamcrest.text.IsEmptyString.isEmptyString)16 Test (org.junit.Test)16 ApprovalStore (org.cloudfoundry.identity.uaa.approval.ApprovalStore)7 MockHttpServletRequestBuilder (org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder)6 ClientDetailsModification (org.cloudfoundry.identity.uaa.oauth.client.ClientDetailsModification)5 ScimUser (org.cloudfoundry.identity.uaa.scim.ScimUser)5 ClientDetails (org.springframework.security.oauth2.provider.ClientDetails)5 ArrayList (java.util.ArrayList)4 ClientDetailsHelper.arrayFromString (org.cloudfoundry.identity.uaa.mock.util.ClientDetailsHelper.arrayFromString)4 ClientDetailsHelper.clientArrayFromString (org.cloudfoundry.identity.uaa.mock.util.ClientDetailsHelper.clientArrayFromString)4 ClientDetailsHelper.clientFromString (org.cloudfoundry.identity.uaa.mock.util.ClientDetailsHelper.clientFromString)4