<commit_before>package oasis.web.authz;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.RedirectionException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import com.google.api.client.util.Maps;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.escape.Escaper;
import com.google.common.net.UrlEscapers;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import oasis.model.applications.ApplicationRepository;
import oasis.model.applications.Scope;
import oasis.model.applications.ScopeCardinality;
import oasis.model.applications.ServiceProvider;
import oasis.model.authn.AuthorizationCode;
import oasis.model.authz.AuthorizationRepository;
import oasis.model.authz.AuthorizedScopes;
import oasis.services.authn.TokenHandler;
import oasis.services.authn.TokenSerializer;
import oasis.web.authn.AccountPrincipal;
import oasis.web.authn.Authenticated;
import oasis.web.authn.User;
import oasis.web.view.View;

@Path("/a/auth")
@Authenticated
@User
@Produces(MediaType.TEXT_HTML)
@Api(value = "/a/auth", description = "Authorization Endpoint.")
public class AuthorizationEndpoint {
  private static final String APPROVE_PATH = "/approve";

  private static final Splitter SPACE_SPLITTER = Splitter.on(' ').omitEmptyStrings();

  @Context SecurityContext securityContext;

  @Inject AuthorizationRepository authorizationRepository;
  @Inject ApplicationRepository applicationRepository;
  @Inject TokenHandler tokenHandler;

  private MultivaluedMap<String, String> params;
  private StringBuilder redirectUriBuilder;

