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

8 9
import {CookieService } from 'ngx-cookie-service';
import {MatTableDataSource } from '@angular/material';
Lukas Burgey's avatar
Lukas Burgey committed
10

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

15 16
import {environment } from '../environments/environment';
import {IdP, User, Service, AuthInfo, AllAuthInfo, UserState, SSHKey, NewSSHKey } from './types/types.module';
Lukas Burgey's avatar
Lukas Burgey committed
17

Lukas Burgey's avatar
Lukas Burgey committed
18 19 20 21 22 23 24

@Injectable()
export class UserService {
  public loggedIn = false;
  public user: User;
  public sshKeyData: MatTableDataSource<any>;
  public userInfoData: MatTableDataSource<any>;
25
  public services: Service[];
Lukas Burgey's avatar
Lukas Burgey committed
26 27 28 29 30 31


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

37 38
  public setIdPPreference(idp: IdP) {
    this.cookieService.set(environment.idpCookieName, String(idp.id));
Lukas Burgey's avatar
Lukas Burgey committed
39 40
  }

41 42 43 44 45 46
  public errorHandler(error: any): void {
    if (error.status === 500) {
      this.snackBar.open('Server Error');
    }
  }

47 48
  public getIdPPreference(): Observable<AllAuthInfo> {
    let idpID = Number(this.cookieService.get(environment.idpCookieName));
Lukas Burgey's avatar
Lukas Burgey committed
49

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
    return this.http.get('/backend/auth/v1/info/').map(
      (authInfo: 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,
        };
      }
67 68 69 70 71
    ).catch(
      (error: any) => {
        this.errorHandler(error);
        return Observable.of(null);
      }
72
    );
Lukas Burgey's avatar
Lukas Burgey committed
73 74
  }

Lukas Burgey's avatar
Lukas Burgey committed
75 76
  private _handleValueChange(newData: any) {
  }
77

Lukas Burgey's avatar
Lukas Burgey committed
78 79
  private _updateUserValues(newUser: any) {
    this.user = newUser;
80 81 82 83 84
    if (this.user) {
      // build sshKeyData
      if ('ssh_keys' in this.user) {
        this.sshKeyData = new MatTableDataSource(this.user.ssh_keys);
      } else {
Lukas Burgey's avatar
Lukas Burgey committed
85
        this.sshKeyData = undefined;
86 87 88 89
      }

      // build userInfoData
      const userInfoList = [];
Lukas Burgey's avatar
Lukas Burgey committed
90 91 92
      for (const key in this.user.userinfo) {
        if (this.user.userinfo.hasOwnProperty(key)) {
          userInfoList.push({name: key, info: this.user.userinfo[key]});
Lukas Burgey's avatar
Lukas Burgey committed
93
        }
94 95 96 97
      }
      this.userInfoData = new MatTableDataSource(userInfoList);

    } else {
Lukas Burgey's avatar
Lukas Burgey committed
98 99
      this.sshKeyData = undefined;
      this.userInfoData = undefined;
100
    }
Lukas Burgey's avatar
Lukas Burgey committed
101 102 103 104 105 106 107
  }

  public updateData(newData: any) {
    // did a login occur?
    let login = (!this.loggedIn && newData.logged_in);
    // did a logout occur?
    let logout = (this.loggedIn && !newData.logged_in);
108

Lukas Burgey's avatar
Lukas Burgey committed
109 110 111 112 113 114 115 116 117 118 119 120 121 122
    // report an occured error
    if (newData.error) {
      this.snackBar.open(newData.error);
    }

    // -- Value updating --
    this.loggedIn = newData.logged_in;
    // this check is needed because the accordeon collapses if we overwrite the list
    if (!this.services) {
      this.services = newData.services;
    }
    this._updateUserValues(newData.user);

    if (login) {
123 124 125
      this.snackBar.open('Logged in');
      this.connectLiveUpdates()
    }
Lukas Burgey's avatar
Lukas Burgey committed
126 127 128 129 130 131 132
    if (logout) {
      this.snackBar.open('Logged out');
      this._stompService.disconnect();

      // reset some attributes
      this.services = [];
    }
Lukas Burgey's avatar
Lukas Burgey committed
133 134 135
  }

  public updateState() {
Lukas Burgey's avatar
Lukas Burgey committed
136 137 138
    this.http
      .get('/backend/api/state/')
      .subscribe(
139
        (data: UserState) => {
140
          this.updateData(data);
Lukas Burgey's avatar
Lukas Burgey committed
141 142 143 144 145 146 147 148
        },
        (err: HttpErrorResponse) => {
          console.log('Error', err);
          this.snackBar.open('Error receiving data from the server');
        }
      );
  }

Lukas Burgey's avatar
Lukas Burgey committed
149 150 151 152
  public update() {
    this.updateState();
  }

