user.service.ts 8.24 KB
Newer Older
Lukas Burgey's avatar
Lukas Burgey committed
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';
Lukas Burgey's avatar
Lukas Burgey committed
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

Lukas Burgey's avatar
Lukas Burgey committed
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
  public messages: string[];
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
    this.messages = [];
Lukas Burgey's avatar
Lukas Burgey committed
37 38
  }

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

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

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

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

  private _handleValueChange(newData: any) {
Lukas Burgey's avatar
Lukas Burgey committed
78
  }
79

Lukas Burgey's avatar
Lukas Burgey committed
80 81
  private _updateUserValues(newUser: any) {
    this.user = newUser;
82 83 84 85 86
    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
87
        this.sshKeyData = undefined;
88 89 90 91
      }

      // build userInfoData
      const userInfoList = [];
Lukas Burgey's avatar
Lukas Burgey committed
92 93 94
      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
95
        }
96 97 98 99
      }
      this.userInfoData = new MatTableDataSource(userInfoList);

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

  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);
110

Lukas Burgey's avatar
Lukas Burgey committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124
    // 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) {
125 126 127
      this.snackBar.open('Logged in');
      this.connectLiveUpdates()
    }
Lukas Burgey's avatar
Lukas Burgey committed
128 129 130 131 132 133 134
    if (logout) {
      this.snackBar.open('Logged out');
      this._stompService.disconnect();

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

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

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

155 156
  public login(idp: IdP) {
    this.setIdPPreference(idp);
157
    window.location.href = 'https://hdf-portal.data.kit.edu/backend/auth/v1/request';
158 159
  }

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

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

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

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

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

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

  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();
      }
    );
  }
254

Lukas Burgey's avatar
Lukas Burgey committed
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
  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/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
      debug: false,
    };
    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;
    }).subscribe((body: any) => {
      let json = JSON.parse(body);
      if (json.message && json.message != '') {
        this.snackBar.open(json.message);
        this.messages.push(json.message);
      }
      if (json.user_state) {
        this._updateUserValues(json.user_state);
      }
    });
  }

Lukas Burgey's avatar
Lukas Burgey committed
307 308
  public taskInProgress(site, service): boolean {
    if (site && service) {
309

Lukas Burgey's avatar
Lukas Burgey committed
310 311 312 313
      for (const item of this.user.deployment_task_items){
        if (item.site.id == site.id && item.service.id == service.id) {
          return true;
        }
Lukas Burgey's avatar
Lukas Burgey committed
314
      }
Lukas Burgey's avatar
Lukas Burgey committed
315 316
    }
    return false;
317
  }
318 319 320 321 322 323 324 325 326 327 328 329

  public taskState(site, service): string {
    if (site && service) {

      for (const item of this.user.deployment_task_items){
        if (item.site.id == site.id && item.service.id == service.id) {
          return item.state;
        }
      }
    }
    return "done";
  }
Lukas Burgey's avatar
Lukas Burgey committed
330
}