user.service.ts 8.62 KB
Newer Older
1 2
import {Injectable} from '@angular/core';
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
Lukas Burgey's avatar
Lukas Burgey committed
3 4 5 6
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';
7 8 9 10 11

import {CookieService} from 'ngx-cookie-service';
import {MatTableDataSource} from '@angular/material';

import {SnackBarService} from './snackbar.service';
12 13
import {StompConfig, StompRService} from '@stomp/ng2-stompjs';
import {Message} from '@stomp/stompjs';
Lukas Burgey's avatar
Lukas Burgey committed
14

15
import {environment} from '../environments/environment';
Lukas Burgey's avatar
Lukas Burgey committed
16
import * as t from './types/types.module';
Lukas Burgey's avatar
Lukas Burgey committed
17

Lukas Burgey's avatar
Lukas Burgey committed
18 19 20

@Injectable()
export class UserService {
Lukas Burgey's avatar
Lukas Burgey committed
21 22 23 24
  private _loggedIn: boolean = false;

  public user: t.User;
  public userState: t.UserState;
25
  public messages: string[] = [];
Lukas Burgey's avatar
Lukas Burgey committed
26
  public services: t.Service[];
Lukas Burgey's avatar
Lukas Burgey committed
27 28 29 30 31 32


  constructor(
    public cookieService: CookieService,
    public http: HttpClient,
    public snackBar: SnackBarService,
33
    private _stompService: StompRService,
Lukas Burgey's avatar
Lukas Burgey committed
34
  ) {
Lukas Burgey's avatar
Lukas Burgey committed
35
    this.update();
Lukas Burgey's avatar
Lukas Burgey committed
36 37
  }

Lukas Burgey's avatar
Lukas Burgey committed
38 39 40 41 42
  // PRIVATE API
  private initStomp() {
    // handle with care
    let login = this.user.id
    let passcode = this.cookieService.get('sessionid');
Lukas Burgey's avatar
Lukas Burgey committed
43

Lukas Burgey's avatar
Lukas Burgey committed
44 45 46
    const stompConfig: StompConfig = {
      // Which server?
      url: 'wss://hdf-portal.data.kit.edu/ws',
47

Lukas Burgey's avatar
Lukas Burgey committed
48 49 50 51 52 53
      // Headers
      // Typical keys: login, passcode, host
      headers: {
        login: 'webpage-client:' + login,
        passcode: passcode,
      },
Lukas Burgey's avatar
Lukas Burgey committed
54

Lukas Burgey's avatar
Lukas Burgey committed
55 56 57 58 59 60 61 62
      // How often to heartbeat?
      // Interval in milliseconds, set to 0 to disable
      heartbeat_in: 0, // Typical value 0 - disabled
      heartbeat_out: 20000, // Typical value 20000 - every 20 seconds
      // Wait in milliseconds before attempting auto reconnect
      // Set to 0 to disable
      // Typical value 5000 (5 seconds)
      reconnect_delay: 5000,
63

Lukas Burgey's avatar
Lukas Burgey committed
64 65 66 67 68
      // Will log diagnostics on console
      debug: false,
    };
    this._stompService.config = stompConfig;
    this._stompService.initAndConnect();
Lukas Burgey's avatar
Lukas Burgey committed
69 70
  }

Lukas Burgey's avatar
Lukas Burgey committed
71 72 73 74 75
  private connectLiveUpdates() {
    this.initStomp();
    let subscription = this._stompService.subscribe(
      '/exchange/update/' + this.user.id.toString()
    );
76

Lukas Burgey's avatar
Lukas Burgey committed
77 78 79 80 81 82 83
    subscription.map((message: Message) => {
      return message.body;
    }).subscribe((body: any) => {
      let json = JSON.parse(body);
      if (json.message && json.message != '') {
        this.snackBar.open(json.message);
        this.messages.push(json.message);
84
      }
Lukas Burgey's avatar
Lukas Burgey committed
85 86
      if (json.user_state) {
        this.updateUserState(json.user_state);
87
      }
Lukas Burgey's avatar
Lukas Burgey committed
88 89
    });
  }
90

Lukas Burgey's avatar
Lukas Burgey committed
91 92
  private updateUser(newUser: t.User) {
    this.user = newUser;
93 94
  }

Lukas Burgey's avatar
Lukas Burgey committed
95 96 97
  private updateUserState(newState: t.UserState) {
      // did a login occur?
    let login = (!this._loggedIn && newState);
98
    // did a logout occur?
Lukas Burgey's avatar
Lukas Burgey committed
99
    let logout = (this._loggedIn && !newState);
100 101 102

    // -- Value updating --
    if (login) {
Lukas Burgey's avatar
Lukas Burgey committed
103
      this._loggedIn = true;
104 105 106
      this.snackBar.open('Logged in');
      this.connectLiveUpdates()
    }
107
    if (logout) {
Lukas Burgey's avatar
Lukas Burgey committed
108
      this._loggedIn = false;
109 110
      this.snackBar.open('Logged out');
      this._stompService.disconnect();
Lukas Burgey's avatar
Lukas Burgey committed
111 112 113 114 115 116 117 118 119
    }

    this.userState = newState;
  }