153 154
  public login(idp: IdP) {
    this.setIdPPreference(idp);
Lukas Burgey's avatar
Lukas Burgey committed
155
    window.location.href = 'https://hdf-portal.data.kit.edu/backend/auth/v1/request/';
156 157
  }

Lukas Burgey's avatar
Lukas Burgey committed
158
  public logout() {
Lukas Burgey's avatar
Lukas Burgey committed
159
    this.http.post('/backend/auth/v1/logout/', {}).subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
160
      data => {
Lukas Burgey's avatar
Lukas Burgey committed
161
        this.updateData(data);
Lukas Burgey's avatar
Lukas Burgey committed
162 163 164 165
      }
    );
  }

166
  public addSshKey(key: NewSSHKey) {
Lukas Burgey's avatar
Lukas Burgey committed
167 168 169 170 171 172
    const body = {
      'type': 'add',
      'key': key,
    };
    return this.http.post('/backend/api/sshkey/', body).subscribe(
      data => {
173
        this.updateData(data);
Lukas Burgey's avatar
Lukas Burgey committed
174 175 176 177
      },
      (err) => {
        this.snackBar.open('Error uploading key');
        console.log(err);
178
        this.update();
Lukas Burgey's avatar
Lukas Burgey committed
179 180 181 182
      }
    );
  }

183
  public removeSshKey(key: SSHKey) {
Lukas Burgey's avatar
Lukas Burgey committed
184 185
    const body = {
      'type': 'remove',
186
      'id': key.id,
Lukas Burgey's avatar
Lukas Burgey committed
187 188 189
    };
    return this.http.post('/backend/api/sshkey/', body).subscribe(
      (data) => {
190
        this.updateData(data);
Lukas Burgey's avatar
Lukas Burgey committed
191 192 193 194
      },
      (err) => {
        this.snackBar.open('Error deleting key');
        console.log(err);
195 196 197 198 199
        this.update();
      }
    );
  }

200
  public addDeployment(service: Service, key: SSHKey) {
201 202
    const body = {
      'type': 'add',
203 204
      'key': key.id,
      'service': service.id,
205 206 207
    };
    return this.http.post('/backend/api/deployments/', body).subscribe(
      (data) => {
Lukas Burgey's avatar
Lukas Burgey committed
208
        //this.snackBar.open('Deployed key ' + key.name);
209 210 211
        this.updateData(data);
      },
      (err) => {
212
        this.snackBar.open('Error deploying key ' + key.name);
213 214 215 216 217 218
        console.log(err);
        this.update();
      }
    );
  }

219
  public removeDeployment(service: Service, key: SSHKey) {
220 221
    const body = {
      'type': 'remove',
222 223
      'key': key.id,
      'service':  service.id,
224
    };
225

226 227
    return this.http.post('/backend/api/deployments/', body).subscribe(
      (data) => {
Lukas Burgey's avatar
Lukas Burgey committed
228
        //this.snackBar.open('Withdrew key ' + key.name);
229 230 231
        this.updateData(data);
      },
      (err) => {
232
        this.snackBar.open('Error withdrawing key ' + key.name);
233 234
        console.log(err);
        this.update();
Lukas Burgey's avatar
Lukas Burgey committed
235 236 237
      }
    );
  }
Lukas Burgey's avatar
Lukas Burgey committed
238 239 240 241 242 243 244 245 246 247 248 249 250 251

  public deleteUser() {
    return this.http.delete('/backend/api/delete_user/').subscribe(
      (data) => {
        this.snackBar.open('Deleted user from server');
        this.updateData(data);
      },
      (err) => {
        this.snackBar.open('Error deleting user from server');
        console.log(err);
        this.update();
      }
    );
  }
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278

  public initStomp() {
    // handle with care
    let login = this.user.id
    let passcode = this.cookieService.get('sessionid');

    const stompConfig: StompConfig = {
      // Which server?
      url: 'wss://hdf-portal.data.kit.edu:15671/ws',

      // Headers
      // Typical keys: login, passcode, host
      headers: {
        login: 'webpage-client:' + login,
        passcode: passcode,
      },

      // 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,

      // Will log diagnostics on console
Lukas Burgey's avatar
Lukas Burgey committed
279
      debug: false,
280 281 282 283 284 285 286 287 288 289 290 291 292
    };
    this._stompService.config = stompConfig;
    this._stompService.initAndConnect();
  }

  public connectLiveUpdates() {
    this.initStomp();
    let subscription = this._stompService.subscribe(
      '/exchange/update/' + this.user.id.toString()
    );

    subscription.map((message: Message) => {
      return message.body;
Lukas Burgey's avatar
Lukas Burgey committed
293 294 295 296 297 298 299 300
    }).subscribe((body: any) => {
      let json = JSON.parse(body);
      if (json.message && json.message != '') {
        this.snackBar.open( json.message);
      }
      if (json.user_state) {
        this._updateUserValues(json.user_state);
      }
301 302
    });
  }
Lukas Burgey's avatar
Lukas Burgey committed
303
}