  @GET
  @ApiOperation(
      value = "Grant authorizations to the client application.",
      notes = "See the <a href=\"http://tools.ietf.org/html/rfc6749#section-3.1\">OAuth 2.0 RFC</a> and " +
          "<a href=\"http://openid.net/specs/openid-connect-basic-1_0.html#AuthorizationRequest\">OpenID Connect RFC</a> for more information."
  )
  public Response get(@Context UriInfo uriInfo) {
    return post(uriInfo.getQueryParameters());
  }

  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @ApiOperation(
      value = "Grant authorizations to the client application.",
      notes = "See the <a href=\"http://tools.ietf.org/html/rfc6749#section-3.1\">OAuth 2.0 RFC</a> and " +
          "<a href=\"http://openid.net/specs/openid-connect-basic-1_0.html#AuthorizationRequest\">OpenID Connect RFC</a> for more information."
  )
  public Response post(MultivaluedMap<String, String> params) {
    this.params = params;

    final String client_id = getRequiredParameter("client_id");
    ServiceProvider serviceProvider = getServiceProvider(client_id);

    final String redirect_uri = getRequiredParameter("redirect_uri");
    if (isRedirectUriValid(redirect_uri)) {
      throw invalidParam("redirect_uri");
    }
    // From now on, we can redirect to the client application, for both success and error conditions

    initRedirectUriBuilder(redirect_uri);

    // we should send the state back to the client if provided, so it's the first thing to get after validating the
    // client_id and redirect_uri (i.e. after verifying that it's OK to redirect to the client)
    // In case of error retrieving the state (i.e. multi-valued), we'll thus redirect to the client
    // without a state, which is OK (and the expected behavior)
    final String state = getParameter("state");
    appendQueryParam("state", state);

    final String response_type = getRequiredParameter("response_type");
    validateResponseType(response_type);

    final String scope = getRequiredParameter("scope");
    Set<String> scopeIds = Sets.newHashSet(SPACE_SPLITTER.split(scope));
    validateScopeIds(scopeIds);

    // TODO: OpenID Connect specifics
    String userId = ((AccountPrincipal) securityContext.getUserPrincipal()).getAccountId();

    final String nonce = getParameter("nonce");

    Set<String> authorizedScopeIds = getAuthorizedScopeIds(serviceProvider.getId(), userId);
    if (authorizedScopeIds.containsAll(scopeIds)) {
      // User already authorized all claimed scopes, let it be a "transparent" redirect
      return generateAuthorizationCodeAndRedirect(userId, scopeIds, serviceProvider.getId(), redirect_uri, nonce);
    }<commit_msg>Fix of redirect uri validation which has an inverted condition<commit_after>package oasis.web.authz;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.RedirectionException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import com.google.api.client.util.Maps;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.escape.Escaper;
import com.google.common.net.UrlEscapers;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import oasis.model.applications.ApplicationRepository;
import oasis.model.applications.Scope;
import oasis.model.applications.ScopeCardinality;
import oasis.model.applications.ServiceProvider;
import oasis.model.authn.AuthorizationCode;
import oasis.model.authz.AuthorizationRepository;
import oasis.model.authz.AuthorizedScopes;
import oasis.services.authn.TokenHandler;
import oasis.services.authn.TokenSerializer;
import oasis.web.authn.AccountPrincipal;
import oasis.web.authn.Authenticated;
import oasis.web.authn.User;
import oasis.web.view.View;

@Path("/a/auth")
@Authenticated
@User
@Produces(MediaType.TEXT_HTML)
@Api(value = "/a/auth", description = "Authorization Endpoint.")
public class AuthorizationEndpoint {
  private static final String APPROVE_PATH = "/approve";

  private static final Splitter SPACE_SPLITTER = Splitter.on(' ').omitEmptyStrings();

  @Context SecurityContext securityContext;

  @Inject AuthorizationRepository authorizationRepository;
  @Inject ApplicationRepository applicationRepository;
  @Inject TokenHandler tokenHandler;

  private MultivaluedMap<String, String> params;
  private StringBuilder redirectUriBuilder;

  @GET
  @ApiOperation(
      value = "Grant authorizations to the client application.",
      notes = "See the <a href=\"http://tools.ietf.org/html/rfc6749#section-3.1\">OAuth 2.0 RFC</a> and " +
          "<a href=\"http://openid.net/specs/openid-connect-basic-1_0.html#AuthorizationRequest\">OpenID Connect RFC</a> for more information."
  )
  public Response get(@Context UriInfo uriInfo) {
    return post(uriInfo.getQueryParameters());
  }

  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @ApiOperation(
      value = "Grant authorizations to the client application.",
      notes = "See the <a href=\"http://tools.ietf.org/html/rfc6749#section-3.1\">OAuth 2.0 RFC</a> and " +
          "<a href=\"http://openid.net/specs/openid-connect-basic-1_0.html#AuthorizationRequest\">OpenID Connect RFC</a> for more information."
  )
  public Response post(MultivaluedMap<String, String> params) {
    this.params = params;

    final String client_id = getRequiredParameter("client_id");
    ServiceProvider serviceProvider = getServiceProvider(client_id);

    final String redirect_uri = getRequiredParameter("redirect_uri");
    if (!isRedirectUriValid(redirect_uri)) {
      throw invalidParam("redirect_uri");
    }
    // From now on, we can redirect to the client application, for both success and error conditions

    initRedirectUriBuilder(redirect_uri);

    // we should send the state back to the client if provided, so it's the first thing to get after validating the
    // client_id and redirect_uri (i.e. after verifying that it's OK to redirect to the client)
    // In case of error retrieving the state (i.e. multi-valued), we'll thus redirect to the client
    // without a state, which is OK (and the expected behavior)
    final String state = getParameter("state");
    appendQueryParam("state", state);

    final String response_type = getRequiredParameter("response_type");
    validateResponseType(response_type);

    final String scope = getRequiredParameter("scope");
    Set<String> scopeIds = Sets.newHashSet(SPACE_SPLITTER.split(scope));
    validateScopeIds(scopeIds);

    // TODO: OpenID Connect specifics
    String userId = ((AccountPrincipal) securityContext.getUserPrincipal()).getAccountId();

    final String nonce = getParameter("nonce");

    Set<String> authorizedScopeIds = getAuthorizedScopeIds(serviceProvider.getId(), userId);
    if (authorizedScopeIds.containsAll(scopeIds)) {
      // User already authorized all claimed scopes, let it be a "transparent" redirect
      return generateAuthorizationCodeAndRedirect(userId, scopeIds, serviceProvider.getId(), redirect_uri, nonce);
    }
{'fraction_non_alphanumeric': 0.10885214007782101, 'fraction_numerical': 0.0038910505836575876, 'mean_word_length': 4.91542002301496, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4333808', 'n_tokens_mistral': 3075, 'n_tokens_neox': 3028, 'n_words': 717}