Search in sources :

Example 1 with StyxException

use of net.petafuel.styx.api.exception.StyxException in project styx by petafuel.

the class AccessTokenFilter method checkToken.

@Override
public boolean checkToken(String tokenHash) {
    AccessToken accessToken;
    try {
        accessToken = PersistentAccessToken.get(tokenHash);
    } catch (PersistenceEmptyResultSetException persistenceEmptyResultSetException) {
        // if there was no matching token found in the database, always return unauthorized
        ResponseEntity responseEntity = new ResponseEntity(ResponseConstant.UNAUTHORIZED, ResponseCategory.ERROR, ResponseOrigin.CLIENT);
        throw new StyxException(responseEntity);
    }
    if (accessToken.getLastUsedOn() == null && (TimeUnit.MILLISECONDS.toSeconds(new Date().getTime() - accessToken.getCreatedAt().getTime())) > accessToken.getExpiresIn()) {
        MasterToken masterToken = PersistentClientApp.get(accessToken.getClientMasterToken());
        LOG.warn("Access token expired before first usage, invalidated. master={}, access_token_created={}, serviceBinding={}", masterToken.getName(), accessToken.getCreatedAt(), accessToken.getServiceType());
        PersistentAccessToken.setValid(tokenHash, false);
        return false;
    }
    // get master token and check restrictions
    MasterToken masterToken = PersistentClientApp.get(accessToken.getClientMasterToken());
    checkRestrictions(masterToken, accessToken.getServiceType());
    // check if maxUsages is reached
    checkMaxUsages(masterToken, accessToken);
    // log necessary token information
    LOG.info("Request sent with following token information: accessToken={} valid={} serviceType={} usages={} clientReference={} createdAt={} masterTokenName={} masterTokenEnabled={}", accessToken.getId(), accessToken.isValid(), accessToken.getServiceType(), accessToken.getUsages(), accessToken.getClientReference(), accessToken.getCreatedAt(), masterToken.getName(), masterToken.isEnabled());
    // get service requirements from Target-Resource class or method
    List<XS2ATokenType> serviceRequirements = null;
    if (ri.getResourceMethod().getAnnotation(CheckAccessToken.class) != null) {
        serviceRequirements = Arrays.asList(ri.getResourceMethod().getAnnotation(CheckAccessToken.class).allowedServices());
    } else if (ri.getResourceClass().getAnnotation(CheckAccessToken.class) != null) {
        serviceRequirements = Arrays.asList(ri.getResourceClass().getAnnotation(CheckAccessToken.class).allowedServices());
    }
    // Get all TokenTypeMapperSPI implementations
    List<TokenTypeMapperSPI> tokenTypeMapperImpls = new TokenTypeMapperService().providers();
    TokenTypeMapperSPI concreteTokenTypeMapper = tokenTypeMapperImpls.stream().filter(tokenTypeMapperSPI -> tokenTypeMapperSPI.getMapping(accessToken.getServiceType()) != null).findFirst().orElse(null);
    if (concreteTokenTypeMapper == null || (serviceRequirements != null && !serviceRequirements.contains(concreteTokenTypeMapper.getMapping(accessToken.getServiceType())))) {
        if (concreteTokenTypeMapper == null) {
            LOG.error("There was not TokenTypeMapperSPI implementation found within the classpath, tokens cannot be validated against access controll");
        }
        ResponseEntity responseEntity = new ResponseEntity(ResponseConstant.STYX_TOKEN_ACCESS_VIOLATION, ResponseCategory.ERROR, ResponseOrigin.CLIENT);
        throw new StyxException(responseEntity);
    }
    // update lastUsedOn and increase usages of accessToken
    if (ri.getResourceClass().isAnnotationPresent(CheckAccessToken.class) && ri.getResourceClass().getAnnotation(CheckAccessToken.class).incrementUsage()) {
        PersistentAccessToken.updateLastUsedOn(tokenHash);
    }
    return accessToken.isValid() && masterToken.isEnabled();
}
Also used : ResponseEntity(net.petafuel.styx.api.exception.ResponseEntity) MasterToken(net.petafuel.styx.core.persistence.models.MasterToken) CheckAccessToken(net.petafuel.styx.api.filter.authentication.boundary.CheckAccessToken) TokenTypeMapperSPI(net.petafuel.styx.spi.tokentypemapper.spi.TokenTypeMapperSPI) AccessToken(net.petafuel.styx.core.persistence.models.AccessToken) CheckAccessToken(net.petafuel.styx.api.filter.authentication.boundary.CheckAccessToken) PersistentAccessToken(net.petafuel.styx.core.persistence.layers.PersistentAccessToken) PersistenceEmptyResultSetException(net.petafuel.styx.core.persistence.PersistenceEmptyResultSetException) TokenTypeMapperService(net.petafuel.styx.spi.tokentypemapper.TokenTypeMapperService) XS2ATokenType(net.petafuel.styx.spi.tokentypemapper.api.XS2ATokenType) StyxException(net.petafuel.styx.api.exception.StyxException) Date(java.util.Date)

