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
}