diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 8c6a42bc10b6555988f8c2c7f23d1d5e9c34cd07..355c7703544b2af298c763783497ad10fb367d5f 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,5 +1,6 @@
 import { Component } from '@angular/core';
 import { TesService } from './tes.service';
+import { AuthorisationService} from './authorisation.service';
 
 @Component({
   selector: 'app-root',
@@ -13,7 +14,7 @@ export class AppComponent {
   public authorised: boolean;
   // private testingAuth: boolean;
 
-  constructor(private tesService: TesService,) {
+  constructor(private tesService: TesService, private authService: AuthorisationService) {
    };
 
   ngOnInit() {
@@ -21,13 +22,13 @@ export class AppComponent {
     // this.testingAuth = false;
   }
 
-  login() {
-    console.log("login");
-    this.tesService.login()
-  }
-
-  logout() {
-    console.log("logout");
-    this.tesService.logout();
-  }
+  // login() {
+  //   console.log("login");
+  //   this.authService.login()
+  // }
+  //
+  // logout() {
+  //   console.log("logout");
+  //   this.tesService.logout();
+  // }
 }
diff --git a/src/app/authorisation.service.spec.ts b/src/app/authorisation.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3286e3a92786fb5b78966b2861c759a2e8d33e3e
--- /dev/null
+++ b/src/app/authorisation.service.spec.ts
@@ -0,0 +1,15 @@
+import { TestBed, inject } from '@angular/core/testing';
+
+import { AuthorisationService } from './authorisation.service';
+
+describe('AuthorisationService', () => {
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      providers: [AuthorisationService]
+    });
+  });
+
+  it('should be created', inject([AuthorisationService], (service: AuthorisationService) => {
+    expect(service).toBeTruthy();
+  }));
+});
diff --git a/src/app/authorisation.service.ts b/src/app/authorisation.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..017e383419c7478b7872123a0c135059a442abd4
--- /dev/null
+++ b/src/app/authorisation.service.ts
@@ -0,0 +1,125 @@
+import { Injectable } from '@angular/core';
+import { HttpClientModule, HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
+import { Observable } from 'rxjs/Observable';
+import { of } from 'rxjs/observable/of';
+import { catchError, map, tap } from 'rxjs/operators';
+import { ActivatedRoute, Router } from '@angular/router';
+import {LocationStrategy} from '@angular/common';
+// import { keypair } from 'keypair';
+import * as keypair from 'keypair';
+import * as forge from "node-forge";
+import { Identity, AuthToken, KeyCert, AuthService } from './identity';
+import {BehaviorSubject} from 'rxjs/BehaviorSubject';
+import {Subject} from 'rxjs/Subject';
+import {TesService} from './tes.service';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class AuthorisationService {
+  private token: Subject<AuthToken>;
+  // private keyCert: Subject<KeyCert>;
+
+
+  constructor(private http: HttpClient,
+              private locationStrategy: LocationStrategy,
+              private route: ActivatedRoute,
+              private router: Router,
+              private tesService: TesService) {
+                this.token = new Subject<AuthToken>();
+                this.token.subscribe(token => this.getCert(token));
+                this.route.fragment.subscribe(frag => this.storeToken(frag));
+ }
+ storeToken(frag: string) {
+   if (frag === undefined || frag == null) {
+       return;
+   }
+   let tokenmatch = null;
+   let statematch = null;
+   if (!(frag === undefined) && !(frag == null)) {
+     tokenmatch = frag.match(/access_token\=([\S\s]*?)[&|$]/);
+     statematch = frag.match(/state\=([\S\s]*?)[&|$]/);
+   }
+   if (tokenmatch == null || statematch == null) {
+     return;
+   }
+
+   let accesstoken = tokenmatch[1];
+   let state = statematch[1];
+   this.router.navigate(['/']);
+
+   //Verify that the state matched the nonce we used when initiating login
+   let tuple = JSON.parse(localStorage.getItem('authservice'));
+   if (tuple[1] != state) {
+     return
+   }
+
+   this.token.next(new AuthToken(tokenmatch[1],tuple[0]));
+
+   // TODO fire off a query to the auth service to get the associated sites
+
+
+ }
+
+ getCert(token: AuthToken) {
+    console.log('in getCert');
+    if (token.token === undefined || token.token === '' || token.token == null) {
+      console.log('no authtoken available, we wont be able to generate a cert');
+      console.log(token);
+      return
+    }
+    console.log("Generating key matter");
+
+    let starttime = new Date();
+    let newkeypair = keypair();
+    let publicKey = forge.pki.publicKeyFromPem(newkeypair.public);
+    let sshpub = forge.ssh.publicKeyToOpenSSH(publicKey, 'sv2@monash.edu');
+    let endtime = new Date();
+    console.log("generating new keys took", endtime.valueOf() - starttime.valueOf())
+
+    let headers = new HttpHeaders();
+    let options = { headers: headers, withCredentials: true};
+
+    let data = {'token': token.token, 'pubkey': sshpub, 'signing_url': token.authservice.sign};
+
+    console.log('posting to getcert',this.tesService.Base);
+    this.http.post<any>(this.tesService.Base+'/getcert',data, options)
+                       .pipe(catchError(this.handleError('getCert',[])))
+                       .subscribe(resp => this.makeKeyCert(newkeypair.private, resp, token.authservice))
+   console.log('getcert complete');
+ }
+
+ makeKeyCert(key: string, resp, authservice: AuthService) {
+   let keyCert = new KeyCert()
+   keyCert.key = key;
+   keyCert.cert = resp['cert'];
+   keyCert.authservice = authservice;
+   console.log('updating keycert',keyCert);
+   this.tesService.keyCert.next(keyCert);
+ }
+
+ public login() {
+   let redirect_uri = window.location.origin+this.locationStrategy.getBaseHref()+"sshauthz_callback";
+   let nonce="asdfzxcv";
+   let authservice = new AuthService();
+   authservice.base = "https://autht.massive.org.au/hpcid/";
+   authservice.authorise = authservice.base + 'oauth/authorize';
+   authservice.sign = authservice.base + 'api/v1/sign_key';
+   authservice.client_id = "86c06039-e589-4b39-9d1f-9eca431be18f";
+   localStorage.setItem('authservice', JSON.stringify([authservice,nonce]));
+   window.location.assign(authservice.authorise+"?response_type=token&redirect_uri="+redirect_uri+"&state="+nonce+"&client_id="+authservice.client_id);
+ }
+
+ private httperror(error: any) {
+   console.log(error);
+ }
+
+ private handleError<T> (operation = 'operation', result?: T) {
+   return (error: any): Observable<T> => {
+     console.log('in handle error',operation);
+     console.log(error.status);
+     console.error(error);
+     return of(result as T);
+   };
+ }
+}
diff --git a/src/app/logindialog/logindialog.component.ts b/src/app/logindialog/logindialog.component.ts
index b9617093d4d66b66aec901417ad982ae2090145a..28bf80fa0eda1a5094efe40e0e003d881f0ff789 100644
--- a/src/app/logindialog/logindialog.component.ts
+++ b/src/app/logindialog/logindialog.component.ts
@@ -1,6 +1,7 @@
 import { Component, OnInit, Inject  } from '@angular/core';
 import { MatDialog, MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material';
 import { TesService } from '../tes.service';
+import {AuthorisationService} from '../authorisation.service';
 
 
 
@@ -14,14 +15,15 @@ export class LogindialogComponent implements OnInit {
   constructor(
     public dialogRef: MatDialogRef<LogindialogComponent>,
     @Inject(MAT_DIALOG_DATA) public data: any,
-    private tesService: TesService) {
+    private tesService: TesService,
+    private authService: AuthorisationService ) {
    }
 
   ngOnInit() {
   }
 
   onLogin() {
-    this.tesService.login();
+    this.authService.login();
   }
   onCancel() {
     this.dialogRef.close();
diff --git a/src/app/tes.service.ts b/src/app/tes.service.ts
index 0362deac03878a7a24207a3e3c30e82bc927807e..fd9b487261dcaa965e122480534f5889724b5e7f 100644
--- a/src/app/tes.service.ts
+++ b/src/app/tes.service.ts
@@ -6,7 +6,6 @@ import { catchError, map, tap } from 'rxjs/operators';
 import { Job } from './job';
 import {BehaviorSubject} from 'rxjs/BehaviorSubject';
 import {Subject} from 'rxjs/Subject';
-
 import { Strudelapp } from './strudelapp';
 import { Computesite } from './computesite';
 import { Identity, AuthToken, KeyCert, AuthService } from './identity';
@@ -16,95 +15,57 @@ import { StrudelappsService } from './strudelapps.service';
 import { timer } from 'rxjs/observable/timer';
 import { repeat } from 'rxjs/operators';
 import {LocationStrategy} from '@angular/common';
-// import { keypair } from 'keypair';
-import * as keypair from 'keypair';
-import * as forge from "node-forge";
 import { ActivatedRoute, Router } from '@angular/router';
 
-// import keypair = require('keypair');
-// import forge = require('node-forge');
-
-
 @Injectable({
   providedIn: 'root',
 })
 export class TesService {
-// private Base='http://localhost:5000'
-private Base='https://vm-118-138-240-255.erc.monash.edu.au/tes'
-// public authorised: BehaviorSubject<boolean>;
-// public tesSelected: BehaviorSubject<boolean>;
+public Base='https://vm-118-138-240-255.erc.monash.edu.au/tes'
 public statusMsg: BehaviorSubject<any>;
 public jobs: any[];
 public busy: BehaviorSubject<boolean> ;
-// public testingAuth: BehaviorSubject<boolean>;
 public joblist: BehaviorSubject<{ [id: string ]: Job[]}>;
 private timerSubscription: any;
-private token: Subject<AuthToken>;
-private keyCert: Subject<KeyCert>;
-private signing_endpoint: string;
-private sshauthzbase: string;
-private sshauthz: string;
-private client_id: string;
-private keypair: any;
-private ssh: any;
-private sshcert: any;
+public keyCert: Subject<KeyCert>;
 public identities: BehaviorSubject<Identity[]>;
 private batchinterface: {[id: string] : BatchInterface};
 
-
-
   constructor(private http: HttpClient,
-              private locationStrategy: LocationStrategy,
-              private route: ActivatedRoute,
-              private router: Router,
               private computesite: ComputesitesService,
               private strudelappsService: StrudelappsService) {
     this.statusMsg = new BehaviorSubject<any>('');
     this.busy = new BehaviorSubject<boolean>(false);
     this.joblist = new BehaviorSubject<{[id: string]: Job[]}>({});
     this.timerSubscription = null;
-    this.token = new Subject<AuthToken>();
     this.keyCert = new Subject<KeyCert>();
     this.identities= new BehaviorSubject<Identity[]>([]);
-    this.route.fragment.subscribe(frag => this.storeToken(frag));
-    this.token.subscribe(token => this.getCert(token));
     this.keyCert.subscribe(keyCert => this.sshAdd(keyCert));
     this.batchinterface = {};
     this.getIdentities();
  }
 
-
-  updateJoblist(resp, identity: Identity) {
-    let joblist = <Job[]>resp;
-    let alljobs = this.joblist.value;
-    let i = 0;
-    for (let j of joblist) {
-      j.app = this.strudelappsService.getApp(j.name);
-      j.identity = identity;
-    }
-    alljobs[identity.repr()] = joblist;
-    this.joblist.next(alljobs);
-    this.statusMsg.next(null);
-  }
-
-  submitted(resp: any ) {
-    this.busy.next(false);
-    this.statusMsg.next('Updating job list');
-    this.getJobs();
-  }
-
- buildParams(app: Strudelapp, identity: Identity, batchinterface: BatchInterface): string {
+ private buildParams(app: Strudelapp, identity: Identity, batchinterface: BatchInterface): string {
    let params = new URLSearchParams();
-   let appstr = JSON.stringify(app);
-   params.set('app',appstr);
-   let interfacestr = JSON.stringify(batchinterface);
-   params.set('interface',interfacestr);
-   let identitystr = JSON.stringify(identity);
-   params.set('identity',identitystr);
-
+   params.set('app',JSON.stringify(app));
+   params.set('interface',JSON.stringify(batchinterface));
+   params.set('identity',JSON.stringify(identity));
    return params.toString();
  }
 
+ updateJoblist(resp, identity: Identity) {
+   let joblist = <Job[]>resp;
+   let alljobs = this.joblist.value;
+   let i = 0;
+   for (let j of joblist) {
+     j.app = this.strudelappsService.getApp(j.name);
+     j.identity = identity;
+   }
+   alljobs[identity.repr()] = joblist;
+   this.joblist.next(alljobs);
+   this.statusMsg.next(null);
+ }
+
  getJobs() {
    let headers = new HttpHeaders();
    let options = { headers: headers, withCredentials: true};
@@ -134,16 +95,28 @@ private batchinterface: {[id: string] : BatchInterface};
                       .pipe(catchError(this.handleError('getJobs',[])))
                       .subscribe(resp => this.updateJoblist(resp,identity));
                     }
+ }
+
+ private startPolling() {
+   this.statusMsg.next(null);
+   if (!(this.timerSubscription === null)) {
+     this.timerSubscription.unsubscribe()
+   }
+   this.timerSubscription = timer(5000).pipe(repeat()).subscribe(() => this.getJobs());
+   this.getJobs();
+ }
 
+ private stopPolling() {
+   if (!(this.timerSubscription === null)) {
+     this.timerSubscription.unsubscribe()
+   }
  }
 
- getconfig(app: Strudelapp, identity: Identity): Observable<any> {
+ public getconfig(app: Strudelapp, identity: Identity): Observable<any> {
    let headers = new HttpHeaders();
    let options = { headers: headers, withCredentials: true};
    return this.http.get<any>(identity.site.url+'getconfig/'+app.name,options)
                                         .pipe(catchError(this.handleError('getconfig',[])))
-
-
 }
 
  submit(app: Strudelapp, identity: Identity, batchinterface: BatchInterface) {
@@ -157,6 +130,12 @@ private batchinterface: {[id: string] : BatchInterface};
                                          .subscribe(resp => this.busy.next(false));
  }
 
+ submitted(resp: any ) {
+   this.busy.next(false);
+   this.statusMsg.next('Updating job list');
+   this.getJobs();
+ }
+
  cancel(job: Job) {
    console.log("In tes cancel");
    let headers = new HttpHeaders();
@@ -183,80 +162,7 @@ private batchinterface: {[id: string] : BatchInterface};
    this.busy.next(false);
  }
 
-
-storeToken(frag: string) {
-  if (frag === undefined || frag == null) {
-      return;
-  }
-  let tokenmatch = null;
-  let statematch = null;
-  if (!(frag === undefined) && !(frag == null)) {
-    tokenmatch = frag.match(/access_token\=([\S\s]*?)[&|$]/);
-    statematch = frag.match(/state\=([\S\s]*?)[&|$]/);
-  }
-  if (tokenmatch == null || statematch == null) {
-    return;
-  }
-
-  let accesstoken = tokenmatch[1];
-  let state = statematch[1];
-  this.router.navigate(['/']);
-
-  //Verify that the state matched the nonce we used when initiating login
-  let tuple = JSON.parse(localStorage.getItem('authservice'));
-  if (tuple[1] != state) {
-    return
-  }
-
-  this.token.next(new AuthToken(tokenmatch[1],tuple[0]));
-
-  // TODO fire off a query to the auth service to get the associated sites
-
-
-}
-
-getCert(token: AuthToken) {
-   console.log('in getCert');
-   if (token.token === undefined || token.token === '' || token.token == null) {
-     console.log('no authtoken available, we wont be able to generate a cert');
-     console.log(token);
-     return
-   }
-   console.log("Generating key matter");
-
-   let starttime = new Date();
-   let newkeypair = keypair();
-   let publicKey = forge.pki.publicKeyFromPem(newkeypair.public);
-   let sshpub = forge.ssh.publicKeyToOpenSSH(publicKey, 'sv2@monash.edu');
-   let endtime = new Date();
-   console.log("generating new keys took", endtime.valueOf() - starttime.valueOf())
-
-   let headers = new HttpHeaders();
-   let options = { headers: headers, withCredentials: true};
-
-   let data = {'token': token.token, 'pubkey': sshpub, 'signing_url': token.authservice.sign};
-
-   this.busy.next(true);
-   this.statusMsg.next("Generating Certificates ...")
-   console.log('posting to getcert',this.Base);
-   this.http.post<any>(this.Base+'/getcert',data, options)
-                      .pipe(catchError(this.handleError('getCert',[])))
-                      .subscribe(resp => this.makeKeyCert(newkeypair.private, resp, token.authservice))
-  console.log('getcert complete');
-}
-
-makeKeyCert(key: string, resp, authservice: AuthService) {
-  let keyCert = new KeyCert()
-  keyCert.key = key;
-  keyCert.cert = resp['cert'];
-  keyCert.authservice = authservice;
-  console.log('updating keycert',keyCert);
-  this.keyCert.next(keyCert);
-}
-
 private sshAdd(keyCert: KeyCert) {
-
-  console.log('in sshAdd');
   if (keyCert.key == undefined) {
     return;
   }
@@ -265,13 +171,10 @@ private sshAdd(keyCert: KeyCert) {
 
   this.statusMsg.next("Authorising ...")
   let data = {'key': keyCert.key, 'cert': keyCert.cert};
-  console.log('adding key',data);
-
   this.http.post<any>(this.Base+'/sshagent',data,options)
                       .pipe(catchError(this.handleError('storeCert',[])))
                       .subscribe(resp => this.getIdentities(),
                                 error => this.httperror(error));
-  console.log('sshAdd complete');
 }
 
 private getIdentities() {
@@ -282,12 +185,10 @@ private getIdentities() {
   this.http.get<any>(this.Base+'/sshagent',options)
                     .pipe(catchError(this.handleError('getIdentities',[])))
                     .subscribe(resp => this.updateIdentities(resp));
-  console.log('getIdentities complete');
 }
 
 private killAgent() {
   this.statusMsg.next("Updating the list of available accounts")
-  this
   let headers = new HttpHeaders();
   let options = { headers: headers, withCredentials: true};
   this.http.delete<any>(this.Base+'/sshagent',options)
@@ -298,11 +199,8 @@ private killAgent() {
 private updateIdentities(resp) {
   //TODO Each cert as the signing CA parameter. Use this to find the compute sites
   // rather than just assuming sites[0]
-  console.log('attempting to update our local list of identities');
   let certcontents = resp;
-  console.log(certcontents);
   let identities = [];
-  console.log('identities updated');
   let sites = this.computesite.getComputeSites();
   let idsShort = []
   for (let i in certcontents) {
@@ -311,52 +209,17 @@ private updateIdentities(resp) {
   this.identities.next(identities);
   if (identities.length == 0) {
     this.statusMsg.next(null);
-    console.log('local identities, none available');
     return;
   }
-  console.log('local identities updated');
   this.startPolling();
 }
 
-private startPolling() {
-  console.log('in start polling');
-  this.statusMsg.next(null);
-  if (!(this.timerSubscription === null)) {
-    console.log('unsubscribing timer');
-    this.timerSubscription.unsubscribe()
-  }
-  console.log('creating timer to poll for jobs');
-  // this.timerSubscription = timer(100,5000).subscribe(() => this.getJobs());
-
-  this.timerSubscription = timer(5000).pipe(repeat()).subscribe(() => this.getJobs());
-  this.getJobs();
-  console.log('start polling complete');
-}
-
-public login() {
-  let redirect_uri = window.location.origin+this.locationStrategy.getBaseHref()+"sshauthz_callback";
-  let nonce="asdfzxcv";
-  let authservice = new AuthService();
-  authservice.base = "https://autht.massive.org.au/hpcid/";
-  authservice.authorise = authservice.base + 'oauth/authorize';
-  authservice.sign = authservice.base + 'api/v1/sign_key';
-  authservice.client_id = "86c06039-e589-4b39-9d1f-9eca431be18f";
-  localStorage.setItem('authservice', JSON.stringify([authservice,nonce]));
-  window.location.assign(authservice.authorise+"?response_type=token&redirect_uri="+redirect_uri+"&state="+nonce+"&client_id="+authservice.client_id);
-}
-
 public logout(): Boolean {
-  this.token = null;
-  this.sshcert = null;
   this.statusMsg.next(null);
   this.killAgent();
-  // if (!(this.timerSubscription === null)) {
-  //   this.timerSubscription.unsubscribe()
-  // }
   return true;
 }
 
-
 public getstatusMsgSubject(): BehaviorSubject<any> {
   return this.statusMsg;
 }