Example 2 with StyxException

use of net.petafuel.styx.api.exception.StyxException in project styx by petafuel.

the class AccessTokenFilter method checkMaxUsages.

/**
 * Check if maximum amount of usages reached => exception if reached, increase usage of token if not reached yet
 *
 * @param masterToken model of MasterToken
 * @param accessToken model of AccessToken
 */
public void checkMaxUsages(MasterToken masterToken, AccessToken accessToken) {
    if (masterToken.getRestrictions().get(accessToken.getServiceType()) == null) {
        LOG.error("Accesstoken has serviceType that does not match mastertoken. Mastertoken restrictions were changed after this accesstoken was created. masterTokenName='{}', accessTokenHash='{}', accessTokenServiceType='{}', accessTokenCreatedAt='{}', accessTokenClientReference='{}'", masterToken.getName(), accessToken.getId(), accessToken.getServiceType(), accessToken.getCreatedAt(), accessToken.getClientReference());
        abortMasterTokenRestricted();
    }
    int maxUsages = masterToken.getRestrictions().get(accessToken.getServiceType()).getMaxUsages();
    if (maxUsages > 0 && maxUsages <= accessToken.getUsages()) {
        ResponseEntity responseEntity = new ResponseEntity(ResponseConstant.STYX_TOKEN_ACCESS_EXEEDED, ResponseCategory.ERROR, ResponseOrigin.CLIENT);
        throw new StyxException(responseEntity);
    }
}
Also used : ResponseEntity(net.petafuel.styx.api.exception.ResponseEntity) StyxException(net.petafuel.styx.api.exception.StyxException)

Example 3 with StyxException

use of net.petafuel.styx.api.exception.StyxException in project styx by petafuel.

the class PreAuthAccessFilter method filter.

/**
 * Supressing java:S3776 -> need to rework logic to reduce code complexity
 *
 * @param containerRequestContext
 */
