import { BusinessPartner } from '@sap/cloud-sdk-vdm-business-partner-service' ; import * as xssec from '@sap/xssec' ; import { Destination } from '@sap-cloud-sdk/connectivity' ; import { executeHttpRequest } from '../../../../packages/http-client/src' ; import { getService , fetchDestination , wrapJwtInHeader , decodeJwt , getDestination , getDestinationFromDestinationService , serviceToken } from '../../../../packages/connectivity/src/internal' ; import { loadLocalVcap , readSystems , readUserAccessToken , Systems , UserAccessTokens } from './auth-flow-util' ; describe ( 'OAuth flows' , ( ) => { let destinationService ; let accessToken ; let systems ; beforeAll ( ( ) => { accessToken = readUserAccessToken ( ) ; systems = readSystems ( ) ; loadLocalVcap ( ) ; destinationService = getService ( 'destination' ) ; } ) ; xit ( 'OAuth2Password: Fetches destination and destination service has token' , async ( ) => { const destination = await getDestination ( { destinationName : systems . destination . providerOauth2Password } ) ; expect ( destination ! . authTokens ! [ 0 ] . type ) . toBe ( 'bearer' ) ; expect ( destination ! . authTokens ! [ 0 ] . value ) . toBeDefined ( ) ; } , 60000 ) ; xit ( 'BasicAuth: Provider Destination & Provider Token + GET request' , async ( ) => { const destination = await getDestination ( { destinationName : systems . s4 . providerBasic , jwt : accessToken . provider } ) ; const result = await BusinessPartner . requestBuilder ( ) . getAll ( ) . top ( 1 ) . execute ( destination ! ) ; expect ( result . length ) . toBe ( 1 ) ; } , 60000 ) ; xit ( 'BasicAuth onPrem  Basic Authentication' , async ( ) => { const destination = await getDestinationFromDestinationService ( { destinationName : systems . s4onPrem . providerBasic } ) ; expect ( destination ! . proxyConfiguration ) . toMatchObject ( { headers : { 'Proxy-Authorization' : expect . stringMatching ( /Bearer.*/ ) } , host : expect . stringMatching ( /.*sap\.hana\.ondemand\.com/ ) , port : expect . stringMatching ( /\d+/ ) , protocol : 'http' } ) ; } , 60000 ) ; xit ( 'BasicAuth: Provider Destination & Provider Token + PUT request (csrf token)' , async ( ) => { const destination = await getDestination ( { destinationName : systems . s4 . providerBasic , jwt : accessToken . provider } ) ; const buPa = BusinessPartner . builder ( ) . businessPartnerCategory ( '1' ) . lastName ( 'name' ) . build ( ) ; const result = await BusinessPartner . requestBuilder ( ) . create ( buPa ) . execute ( destination ! ) ; expect ( result . lastName ) . toBe ( 'name' ) ; } , 60000 ) ; xit ( 'BasicAuth: Subscriber Destination & Subscriber Token' , async ( ) => { const destination = await getDestination ( { destinationName : systems . s4 . subscriberBasic , jwt : accessToken . subscriber } ) ; const result = await BusinessPartner . requestBuilder ( ) . getAll ( ) . top ( 1 ) . execute ( destination ! ) ; expect ( result . length ) . toBe ( 1 ) ; } , 60000 ) ; xit ( 'Basic Auth: iss as token ' , async ( ) => { const destination = await getDestination ( { destinationName : systems . s4 . providerBasic , iss : 'http://s4sdk.localhost:8080/uaa/oauth/token' } ) ; expect ( destination ?. password ) . toBeDefined ( ) ; } , 60000 ) ; xit ( 'OAuth2SAMLBearerAssertion: Provider Destination & Provider Token' , async ( ) => { const destination = await getDestination ( { destinationName : systems . s4 . providerOAuth2SAMLBearerAssertion , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] . error ) . toBeNull ( ) ; const result = await BusinessPartner . requestBuilder ( ) . getAll ( ) . top ( 1 ) . execute ( destination ! ) ; expect ( result . length ) . toBe ( 1 ) ; } , 60000 ) ; xit ( 'OAuth2ClientCredentials: Provider Destination (common token url)' , async ( ) => { let destination = await getDestination ( { destinationName : systems . destination . providerOauth2ClientCredentialsCommonTokenURL } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toBeUndefined ( ) ; destination = await getDestination ( { destinationName : systems . destination . providerOauth2ClientCredentialsCommonTokenURL , jwt : accessToken . subscriber } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toBeUndefined ( ) ; destination = await getDestination ( { destinationName : systems . destination . providerOauth2ClientCredentialsCommonTokenURL , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toBeUndefined ( ) ; assertCommenTokenUrl ( destination ! ) ; } , 60000 ) ; xit ( 'OAuth2ClientCredentials: Provider Destination (dedicated token service url)' , async ( ) => { let destination = await getDestination ( { destinationName : systems . destination . providerOauth2ClientCredentials } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toBeNull ( ) ; destination = await getDestination ( { destinationName : systems . destination . providerOauth2ClientCredentials , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toBeNull ( ) ; destination = await getDestination ( { destinationName : systems . destination . providerOauth2ClientCredentials , jwt : accessToken . subscriber } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toBeNull ( ) ; assertDedicatedTokenUrl ( destination ! ) ; } , 60000 ) ; xit ( 'OAuth2ClientCredentials: Provider Destination & Provider Jwt (workflow)' , async ( ) => { const destination = await getDestination ( { destinationName : systems . workflow . providerOAuth2ClientCredentials , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] . error ) . toBeNull ( ) ; destination ! . url = destination ! . url + '/v1/workflow-definitions' ; const response = await executeHttpRequest ( destination ! , { method : 'get' } ) ; expect ( response . status ) . toBe ( 200 ) ; } , 60000 ) ; xit ( 'OAuth2UserTokenExchange: Provider destination and Provider Jwt (workflow)' , async ( ) => { const destination = await getDestination ( { destinationName : systems . workflow . providerOAuth2UserTokenExchange , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] . error ) . toBeNull ( ) ; destination ! . url = destination ! . url + '/v1/workflow-definitions' ; const response = await executeHttpRequest ( destination ! , { method : 'get' } ) ; expect ( response . status ) . toBe ( 200 ) ; } , 60000 ) ; xit ( 'OAuth2UserTokenExchange: Provider destination (common token url)' , async ( ) => { let destination = await getDestination ( { destinationName : systems . destination . providerOauth2UserTokenExchangeCommonTokenURL , jwt : accessToken . subscriber } ) ; expect ( destination ! . authTokens ! [ 0 ] . error ) . toBeNull ( ) ; destination = await getDestination ( { destinationName : systems . destination . providerOauth2UserTokenExchangeCommonTokenURL , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] . error ) . toBeNull ( ) ; assertCommenTokenUrl ( destination ! ) ; } , 60000 ) ; xit ( 'OAuth2UserTokenExchange: Subscriber destination and Subscriber Jwt' , async ( ) => { const destination = await getDestination ( { destinationName : systems . destination . subscriberOauth2UserTokenExchange , jwt : accessToken . subscriber } ) ; expect ( destination ! . authTokens ! [ 0 ] . error ) . toBeNull ( ) ; const response = await executeHttpRequest ( { url : 'https://destination-configuration.cfapps.sap.hana.ondemand.com/destination-configuration/v1/subaccountDestinations' } , { method : 'get' , headers : wrapJwtInHeader ( destination ! . authTokens ! [ 0 ] . value ) . headers } ) ; expect ( response . status ) . toBe ( 200 ) ; } , 60000 ) ; xit ( 'OAuth2UserTokenExchange: Provider destination (dedicated token url)' , async ( ) => { let destination = await getDestination ( { destinationName : systems . destination . providerOauth2UserTokenExchange , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] . error ) . toBeNull ( ) ; destination = await getDestination ( { destinationName : systems . destination . providerOauth2UserTokenExchange , jwt : accessToken . subscriber } ) ; expect ( destination ! . authTokens ! [ 0 ] . error ) . toMatch ( /Invalid issuer.*token did not match expected/ ) ; assertDedicatedTokenUrl ( destination ! ) ; } , 60000 ) ; xit ( 'OAuth2JWTBearer: Provider Destination & Provider Token (workflow call)' , async ( ) => { const destination = await getDestination ( { destinationName : systems . workflow . providerOauth2JWTBearer , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] . error ) . toBeNull ( ) ; destination ! . url = destination ! . url + '/v1/workflow-definitions' ; const response = await executeHttpRequest ( destination ! , { method : 'get' } ) ; expect ( response . status ) . toBe ( 200 ) ; } , 60000 ) ; xit ( 'OAuth2JWTBearer: Provider Destination  (common token service URL)' , async ( ) => { let destination = await getDestination ( { destinationName : systems . destination . providerOauth2JWTBearerCommonTokenURL , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toBeNull ( ) ; destination = await getDestination ( { destinationName : systems . destination . providerOauth2JWTBearerCommonTokenURL , jwt : accessToken . subscriber } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toBeNull ( ) ; } , 60000 ) ; xit ( 'OAuth2JWTBearer: Provider Destination (dedicated token service URL)' , async ( ) => { let destination = await getDestination ( { destinationName : systems . destination . providerOauth2JWTBearer , jwt : accessToken . subscriber } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toMatch ( /Unable to map issuer/ ) ; destination = await getDestination ( { destinationName : systems . destination . providerOauth2JWTBearer , jwt : accessToken . provider } ) ; expect ( destination ! . authTokens ! [ 0 ] ! . error ) . toBeNull ( ) ; } , 60000 ) ; xit ( 'ClientCertificate: Fetches the certificate and uses it' , async ( ) => { const destination = await getDestination ( { destinationName : systems . s4 . providerClientCert } ) ; expect ( destination ! . certificates ! . length ) . toBe ( 1 ) ; const bps = await BusinessPartner . requestBuilder ( ) . getAll ( ) . top ( 5 ) . execute ( destination ! ) ; expect ( bps . length ) . toBeGreaterThan ( 0 ) ; } , 10000 ) ; xit ( 'ClientCertificate: Fetches the certificate and uses it - ignoring broken proxy' , async ( ) => { process . env . HTTPS_PROXY = 'http://someHost:1234' ; process . env . NO_PROXY = 'https://s4sdk.authentication.sap.hana.ondemand.com/oauth/token,https://my300470-api.s4hana.ondemand.com' ; const destination = await getDestination ( { destinationName : systems . s4 . providerClientCert } ) ; expect ( destination ! . certificates ! . length ) . toBe ( 1 ) ; const bps = await BusinessPartner . requestBuilder ( ) . getAll ( ) . top ( 5 ) . execute ( destination ! ) ; expect ( bps . length ) . toBeGreaterThan ( 0 ) ; } , 60000 ) ; xit ( 'PrincipalPropagation: Provider not E2E' , async ( ) => { const destination = await getDestination ( { destinationName : systems . s4onPrem . providerPrincipalPropagation , jwt : accessToken . provider } ) ; expect ( destination ?. proxyConfiguration ) . toBeDefined ( ) ; expect ( destination ?. proxyConfiguration ?. headers ?. [ 'Proxy-Authorization' ] ) . toBeDefined ( ) ; expect ( destination ?. proxyConfiguration ?. headers ?. [ 'SAP-Connectivity-Authentication' ] ) . toBeDefined ( ) ; } , 60000 ) ; xit ( 'IAS: token exchange by making an xsuaa call' , async ( ) => { const iasToken = accessToken . iasProvider ; const xsuaaConfig = JSON . parse ( process . env . VCAP_SERVICES ! ) . xsuaa [ 0 ] . credentials ; const token = await new Promise ( ( resolve , reject ) => { xssec . requests . requestUserToken ( iasToken , xsuaaConfig , null , null , null , xsuaaConfig . subaccountid , ( err , xsuaaToken ) => ( err ? reject ( err ) : resolve ( xsuaaToken ) ) ) ; } ) ; const decoded = decodeJwt ( token ) ; expect ( decoded . scope . length ) . toBeGreaterThan ( 0 ) ; } , 60000 ) ; xit ( 'IAS: token exchange with xssec createSecurityContext' , async ( ) => { const iasToken = accessToken . iasProvider ; const xsuaaConfig = JSON . parse ( process . env . VCAP_SERVICES ! ) . xsuaa [ 0 ] . credentials ; const token = await new Promise ( ( resolve , reject ) => { xssec . createSecurityContext ( iasToken , xsuaaConfig , ( err , context , tokenInfo ) => err ? reject ( err ) : resolve ( tokenInfo . getTokenValue ( ) ) ) ; } ) ; const decoded = decodeJwt ( token ) ; expect ( decoded . scope . length ) . toBeGreaterThan ( 0 ) ; } , 60000 ) ; xit ( 'IAS + OAuth2ClientCredentials: Provider Destination & Provider Jwt' , async ( ) => { const iasToken = accessToken . iasProvider ; const xsuaaConfig = JSON . parse ( process . env . VCAP_SERVICES ! ) . xsuaa [ 0 ] . credentials ; const xsuaaToken = await new Promise ( ( resolve , reject ) => { xssec . createSecurityContext ( iasToken , xsuaaConfig , ( err , context , tokenInfo ) => err ? reject ( err ) : resolve ( tokenInfo . getTokenValue ( ) ) ) ; } ) ; const clientGrant = await serviceToken ( 'destination' , { jwt : xsuaaToken } ) ; const destination = await fetchDestination ( destinationService ! . credentials . uri , clientGrant , systems . workflow . providerOAuth2ClientCredentials ) ; expect ( destination . authTokens ! [ 0 ] . error ) . toBeNull ( ) ; destination . url = destination . url + '/v1/workflow-definitions' ; const response = await executeHttpRequest ( destination , { method : 'get' } ) ; expect ( response . status ) . toBe ( 200 ) ; } , 60000 ) ; } ) ; function assertCommenTokenUrl ( destination ) { expect ( destination . originalProperties ! . destinationConfiguration [ 'tokenServiceURLType' ] ) . toBe ( 'Common' ) ; } function assertDedicatedTokenUrl ( destination ) { expect ( destination . originalProperties ! . destinationConfiguration [ 'tokenServiceURLType' ] ) . toBe ( 'Dedicated' ) ; }