user.service.ts 7.91 KB
Newer Older
Lukas Burgey's avatar
Lukas Burgey committed
1

Lukas Burgey's avatar
Lukas Burgey committed
2
import {of as observableOf, Observable} from 'rxjs';
Lukas Burgey's avatar
Lukas Burgey committed
3

Lukas Burgey's avatar
Lukas Burgey committed
4 5 6 7 8 9 10 11 12 13 14
import {catchError, map} from 'rxjs/operators';
import {Injectable} from '@angular/core';
import {HttpClient, HttpErrorResponse} from '@angular/common/http';




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

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

Lukas Burgey's avatar
Lukas Burgey committed
18 19
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
20

Lukas Burgey's avatar
Lukas Burgey committed
21 22 23 24 25 26 27

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


  constructor(
    public cookieService: CookieService,
    public http: HttpClient,
    public snackBar: SnackBarService,
36
    private _stompService: StompRService,
Lukas Burgey's avatar
Lukas Burgey committed
37
  ) {
Lukas Burgey's avatar
Lukas Burgey committed
38
    this.update();
Lukas Burgey's avatar
Lukas Burgey committed
39
    this.messages = [];
Lukas Burgey's avatar
Lukas Burgey committed
40 41
  }

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

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

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

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

Lukas Burgey's avatar
Lukas Burgey committed
155 156 157 158 159 160 161 162 163 164 165 166 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 200 201 202 203 204 205 206
  private 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();
  }

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

    subscription.pipe(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);
      }
    });
  }

207 208
  public login(idp: IdP) {
    this.setIdPPreference(idp);
Lukas Burgey's avatar
Lukas Burgey committed
209
    window.location.href = 'https://hdf-portal.data.kit.edu/backend/auth/v1/request/';
210 211
  }

Lukas Burgey's avatar
Lukas Burgey committed
212
  public logout() {
Lukas Burgey's avatar
Lukas Burgey committed
213
    this.http.post('/backend/auth/v1/logout/', {}).subscribe(
Lukas Burgey's avatar
Lukas Burgey committed
214
      data => {
Lukas Burgey's avatar
Lukas Burgey committed
215
        this.updateData(data);
Lukas Burgey's avatar
Lukas Burgey committed
216 217 218 219
      }
    );
  }

220
  public addSshKey(key: NewSSHKey) {
Lukas Burgey's avatar
Lukas Burgey committed
221 222 223 224 225 226
    const body = {
      'type': 'add',
      'key': key,
    };
    return this.http.post('/backend/api/sshkey/', body).subscribe(
      data => {
227
        this.updateData(data);
Lukas Burgey's avatar
Lukas Burgey committed
228 229 230 231
      },
      (err) => {
        this.snackBar.open('Error uploading key');
        console.log(err);
232
        this.update();
Lukas Burgey's avatar
Lukas Burgey committed
233 234 235 236
      }
    );
  }

237
  public removeSshKey(key: SSHKey) {
Lukas Burgey's avatar
Lukas Burgey committed
238 239
    const body = {
      'type': 'remove',
240
      'id': key.id,
Lukas Burgey's avatar
Lukas Burgey committed
241 242 243
    };
    return this.http.post('/backend/api/sshkey/', body).subscribe(
      (data) => {
244
        this.updateData(data);
Lukas Burgey's avatar
Lukas Burgey committed
245 246 247 248
      },
      (err) => {
        this.snackBar.open('Error deleting key');
        console.log(err);
249 250 251 252 253
        this.update();
      }
    );
  }

254
  public addDeployment(service: Service, key: SSHKey) {
255 256
    const body = {
      'type': 'add',
257 258
      'key': key.id,
      'service': service.id,
259 260 261
    };
    return this.http.post('/backend/api/deployments/', body).subscribe(
      (data) => {
Lukas Burgey's avatar
Lukas Burgey committed
262
        //this.snackBar.open('Deployed key ' + key.name);
263 264 265
        this.updateData(data);
      },
      (err) => {
266
        this.snackBar.open('Error deploying key ' + key.name);
267 268 269 270 271 272
        console.log(err);
        this.update();
      }
    );
  }

273
  public removeDeployment(service: Service, key: SSHKey) {
274 275
    const body = {
      'type': 'remove',
276 277
      'key': key.id,
      'service':  service.id,
278
    };
279

280 281
    return this.http.post('/backend/api/deployments/', body).subscribe(
      (data) => {
Lukas Burgey's avatar
Lukas Burgey committed
282
        //this.snackBar.open('Withdrew key ' + key.name);
283 284 285
        this.updateData(data);
      },
      (err) => {
286
        this.snackBar.open('Error withdrawing key ' + key.name);
287 288
        console.log(err);
        this.update();
Lukas Burgey's avatar
Lukas Burgey committed
289 290 291
      }
    );
  }
Lukas Burgey's avatar
Lukas Burgey committed
292 293 294 295 296 297 298 299 300 301 302 303 304 305

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

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
  }
Lukas Burgey's avatar
Lukas Burgey committed
318
}