@Override
@SuppressWarnings("java:S3776")
public void filter(ContainerRequestContext containerRequestContext) {
    XS2AStandard xs2AStandard = (XS2AStandard) containerRequestContext.getProperty(XS2AStandard.class.getName());
    IOParser ioParser = new IOParser(xs2AStandard.getAspsp());
    ImplementerOption ioPreAuthRequired = ioParser.get("IO6");
    if (ioPreAuthRequired != null && ioPreAuthRequired.getOptions().get(IOParser.Option.REQUIRED)) {
        LOG.info("ASPSP bic={} requires pre-auth", xs2AStandard.getAspsp().getBic());
        // preauth is available and required for this bank -> check if preauth id is present
        String preAuthIdString = containerRequestContext.getHeaderString(PRE_AUTH_ID);
        if (preAuthIdString == null || "".equals(preAuthIdString)) {
            throw new StyxException(new ResponseEntity("The requested aspsps requires a pre-step authorisation, preAuthId Header is missing", ResponseConstant.STYX_PREAUTH_HEADER_REQUIRED, ResponseCategory.ERROR, ResponseOrigin.CLIENT));
        }
        try {
            UUID preAuthId = UUID.fromString(preAuthIdString);
            OAuthSession oAuthSession = PersistentOAuthSession.getById(preAuthId);
            LOG.info("Loaded state={} oauth_session", oAuthSession.getState());
            STYX03.setPreauthId(preAuthId);
            if (oAuthSession.getAccessToken() == null || oAuthSession.getAccessTokenExpiresAt() == null) {
                throw new PersistenceEmptyResultSetException("The access_token data should be set");
            }
            if (oAuthSession.getAccessTokenExpiresAt().before(new Date())) {
                if (oAuthSession.getRefreshTokenExpiresAt().after(new Date())) {
                    oAuthSession = refreshToken(oAuthSession);
                } else {
                    throw new OAuthTokenExpiredException(OAuthTokenExpiredException.MESSAGE);
                }
            }
            // Add the Authorization: <type> <credentials> header to the request context so we can use it later on demand
            Map<String, String> additionalHeaders = new HashMap<>();
            additionalHeaders.put(XS2AHeader.AUTHORIZATION, oAuthSession.getTokenType() + " " + oAuthSession.getAccessToken());
            containerRequestContext.setProperty(PreAuthAccessFilter.class.getName(), additionalHeaders);
            LOG.info("Successfully attached pre-auth from oAuthSessionState={}", oAuthSession.getState());
        } catch (PersistenceEmptyResultSetException noOauthSessionFound) {
            throw new StyxException(new ResponseEntity("There was no valid pre-step authorisation found for the specified preAuthId", ResponseConstant.STYX_PREAUTH_NOT_AVAILABLE, ResponseCategory.ERROR, ResponseOrigin.CLIENT));
        } catch (OAuthTokenExpiredException tokenExpired) {
            throw new StyxException(new ResponseEntity(tokenExpired.getMessage(), ResponseConstant.STYX_PREAUTH_EXPIRED, ResponseCategory.ERROR, ResponseOrigin.CLIENT));
        }
    }
}
Also used : XS2AStandard(net.petafuel.styx.core.banklookup.XS2AStandard) OAuthTokenExpiredException(net.petafuel.styx.core.xs2a.exceptions.OAuthTokenExpiredException) HashMap(java.util.HashMap) PersistentOAuthSession(net.petafuel.styx.core.persistence.layers.PersistentOAuthSession) OAuthSession(net.petafuel.styx.core.xs2a.oauth.entities.OAuthSession) PersistenceEmptyResultSetException(net.petafuel.styx.core.persistence.PersistenceEmptyResultSetException) ImplementerOption(net.petafuel.styx.core.banklookup.sad.entities.ImplementerOption) StyxException(net.petafuel.styx.api.exception.StyxException) Date(java.util.Date) ResponseEntity(net.petafuel.styx.api.exception.ResponseEntity) IOParser(net.petafuel.styx.core.ioprocessing.IOParser) UUID(java.util.UUID)

Example 4 with StyxException

use of net.petafuel.styx.api.exception.StyxException in project styx by petafuel.

the class PSUFilter method filter.

@Override
public void filter(ContainerRequestContext containerRequestContext) {
    String id = containerRequestContext.getHeaderString(XS2AHeader.PSU_ID);
    if (id == null || "".equals(id)) {
        throw new StyxException(new ResponseEntity("PSU-ID is not provided or empty", ResponseConstant.BAD_REQUEST, ResponseCategory.ERROR, ResponseOrigin.CLIENT));
    }
    PSU psu = new PSU(id);
    psu.setIdType(containerRequestContext.getHeaderString(XS2AHeader.PSU_ID_TYPE));
    psu.setCorporateId(containerRequestContext.getHeaderString(XS2AHeader.PSU_CORPORATE_ID));
    psu.setCorporateIdType(containerRequestContext.getHeaderString(XS2AHeader.PSU_CORPORATE_ID_TYPE));
    if (Boolean.getBoolean(ApiProperties.STYX_PROXY_ENABLED)) {
        String forwardedIps = containerRequestContext.getHeaderString(XS2AHeader.X_FORWARDED_FOR);
        psu.setIp(Sanitizer.parseClientIpFromForwardedIPs(forwardedIps));
    } else {
        psu.setIp(httpServletRequest.getRemoteAddr());
    }
    String psuPort = containerRequestContext.getHeaderString(XS2AHeader.PSU_IP_PORT);
    try {
        Integer intVal = psuPort != null ? Integer.valueOf(psuPort) : null;
        psu.setPort(intVal);
    } catch (NumberFormatException invalidDataType) {
        LOG.warn("PSU-PORT header was bigger than integer MAX_VALUE, not accepting header value");
    }
    psu.setUserAgent(containerRequestContext.getHeaderString(XS2AHeader.PSU_USER_AGENT));
    psu.setGeoLocation(containerRequestContext.getHeaderString(XS2AHeader.PSU_GEO_LOCATION));
    containerRequestContext.setProperty(PSU.class.getName(), psu);
}
Also used : ResponseEntity(net.petafuel.styx.api.exception.ResponseEntity) RequiresPSU(net.petafuel.styx.api.filter.input.boundary.RequiresPSU) PSU(net.petafuel.styx.core.xs2a.entities.PSU) StyxException(net.petafuel.styx.api.exception.StyxException)

