2018-09-25 16:28:26 +00:00
import { later , run } from '@ember/runloop' ;
import EmberObject from '@ember/object' ;
import { resolve } from 'rsvp' ;
import $ from 'jquery' ;
import Service from '@ember/service' ;
import { module , test } from 'qunit' ;
import { setupRenderingTest } from 'ember-qunit' ;
import { render , settled } from '@ember/test-helpers' ;
2018-07-05 18:28:12 +00:00
import { supportedAuthBackends } from 'vault/helpers/supported-auth-backends' ;
2018-04-05 21:36:33 +00:00
import hbs from 'htmlbars-inline-precompile' ;
2018-07-05 18:28:12 +00:00
import sinon from 'sinon' ;
2018-04-05 21:36:33 +00:00
import Pretender from 'pretender' ;
import { create } from 'ember-cli-page-object' ;
import authForm from '../../pages/components/auth-form' ;
const component = create ( authForm ) ;
2018-07-05 18:28:12 +00:00
const BACKENDS = supportedAuthBackends ( ) ;
2018-04-05 21:36:33 +00:00
2018-09-25 16:28:26 +00:00
const authService = Service . extend ( {
2018-04-05 21:36:33 +00:00
authenticate ( ) {
2018-09-25 16:28:26 +00:00
return $ . getJSON ( 'http://localhost:2000' ) ;
2018-04-05 21:36:33 +00:00
} ,
2018-08-16 17:48:24 +00:00
setLastFetch ( ) { } ,
2018-04-05 21:36:33 +00:00
} ) ;
2018-09-25 16:28:26 +00:00
const workingAuthService = Service . extend ( {
2018-07-05 18:28:12 +00:00
authenticate ( ) {
2018-09-25 16:28:26 +00:00
return resolve ( { } ) ;
2018-07-05 18:28:12 +00:00
} ,
setLastFetch ( ) { } ,
} ) ;
2018-09-25 16:28:26 +00:00
const routerService = Service . extend ( {
2018-07-05 18:28:12 +00:00
transitionTo ( ) {
2018-10-02 13:53:39 +00:00
return {
followRedirects ( ) {
return resolve ( ) ;
} ,
} ;
2018-07-05 18:28:12 +00:00
} ,
replaceWith ( ) {
2018-09-25 16:28:26 +00:00
return resolve ( ) ;
2018-07-05 18:28:12 +00:00
} ,
} ) ;
2018-09-25 16:28:26 +00:00
module ( 'Integration | Component | auth form' , function ( hooks ) {
setupRenderingTest ( hooks ) ;
hooks . beforeEach ( function ( ) {
this . owner . lookup ( 'service:csp-event' ) . attach ( ) ;
this . owner . register ( 'service:router' , routerService ) ;
this . router = this . owner . lookup ( 'service:router' ) ;
} ) ;
2018-04-05 21:36:33 +00:00
2018-09-25 16:28:26 +00:00
hooks . afterEach ( function ( ) {
this . owner . lookup ( 'service:csp-event' ) . remove ( ) ;
2018-04-05 21:36:33 +00:00
} ) ;
2018-09-25 16:28:26 +00:00
const CSP _ERR _TEXT = ` Error This is a standby Vault node but can't communicate with the active node via request forwarding. Sign in at the active node to use the Vault UI. ` ;
test ( 'it renders error on CSP violation' , async function ( assert ) {
2019-01-18 22:04:40 +00:00
this . owner . unregister ( 'service:auth' ) ;
2018-09-25 16:28:26 +00:00
this . owner . register ( 'service:auth' , authService ) ;
this . auth = this . owner . lookup ( 'service:auth' ) ;
this . set ( 'cluster' , EmberObject . create ( { standby : true } ) ) ;
this . set ( 'selectedAuth' , 'token' ) ;
await render ( hbs ` {{auth-form cluster=cluster selectedAuth=selectedAuth}} ` ) ;
assert . equal ( component . errorText , '' ) ;
component . login ( ) ;
// because this is an ember-concurrency backed service,
// we have to manually force settling the run queue
later ( ( ) => run . cancelTimers ( ) , 50 ) ;
return settled ( ) . then ( ( ) => {
assert . equal ( component . errorText , CSP _ERR _TEXT ) ;
2018-04-05 21:36:33 +00:00
} ) ;
} ) ;
2018-09-25 16:28:26 +00:00
test ( 'it renders with vault style errors' , async function ( assert ) {
let server = new Pretender ( function ( ) {
this . get ( '/v1/auth/**' , ( ) => {
return [
400 ,
{ 'Content-Type' : 'application/json' } ,
JSON . stringify ( {
errors : [ 'Not allowed' ] ,
} ) ,
] ;
} ) ;
} ) ;
2018-04-05 21:36:33 +00:00
2018-09-25 16:28:26 +00:00
this . set ( 'cluster' , EmberObject . create ( { } ) ) ;
this . set ( 'selectedAuth' , 'token' ) ;
await render ( hbs ` {{auth-form cluster=cluster selectedAuth=selectedAuth}} ` ) ;
return component . login ( ) . then ( ( ) => {
assert . equal ( component . errorText , 'Error Authentication failed: Not allowed' ) ;
server . shutdown ( ) ;
2018-04-05 21:36:33 +00:00
} ) ;
} ) ;
2018-09-25 16:28:26 +00:00
test ( 'it renders AdapterError style errors' , async function ( assert ) {
let server = new Pretender ( function ( ) {
this . get ( '/v1/auth/**' , ( ) => {
return [ 400 , { 'Content-Type' : 'application/json' } ] ;
} ) ;
} ) ;
this . set ( 'cluster' , EmberObject . create ( { } ) ) ;
this . set ( 'selectedAuth' , 'token' ) ;
await render ( hbs ` {{auth-form cluster=cluster selectedAuth=selectedAuth}} ` ) ;
return component . login ( ) . then ( ( ) => {
assert . equal ( component . errorText , 'Error Authentication failed: Bad Request' ) ;
server . shutdown ( ) ;
} ) ;
2018-04-05 21:36:33 +00:00
} ) ;
2018-07-05 18:28:12 +00:00
2018-09-25 16:28:26 +00:00
test ( 'it renders all the supported tabs when no methods are passed' , async function ( assert ) {
let methods = {
'approle/' : {
type : 'approle' ,
} ,
} ;
let server = new Pretender ( function ( ) {
this . get ( '/v1/sys/internal/ui/mounts' , ( ) => {
return [ 200 , { 'Content-Type' : 'application/json' } , JSON . stringify ( { data : { auth : methods } } ) ] ;
} ) ;
} ) ;
await render ( hbs ` {{auth-form cluster=cluster}} ` ) ;
2018-09-05 19:28:10 +00:00
2018-09-25 16:28:26 +00:00
await settled ( ) ;
2018-09-05 19:28:10 +00:00
assert . equal ( component . tabs . length , BACKENDS . length , 'renders a tab for every backend' ) ;
2018-09-25 16:28:26 +00:00
server . shutdown ( ) ;
2018-09-05 19:28:10 +00:00
} ) ;
2018-07-05 18:28:12 +00:00
2018-09-25 16:28:26 +00:00
test ( 'it renders all the supported methods and Other tab when methods are present' , async function ( assert ) {
let methods = {
'foo/' : {
type : 'userpass' ,
} ,
'approle/' : {
type : 'approle' ,
} ,
} ;
let server = new Pretender ( function ( ) {
this . get ( '/v1/sys/internal/ui/mounts' , ( ) => {
return [ 200 , { 'Content-Type' : 'application/json' } , JSON . stringify ( { data : { auth : methods } } ) ] ;
} ) ;
2018-08-16 17:48:24 +00:00
} ) ;
2018-07-05 18:28:12 +00:00
2018-10-02 13:53:39 +00:00
this . set ( 'cluster' , EmberObject . create ( { } ) ) ;
2018-09-25 16:28:26 +00:00
await render ( hbs ` {{auth-form cluster=cluster }} ` ) ;
await settled ( ) ;
2018-08-16 17:48:24 +00:00
assert . equal ( component . tabs . length , 2 , 'renders a tab for userpass and Other' ) ;
assert . equal ( component . tabs . objectAt ( 0 ) . name , 'foo' , 'uses the path in the label' ) ;
assert . equal ( component . tabs . objectAt ( 1 ) . name , 'Other' , 'second tab is the Other tab' ) ;
server . shutdown ( ) ;
} ) ;
2018-07-05 18:28:12 +00:00
2018-10-02 15:05:34 +00:00
test ( 'it calls authenticate with the correct path' , async function ( assert ) {
2019-01-18 22:04:40 +00:00
this . owner . unregister ( 'service:auth' ) ;
2018-09-25 16:28:26 +00:00
this . owner . register ( 'service:auth' , workingAuthService ) ;
this . auth = this . owner . lookup ( 'service:auth' ) ;
let authSpy = sinon . spy ( this . get ( 'auth' ) , 'authenticate' ) ;
let methods = {
'foo/' : {
type : 'userpass' ,
} ,
} ;
let server = new Pretender ( function ( ) {
this . get ( '/v1/sys/internal/ui/mounts' , ( ) => {
return [ 200 , { 'Content-Type' : 'application/json' } , JSON . stringify ( { data : { auth : methods } } ) ] ;
} ) ;
2018-08-16 17:48:24 +00:00
} ) ;
2018-07-20 21:48:25 +00:00
2018-10-02 13:53:39 +00:00
this . set ( 'cluster' , EmberObject . create ( { } ) ) ;
2018-09-25 16:28:26 +00:00
this . set ( 'selectedAuth' , 'foo/' ) ;
await render ( hbs ` {{auth-form cluster=cluster selectedAuth=selectedAuth}} ` ) ;
await component . login ( ) ;
2018-07-20 21:48:25 +00:00
2018-09-25 16:28:26 +00:00
await settled ( ) ;
2018-07-20 21:48:25 +00:00
assert . ok ( authSpy . calledOnce , 'a call to authenticate was made' ) ;
let { data } = authSpy . getCall ( 0 ) . args [ 0 ] ;
2018-08-16 17:48:24 +00:00
assert . equal ( data . path , 'foo' , 'uses the id for the path' ) ;
2018-07-20 21:48:25 +00:00
authSpy . restore ( ) ;
2018-08-16 17:48:24 +00:00
server . shutdown ( ) ;
2018-07-20 21:48:25 +00:00
} ) ;
2018-09-25 16:28:26 +00:00
test ( 'it renders all the supported methods when no supported methods are present in passed methods' , async function ( assert ) {
let methods = {
'approle/' : {
type : 'approle' ,
} ,
} ;
let server = new Pretender ( function ( ) {
this . get ( '/v1/sys/internal/ui/mounts' , ( ) => {
return [ 200 , { 'Content-Type' : 'application/json' } , JSON . stringify ( { data : { auth : methods } } ) ] ;
} ) ;
2018-07-05 18:28:12 +00:00
} ) ;
2018-10-02 13:53:39 +00:00
this . set ( 'cluster' , EmberObject . create ( { } ) ) ;
2018-09-25 16:28:26 +00:00
await render ( hbs ` {{auth-form cluster=cluster}} ` ) ;
await settled ( ) ;
server . shutdown ( ) ;
assert . equal ( component . tabs . length , BACKENDS . length , 'renders a tab for every backend' ) ;
2018-07-05 18:28:12 +00:00
} ) ;
2018-09-25 16:28:26 +00:00
test ( 'it makes a request to unwrap if passed a wrappedToken and logs in' , async function ( assert ) {
this . owner . register ( 'service:auth' , workingAuthService ) ;
this . auth = this . owner . lookup ( 'service:auth' ) ;
let authSpy = sinon . spy ( this . get ( 'auth' ) , 'authenticate' ) ;
let server = new Pretender ( function ( ) {
this . post ( '/v1/sys/wrapping/unwrap' , ( ) => {
return [
200 ,
{ 'Content-Type' : 'application/json' } ,
JSON . stringify ( {
auth : {
client _token : '12345' ,
} ,
} ) ,
] ;
} ) ;
} ) ;
let wrappedToken = '54321' ;
this . set ( 'wrappedToken' , wrappedToken ) ;
2018-10-02 13:53:39 +00:00
this . set ( 'cluster' , EmberObject . create ( { } ) ) ;
2018-09-25 16:28:26 +00:00
await render ( hbs ` {{auth-form cluster=cluster wrappedToken=wrappedToken}} ` ) ;
later ( ( ) => run . cancelTimers ( ) , 50 ) ;
await settled ( ) ;
2018-07-05 18:28:12 +00:00
assert . equal ( server . handledRequests [ 0 ] . url , '/v1/sys/wrapping/unwrap' , 'makes call to unwrap the token' ) ;
assert . equal (
server . handledRequests [ 0 ] . requestHeaders [ 'X-Vault-Token' ] ,
wrappedToken ,
'uses passed wrapped token for the unwrap'
) ;
assert . ok ( authSpy . calledOnce , 'a call to authenticate was made' ) ;
server . shutdown ( ) ;
authSpy . restore ( ) ;
} ) ;
2018-09-25 16:28:26 +00:00
test ( 'it shows an error if unwrap errors' , async function ( assert ) {
let server = new Pretender ( function ( ) {
this . post ( '/v1/sys/wrapping/unwrap' , ( ) => {
return [
400 ,
{ 'Content-Type' : 'application/json' } ,
JSON . stringify ( {
errors : [ 'There was an error unwrapping!' ] ,
} ) ,
] ;
} ) ;
2018-07-05 18:28:12 +00:00
} ) ;
2018-09-25 16:28:26 +00:00
this . set ( 'wrappedToken' , '54321' ) ;
await render ( hbs ` {{auth-form cluster=cluster wrappedToken=wrappedToken}} ` ) ;
later ( ( ) => run . cancelTimers ( ) , 50 ) ;
2018-07-05 18:28:12 +00:00
2018-09-25 16:28:26 +00:00
await settled ( ) ;
2018-07-05 18:28:12 +00:00
assert . equal (
component . errorText ,
'Error Token unwrap failed: There was an error unwrapping!' ,
'shows the error'
) ;
server . shutdown ( ) ;
} ) ;
} ) ;