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
}