  private stateAPIUpdate(update: t.StateAPIResult) {
    this.updateUser(update.user)
    this.updateUserState(update.user_state);
    this.services = update.services;
120

Lukas Burgey's avatar
Lukas Burgey committed
121 122 123
    // report an occured error
    if (update.error) {
      this.snackBar.open(update.error);
124
    }
Lukas Burgey's avatar
Lukas Burgey committed
125 126
  }

Lukas Burgey's avatar
Lukas Burgey committed
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
  private setIdPPreference(idp: t.IdP) {
    this.cookieService.set(environment.idpCookieName, String(idp.id));
  }

  // PUBLIC API
  public userInfo(): MatTableDataSource<any> {
      const userInfoList = [];
      for (const key in this.user.userinfo) {
        if (this.user.userinfo.hasOwnProperty(key)) {
          userInfoList.push({name: key, info: this.user.userinfo[key]});
        }
      }
      return new MatTableDataSource(userInfoList);
  }

  public sshKeyTable(): MatTableDataSource<any> {
      return new MatTableDataSource(this.user.ssh_keys);
  }

  public loggedIn():boolean {
    if (this.userState) {
      return true;
    }
    return false;
  }

  public update() {
Lukas Burgey's avatar
Lukas Burgey committed
154
    this.http
155
      .get('/backend/api/state')
Lukas Burgey's avatar
Lukas Burgey committed
156
      .subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
157 158
        (data: t.StateAPIResult) => {
          this.stateAPIUpdate(data);
Lukas Burgey's avatar
Lukas Burgey committed
159 160 161 162 163 164 165 166
        },
        (err: HttpErrorResponse) => {
          console.log('Error', err);
          this.snackBar.open('Error receiving data from the server');
        }
      );
  }

Lukas Burgey's avatar
Lukas Burgey committed
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
  public errorHandler(error: any): void {
    if (error.status === 500) {
      this.snackBar.open('Server Error');
    }
  }

  public getIdPPreference(): Observable<t.AllAuthInfo> {
    let idpID = Number(this.cookieService.get(environment.idpCookieName));

    return this.http.get('/backend/auth/v1/info').map(
      (authInfo: t.AuthInfo) => {
        let selected = authInfo.idps[1];

        if (!idpID) {
          idpID = authInfo.default;
        }
        for (const idp of authInfo.idps) {
          if (idp.id === idpID) {
            selected = idp;
          }
        }
        return {
          idps: authInfo.idps,
          selected: selected,
        };
      }
    ).catch(
      (error: any) => {
        this.errorHandler(error);
        return Observable.of(null);
      }
    );
  }
Lukas Burgey's avatar
Lukas Burgey committed
200

Lukas Burgey's avatar
Lukas Burgey committed
201
  public login(idp: t.IdP) {
202
    this.setIdPPreference(idp);
203
    window.location.href = 'https://hdf-portal.data.kit.edu/backend/auth/v1/request';
204 205
  }

Lukas Burgey's avatar
Lukas Burgey committed
206
  public logout() {
207
    this.http.post('/backend/auth/v1/logout', {}).subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
208 209
      (data: t.StateAPIResult) => {
        this.stateAPIUpdate(data);
Lukas Burgey's avatar
Lukas Burgey committed
210 211 212 213
      }
    );
  }

Lukas Burgey's avatar
Lukas Burgey committed
214
  public addSshKey(key: t.NewSSHKey) {
Lukas Burgey's avatar
Lukas Burgey committed
215 216 217 218
    const body = {
      'type': 'add',
      'key': key,
    };
219
    return this.http.post('/backend/api/sshkey', body).subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
220 221
      (data: t.UserState) => {
        this.updateUserState(data);
Lukas Burgey's avatar
Lukas Burgey committed
222 223 224 225
      },
      (err) => {
        this.snackBar.open('Error uploading key');
        console.log(err);
Lukas Burgey's avatar
Lukas Burgey committed
226
        this.update();
Lukas Burgey's avatar
Lukas Burgey committed
227 228 229 230
      }
    );
  }

