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
}