Example 5 with StyxException

use of net.petafuel.styx.api.exception.StyxException in project styx by petafuel.

the class PaymentInitiationResource method initiateSinglePayment.

/**
 * Initiate single or future dated payments
 *
 * @param paymentTypeBean   contains which payment product is used
 * @param singlePaymentBody contains the request body as parsed json
 * @return 201 if successful
 * @throws BankRequestFailedException in case the communication between styx and aspsp was not successful
 */
@POST
@Path("/payments/{paymentProduct}")
@RequiresMandatoryHeader
@AcceptsPreStepAuth
public Response initiateSinglePayment(@BeanParam PaymentTypeBean paymentTypeBean, @Valid SinglePaymentInitiation singlePaymentBody) throws BankRequestFailedException {
    Optional<SinglePayment> singlePayment = singlePaymentBody.getPayments().stream().findFirst();
    if (!singlePayment.isPresent()) {
        throw new StyxException(new ResponseEntity("No valid single payment object was found within the payments array", ResponseConstant.BAD_REQUEST, ResponseCategory.ERROR, ResponseOrigin.CLIENT));
    }
    SinglePayment payment = singlePayment.get();
    XS2AFactoryInput xs2AFactoryInput = new XS2AFactoryInput();
    xs2AFactoryInput.setPayment(payment);
    xs2AFactoryInput.setPsu(getPsu());
    xs2AFactoryInput.setPaymentService(PaymentService.PAYMENTS);
    xs2AFactoryInput.setPaymentProduct(paymentTypeBean.getPaymentProduct());
    IOProcessor ioProcessor = new IOProcessor(getXS2AStandard());
    ioProcessor.modifyInput(xs2AFactoryInput);
    PISRequest paymentInitiationRequest = new PISRequestFactory().create(getXS2AStandard().getRequestClassProvider().paymentInitiation(), xs2AFactoryInput);
    paymentInitiationRequest.getHeaders().putAll(getAdditionalHeaders());
    paymentInitiationRequest.setTppRedirectPreferred(getRedirectPreferred());
    paymentInitiationRequest.setXrequestId(ThreadContext.get(RequestUUIDAdapter.REQUEST_UUID));
    ioProcessor.modifyRequest(paymentInitiationRequest, xs2AFactoryInput);
    InitiatedPayment initiatedPayment = getXS2AStandard().getPis().initiatePayment(paymentInitiationRequest);
    PersistentPayment.create(paymentInitiationRequest.getXrequestId(), initiatedPayment.getPaymentId(), (String) getContainerRequestContext().getProperty(AbstractTokenFilter.class.getName()), getXS2AStandard().getAspsp().getBic(), initiatedPayment.getStatus(), PaymentService.PAYMENTS, paymentTypeBean.getPaymentProduct());
    if (containerRequestContext.getProperty(PreAuthAccessFilter.class.getName()) != null) {
        initiatedPayment.setxRequestId(UUID.fromString(containerRequestContext.getHeaderString(PreAuthAccessFilter.PRE_AUTH_ID)));
    }
    xs2AFactoryInput.setPaymentId(initiatedPayment.getPaymentId());
    ioProcessor.modifyResponse(initiatedPayment, xs2AFactoryInput);
    PaymentResponse paymentResponse = new PaymentResponse(initiatedPayment);
    SCAApproach approach = SCAHandler.decision(initiatedPayment);
    if (approach instanceof OAuth2) {
        paymentResponse.getLinks().getScaOAuth().setUrl(((OAuth2) approach).getAuthoriseLink());
    }
    LOG.info("Initiate single payment bic={} aspsp_name={} aspsp_id={} paymentId={} xrequestid={}", getXS2AStandard().getAspsp().getBic(), getXS2AStandard().getAspsp().getName(), getXS2AStandard().getAspsp().getId(), paymentResponse.getPaymentId(), paymentInitiationRequest.getXrequestId());
    AspspUrlMapper aspspUrlMapper = new AspspUrlMapper(PaymentService.PAYMENTS, paymentTypeBean.getPaymentProduct(), paymentResponse.getPaymentId(), null);
    paymentResponse.setLinks(aspspUrlMapper.map(paymentResponse.getLinks()));
    return Response.status(ResponseConstant.CREATED).entity(paymentResponse).build();
}
Also used : OAuth2(net.petafuel.styx.core.xs2a.sca.OAuth2) SCAApproach(net.petafuel.styx.core.xs2a.sca.SCAApproach) AspspUrlMapper(net.petafuel.styx.api.util.AspspUrlMapper) SinglePayment(net.petafuel.styx.core.xs2a.entities.SinglePayment) StyxException(net.petafuel.styx.api.exception.StyxException) PaymentResponse(net.petafuel.styx.api.v1.payment.entity.PaymentResponse) ResponseEntity(net.petafuel.styx.api.exception.ResponseEntity) PISRequest(net.petafuel.styx.core.xs2a.contracts.PISRequest) PISRequestFactory(net.petafuel.styx.core.xs2a.factory.PISRequestFactory) AbstractTokenFilter(net.petafuel.styx.api.filter.authentication.control.AbstractTokenFilter) XS2AFactoryInput(net.petafuel.styx.core.xs2a.factory.XS2AFactoryInput) InitiatedPayment(net.petafuel.styx.core.xs2a.entities.InitiatedPayment) IOProcessor(net.petafuel.styx.core.ioprocessing.IOProcessor) Path(javax.ws.rs.Path) AcceptsPreStepAuth(net.petafuel.styx.api.filter.authentication.boundary.AcceptsPreStepAuth) RequiresMandatoryHeader(net.petafuel.styx.api.filter.input.boundary.RequiresMandatoryHeader) POST(javax.ws.rs.POST)

