From 71077413b7735170aec0e05700bbe8e0b09131ef Mon Sep 17 00:00:00 2001 From: piotrpekala7 <31202938+piotrpekala7@users.noreply.github.com> Date: Thu, 29 Apr 2021 17:32:53 +0200 Subject: [PATCH] Login component added --- src/app/app-routing.module.ts | 2 + src/app/app.module.ts | 4 ++ src/app/components/login/login.component.html | 30 +++++++++ src/app/components/login/login.component.scss | 31 +++++++++ .../components/login/login.component.spec.ts | 0 src/app/components/login/login.component.ts | 66 +++++++++++++++++++ .../components/template/template.component.ts | 2 +- src/app/guards/login-guard.ts | 0 .../default-layout.component.html | 2 +- src/app/models/authResponse.ts | 4 ++ src/app/models/server.ts | 1 + src/app/services/http-server.service.ts | 7 +- src/app/services/login.service.ts | 23 +++++++ src/app/services/symbol.service.ts | 5 ++ 14 files changed, 171 insertions(+), 6 deletions(-) create mode 100644 src/app/components/login/login.component.html create mode 100644 src/app/components/login/login.component.scss create mode 100644 src/app/components/login/login.component.spec.ts create mode 100644 src/app/components/login/login.component.ts create mode 100644 src/app/guards/login-guard.ts create mode 100644 src/app/models/authResponse.ts create mode 100644 src/app/services/login.service.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index fab73cbf..eeba6e83 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -5,6 +5,7 @@ import { DirectLinkComponent } from './components/direct-link/direct-link.compon import { HelpComponent } from './components/help/help.component'; import { ReportIssueComponent } from './components/help/report-issue/report-issue.component'; import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component'; +import { LoginComponent } from './components/login/login.component'; import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component'; import { BuiltInPreferencesComponent } from './components/preferences/built-in/built-in-preferences.component'; import { CloudNodesAddTemplateComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component'; @@ -63,6 +64,7 @@ const routes: Routes = [ { path: '', redirectTo: 'servers', pathMatch: 'full' }, { path: 'servers', component: ServersComponent }, { path: 'bundled', component: BundledServerFinderComponent }, + { path: 'server/:server_id/login', component: LoginComponent }, { path: 'server/:server_id/projects', component: ProjectsComponent, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b452dc4a..9a5b8d01 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -269,11 +269,14 @@ import { VpcsService } from './services/vpcs.service'; import { NonNegativeValidator } from './validators/non-negative-validator'; import { RotationValidator } from './validators/rotation-validator'; import { MarkedDirective } from './directives/marked.directive'; +import { LoginComponent } from './components/login/login.component'; +import { LoginService } from './services/login.service'; @NgModule({ declarations: [ AppComponent, ProjectMapComponent, + LoginComponent, ServersComponent, AddServerDialogComponent, CreateSnapshotDialogComponent, @@ -549,6 +552,7 @@ import { MarkedDirective } from './directives/marked.directive'; Title, ApplianceService, UpdatesService, + LoginService ], entryComponents: [ AddServerDialogComponent, diff --git a/src/app/components/login/login.component.html b/src/app/components/login/login.component.html new file mode 100644 index 00000000..f7953ec0 --- /dev/null +++ b/src/app/components/login/login.component.html @@ -0,0 +1,30 @@ +
+
+ +
+
+ +
+

GNS3

+
v{{version}}
+
+
+
+ +
+ + + You must enter username + + + + You must enter password + +
+ +
+ +
+
+
+
diff --git a/src/app/components/login/login.component.scss b/src/app/components/login/login.component.scss new file mode 100644 index 00000000..d9529403 --- /dev/null +++ b/src/app/components/login/login.component.scss @@ -0,0 +1,31 @@ +mat-form-field { + width: 100%; +} + +.wrapper { + display: flex; + justify-content: center; +} + +.loginCard { + width: 540px; +} + +.mat-icon-login { + height: 200px!important; + width: 200px!important; +} + +.loginTitle { + display: flex; + justify-content: center; +} + +.loginIcon { + display: flex; + align-items: center; +} + +.loginButton { + width: 100%; +} diff --git a/src/app/components/login/login.component.spec.ts b/src/app/components/login/login.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/login/login.component.ts b/src/app/components/login/login.component.ts new file mode 100644 index 00000000..fafc30fa --- /dev/null +++ b/src/app/components/login/login.component.ts @@ -0,0 +1,66 @@ +import { Component, ComponentFactoryResolver, OnInit, ViewEncapsulation } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { Server } from '../../models/server'; +import { LoginService } from '../../services/login.service'; +import { ServerDatabase } from '../../services/server.database'; +import { ServerService } from '../../services/server.service'; +import { ToasterService } from '../../services/toaster.service'; +import { AuthResponse } from '../../models/authResponse'; +import { VersionService } from '../../services/version.service'; +import { Version } from '../../models/version'; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.scss'], + encapsulation: ViewEncapsulation.None, +}) +export class LoginComponent implements OnInit { + private server: Server; + public version: string; + + loginForm = new FormGroup({ + username: new FormControl('', [Validators.required]), + password: new FormControl('', [Validators.required]) + }); + + constructor( + private loginService: LoginService, + private serverService: ServerService, + private serverDatabase: ServerDatabase, + private route: ActivatedRoute, + private router: Router, + private toasterService: ToasterService, + private versionService: VersionService + ) {} + + async ngOnInit() { + const server_id = this.route.snapshot.paramMap.get('server_id'); + this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { + this.server = server; + + this.versionService.get(this.server).subscribe((version: Version) => { + this.version = version.version; + }); + }); + } + + public login() { + if (this.loginForm.get('username').invalid || this.loginForm.get('password').invalid) { + this.toasterService.error("Please enter username and password") + return; + } + + let username = this.loginForm.get('username').value; + let password = this.loginForm.get('password').value; + + this.loginService.login(this.server, username, password).subscribe(async (response: AuthResponse) => { + let server = this.server; + server.authToken = response.access_token; + await this.serverService.update(server); + + this.router.navigate(['/server', this.server.id, 'projects']); + }); + } +} diff --git a/src/app/components/template/template.component.ts b/src/app/components/template/template.component.ts index c4868d45..acf6ced2 100644 --- a/src/app/components/template/template.component.ts +++ b/src/app/components/template/template.component.ts @@ -127,7 +127,7 @@ export class TemplateComponent implements OnInit, OnDestroy { } getImageSourceForTemplate(template: Template) { - return `${this.server.protocol}//${this.server.host}:${this.server.port}/v3/symbols/${template.symbol}/raw`; + return this.symbolService.getSymbolFromTemplate(this.server, template); } ngOnDestroy() { diff --git a/src/app/guards/login-guard.ts b/src/app/guards/login-guard.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/layouts/default-layout/default-layout.component.html b/src/app/layouts/default-layout/default-layout.component.html index e50813a0..f2c5559d 100644 --- a/src/app/layouts/default-layout/default-layout.component.html +++ b/src/app/layouts/default-layout/default-layout.component.html @@ -39,4 +39,4 @@ - + diff --git a/src/app/models/authResponse.ts b/src/app/models/authResponse.ts new file mode 100644 index 00000000..d5427726 --- /dev/null +++ b/src/app/models/authResponse.ts @@ -0,0 +1,4 @@ +export interface AuthResponse { + access_token: string; + token_type: string; +} diff --git a/src/app/models/server.ts b/src/app/models/server.ts index 9d110bff..9be64aa9 100644 --- a/src/app/models/server.ts +++ b/src/app/models/server.ts @@ -3,6 +3,7 @@ export type ServerStatus = 'stopped' | 'starting' | 'running'; export type ServerProtocol = 'http:' | 'https:'; export class Server { + authToken: string; id: number; name: string; location: ServerLocation; diff --git a/src/app/services/http-server.service.ts b/src/app/services/http-server.service.ts index a88a75a6..9af22d26 100644 --- a/src/app/services/http-server.service.ts +++ b/src/app/services/http-server.service.ts @@ -187,10 +187,9 @@ export class HttpServer { options.headers = {}; } - // if (server.authorization === 'basic') { - // const credentials = btoa(`${server.login}:${server.password}`); - // options.headers['Authorization'] = `Basic ${credentials}`; - // } + if (server.authToken) { + options.headers['Authorization'] = `Bearer ${server.authToken}`; + } return { url: url, diff --git a/src/app/services/login.service.ts b/src/app/services/login.service.ts new file mode 100644 index 00000000..ea7b478a --- /dev/null +++ b/src/app/services/login.service.ts @@ -0,0 +1,23 @@ +import { HttpHeaders, HttpParams } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import 'rxjs/add/operator/map'; +import { Server } from '../models/server'; +import { HttpServer } from './http-server.service'; +import { AuthResponse } from '../models/authResponse'; + +@Injectable() +export class LoginService { + constructor(private httpServer: HttpServer) {} + + login(server: Server, username: string, password: string) { + const payload = new HttpParams() + .set('username', username) + .set('password', password); + + const options = { + headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded') + }; + + return this.httpServer.post(server, '/users/login', payload, options); + } +} diff --git a/src/app/services/symbol.service.ts b/src/app/services/symbol.service.ts index 6c39a964..65cb22b8 100644 --- a/src/app/services/symbol.service.ts +++ b/src/app/services/symbol.service.ts @@ -5,6 +5,7 @@ import { Node } from '../cartography/models/node'; import { Server } from '../models/server'; import { Symbol } from '../models/symbol'; import { HttpServer } from './http-server.service'; +import { Template } from '../models/template'; const CACHE_SIZE = 1; @@ -62,6 +63,10 @@ export class SymbolService { const encoded_uri = encodeURI(symbol_id); return this.httpServer.getText(server, `/symbols/${encoded_uri}/raw`); } + + getSymbolFromTemplate(server: Server, template: Template) { + return `${server.protocol}//${server.host}:${server.port}/v3/symbols/${template.symbol}/raw`; + } } class SymbolDimension {