Lukas Burgey's avatar
Lukas Burgey committed
231
  public removeSshKey(key: t.SSHKey) {
Lukas Burgey's avatar
Lukas Burgey committed
232 233
    const body = {
      'type': 'remove',
234
      'id': key.id,
Lukas Burgey's avatar
Lukas Burgey committed
235
    };
236
    return this.http.post('/backend/api/sshkey', body).subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
237 238
      (data: t.UserState) => {
        this.updateUserState(data);
Lukas Burgey's avatar
Lukas Burgey committed
239 240 241 242
      },
      (err) => {
        this.snackBar.open('Error deleting key');
        console.log(err);
Lukas Burgey's avatar
Lukas Burgey committed
243
        this.update();
244 245 246 247
      }
    );
  }

Lukas Burgey's avatar
Lukas Burgey committed
248
  public addDeployment(service: t.Service, key: t.SSHKey) {
249 250
    const body = {
      'type': 'add',
251 252
      'key': key.id,
      'service': service.id,
253
    };
254
    return this.http.post('/backend/api/deployments', body).subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
255
      (data: t.UserState) => {
256
        //this.snackBar.open('Deployed key ' + key.name);
Lukas Burgey's avatar
Lukas Burgey committed
257
        this.updateUserState(data);
258 259
      },
      (err) => {
260
        this.snackBar.open('Error deploying key ' + key.name);
261
        console.log(err);
Lukas Burgey's avatar
Lukas Burgey committed
262
        this.update();
263 264 265 266
      }
    );
  }

Lukas Burgey's avatar
Lukas Burgey committed
267
  public removeDeployment(service: t.Service, key: t.SSHKey) {
268 269
    const body = {
      'type': 'remove',
270 271
      'key': key.id,
      'service':  service.id,
272
    };
273

274
    return this.http.post('/backend/api/deployments', body).subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
275
      (data: t.UserState) => {
276
        //this.snackBar.open('Withdrew key ' + key.name);
Lukas Burgey's avatar
Lukas Burgey committed
277
        this.updateUserState(data);
278 279
      },
      (err) => {
280
        this.snackBar.open('Error withdrawing key ' + key.name);
281
        console.log(err);
Lukas Burgey's avatar
Lukas Burgey committed
282
        this.update();
Lukas Burgey's avatar
Lukas Burgey committed
283 284 285
      }
    );
  }
Lukas Burgey's avatar
Lukas Burgey committed
286

Lukas Burgey's avatar
Lukas Burgey committed
287
  public sentQuestionnaire(taskItemID: number, answers: any) {
288
    return this.http.post('/backend/api/questionnaire?id='+String(taskItemID), answers).subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
289
      (data: t.UserState) => {
Lukas Burgey's avatar
Lukas Burgey committed
290 291
        this.snackBar.open('Uploaded questionnaire');
        //this.snackBar.open('Deployed key ' + key.name);
Lukas Burgey's avatar
Lukas Burgey committed
292
        this.updateUserState(data);
Lukas Burgey's avatar
Lukas Burgey committed
293 294 295 296
      },
      (err) => {
        this.snackBar.open('Error uploading questionnaire');
        console.log(err);
Lukas Burgey's avatar
Lukas Burgey committed
297
        this.update();
Lukas Burgey's avatar
Lukas Burgey committed
298 299 300 301
      }
    );
  }

Lukas Burgey's avatar
Lukas Burgey committed
302 303
  public deleteUser() {
    return this.http.delete('/backend/api/delete_user/').subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
304
      (data: t.UserState) => {
Lukas Burgey's avatar
Lukas Burgey committed
305
        this.snackBar.open('Deleted user from server');
Lukas Burgey's avatar
Lukas Burgey committed
306
        this.updateUserState(data);
Lukas Burgey's avatar
Lukas Burgey committed
307 308 309 310
      },
      (err) => {
        this.snackBar.open('Error deleting user from server');
        console.log(err);
Lukas Burgey's avatar
Lukas Burgey committed
311
        this.update();
Lukas Burgey's avatar
Lukas Burgey committed
312 313 314
      }
    );
  }
315

Lukas Burgey's avatar
Lukas Burgey committed
316 317 318
  public taskItem(site: t.Site, service: t.Service, key: t.SSHKeyRef): t.DeploymentStateItem {
    if (this.userState.deployment_state_items && site && service && key) {
      for (const item of this.userState.deployment_state_items){
319 320 321
        if (item.site.id == site.id
          && item.key.id == key.id
          && item.service.id == service.id) {
Lukas Burgey's avatar
Lukas Burgey committed
322
          return item;
323
        }
324
      }
325
    }
Lukas Burgey's avatar
Lukas Burgey committed
326
    return null;
327
  }
328

Lukas Burgey's avatar
Lukas Burgey committed
329
  public taskState(site: t.Site, service: t.Service, key: t.SSHKeyRef): string {
330
    let item = this.taskItem(site, service, key);
Lukas Burgey's avatar
Lukas Burgey committed
331 332
    if (item !== null) {
      return item.state;
333
    }
334
    return "";
335
  }
Lukas Burgey's avatar
Lukas Burgey committed
336
}