Aggregations

ResponseEntity (net.petafuel.styx.api.exception.ResponseEntity)17 StyxException (net.petafuel.styx.api.exception.StyxException)17 MasterToken (net.petafuel.styx.core.persistence.models.MasterToken)6 Test (org.junit.jupiter.api.Test)5 Path (javax.ws.rs.Path)4 POST (javax.ws.rs.POST)3 AcceptsPreStepAuth (net.petafuel.styx.api.filter.authentication.boundary.AcceptsPreStepAuth)3 AbstractTokenFilter (net.petafuel.styx.api.filter.authentication.control.AbstractTokenFilter)3 RequiresMandatoryHeader (net.petafuel.styx.api.filter.input.boundary.RequiresMandatoryHeader)3 AspspUrlMapper (net.petafuel.styx.api.util.AspspUrlMapper)3 PaymentResponse (net.petafuel.styx.api.v1.payment.entity.PaymentResponse)3 IOProcessor (net.petafuel.styx.core.ioprocessing.IOProcessor)3 PersistenceEmptyResultSetException (net.petafuel.styx.core.persistence.PersistenceEmptyResultSetException)3 AccessToken (net.petafuel.styx.core.persistence.models.AccessToken)3 PISRequest (net.petafuel.styx.core.xs2a.contracts.PISRequest)3 InitiatedPayment (net.petafuel.styx.core.xs2a.entities.InitiatedPayment)3 SinglePayment (net.petafuel.styx.core.xs2a.entities.SinglePayment)3 PISRequestFactory (net.petafuel.styx.core.xs2a.factory.PISRequestFactory)3 XS2AFactoryInput (net.petafuel.styx.core.xs2a.factory.XS2AFactoryInput)3 OAuth2 (net.petafuel.styx.core.xs2a.sca.OAuth2)3