From 48e0a3e1aaa32ebf495348a66d13d6b3d1870ce3 Mon Sep 17 00:00:00 2001 From: Chris Hines <chris.hines@monash.edu> Date: Wed, 6 May 2020 16:20:23 +1000 Subject: [PATCH] support apps that require a form post to log in (as opposed to a token in the query params) --- src/app/browser-window.service.ts | 43 ++++++++++++++++--- .../launch-dialog/launch-dialog.component.ts | 3 +- src/app/strudelapp.ts | 1 + src/app/tes.service.ts | 6 +-- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/app/browser-window.service.ts b/src/app/browser-window.service.ts index 10b2d86..157c46e 100644 --- a/src/app/browser-window.service.ts +++ b/src/app/browser-window.service.ts @@ -10,7 +10,7 @@ import { Injectable } from '@angular/core'; import { Job } from './job'; import { AppAction, Strudelapp, StrudelappInstance } from './strudelapp'; import {BackendSelectionService} from './backend-selection.service'; -import {repeat, take, takeUntil, filter, catchError} from 'rxjs/operators'; +import {repeat, take, takeUntil, filter, catchError, map, tap} from 'rxjs/operators'; import {timer, interval, Subject, BehaviorSubject, of} from 'rxjs'; import { ModaldialogComponent } from './modaldialog/modaldialog.component'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material'; @@ -55,22 +55,55 @@ export class BrowserWindowService { } } - public openAppWindow( job: Job, url: any, basicAuth: boolean, action: AppAction ) { + public openAppWindow( job: Job, url: any, basicAuth: boolean, action: AppAction, appinst: any ) { var re = /^https:\/\/([a-z0-9\.-]+)\/?/; let twshost = this.twsproxy.replace(re,"$1"); let windowloc = url.replace(/\{twsproxy\}/g,this.twsproxy).replace(/twshost/g,twshost); var authwindow = null; if (basicAuth) { - let authwindowloc = windowloc.replace(/^https:\/\//,'https://'+job.appinst.username+':'+job.appinst.password+'@'); + let authwindowloc = windowloc.replace(/^https:\/\//,'https://'+appinst.username+':'+appinst.password+'@'); authwindow = window.open(authwindowloc); this.authdone$.pipe(take(1)).subscribe( () => { authwindow.close() ; this.finishAppWindow(windowloc,job,action) }); interval(500).pipe(takeUntil(this.authdone$),filter((v) => this.windowLoaded(authwindow, authwindowloc))).subscribe( () => this.authdone$.next(true)); - } else { - this.finishAppWindow(windowloc,job, action); + return + } + if (action.postData !== undefined && action.postData !== null) { + let params = {} + for (let k in action.postData) { + params[k] = action.postData[k].replace(/\{password\}/g,appinst.password).replace(/\{username\}/g,appinst.username); + } + this.openWindowWithPostRequest(windowloc,params); + return } + + + this.finishAppWindow(windowloc,job, action); } + + public openWindowWithPostRequest(url: string, params: any) { + var winName='MyWindow'; + var form = document.createElement("form"); + form.setAttribute("method", "post"); + form.setAttribute("action", url); + form.setAttribute("target",winName); + for (var i in params) { + if (params.hasOwnProperty(i)) { + var input = document.createElement('input'); + input.type = 'hidden'; + input.name = i; + input.value = params[i]; + form.appendChild(input); + } + } + document.body.appendChild(form); + window.open('', winName); + form.target = winName; + form.submit(); + document.body.removeChild(form); +} + public logUsage() { var app: any; this.openapps.forEach( (app,index) => { diff --git a/src/app/launch-dialog/launch-dialog.component.ts b/src/app/launch-dialog/launch-dialog.component.ts index 2fd67d4..f186c31 100644 --- a/src/app/launch-dialog/launch-dialog.component.ts +++ b/src/app/launch-dialog/launch-dialog.component.ts @@ -59,7 +59,7 @@ export class LaunchDialogComponent implements OnInit { this.height=0; this.submitcmd.subscribe(() => this.canILaunch()); this.appData.subscribe(() => this.canILaunch()); - this.tesService.openWindow$.subscribe((v) => { this.browserWindowService.openAppWindow(v.job,v.url,v.usebasicauth,v.action)}) + this.tesService.openWindow$.subscribe((v) => { this.browserWindowService.openAppWindow(v.job,v.url,v.usebasicauth,v.action,v.appinst)}) this.browserWindowService.cancelJob$.subscribe((v) => this.tesService.cancel(v)) } @@ -159,6 +159,7 @@ export class LaunchDialogComponent implements OnInit { newaction.paramscmd = action.paramscmd.replace(/\{submitcmd\}/,submitcmd); newaction.notunnel = action.notunnel; newaction.client = action.client; + newaction.postData = action.postData; this.tesService.connect(job,newaction); } diff --git a/src/app/strudelapp.ts b/src/app/strudelapp.ts index eab5c2f..7b8c863 100644 --- a/src/app/strudelapp.ts +++ b/src/app/strudelapp.ts @@ -4,6 +4,7 @@ export class AppAction { notunnel: boolean = false; client: {cmd: string[], redir: string, usebasicauth: boolean}; states: string[]; // list of stats such as 'RUNNING' in which the action is valid. null||undefined if its always valid + postData: string; // if you need to post to the url to authenticate use this } export class Strudelapp { url: string; // A url used to retrieve extra config options. May be null diff --git a/src/app/tes.service.ts b/src/app/tes.service.ts index 4afcc8c..02d0690 100644 --- a/src/app/tes.service.ts +++ b/src/app/tes.service.ts @@ -297,14 +297,14 @@ private addUserHealth(identity,resp) { (data,tunnelresp) => { data[1]['localport'] = (<any> tunnelresp)['localport'] ; return data}), // we don't care about data from the tunnel as long as it was successful.` tap((_) => job.connectionState=3), switchMap(([apiserver,appinst]) => this.getAppUrl(job,appinst,action,<APIServer>apiserver), - ([apiserver,appinst],url) => {return [apiserver,url]}), + ([apiserver,appinst],url) => {return [apiserver,appinst,url]}), tap((_) => job.connectionState=4), - ).subscribe(([apiserver,url]) => { if (url !== null) { + ).subscribe(([apiserver,appinst,url]) => { if (url !== null) { this.openWindow$.next( {'job':job, 'url': <string> url, 'usebasicauth':action.client.usebasicauth, 'apiserver':apiserver, - 'action':action}); + 'action':action,'appinst':appinst}); } job.connectionState=0}, (err) => { job.connectionState = 0; this.handleError(err)}) -- GitLab