Commit b51c29be authored by jcorvi's avatar jcorvi
Browse files

Merge branch 'develop' into 'master'

Develop

See merge request !4
parents 1a60626b 709bf528
Pipeline #25036 passed with stage
in 1 minute and 55 seconds
variables:
DOCKER_USER: javicorvi
DOCKER_BUILD: $DOCKER_USER/$CI_PROJECT_NAME:$CI_COMMIT_REF_NAME
DOCKER_REGISTRY: registry.gitlab.bsc.es
IMAGE_FULL_PATH: $DOCKER_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_NAME
stages:
- build
build_docker_image:
stage: build
script:
- docker login -u javicorvi -p $DOCKER_PASS
- docker build -t $DOCKER_BUILD . -f DockerfileDev
- docker push $DOCKER_BUILD
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $DOCKER_REGISTRY
- docker build -t $IMAGE_FULL_PATH .
- docker push $IMAGE_FULL_PATH
tags:
- build
......@@ -8,15 +8,11 @@ import { SrdomaintemplateTabulatorComponent } from './srdomaintemplate-tabulator
import { PretoxsentencesTabulatorComponent } from './pretoxsentences-tabulator/pretoxsentences-tabulator.component';
import { FindingTabulatorComponent } from './finding-tabulator/finding-tabulator.component';
import {LoginComponent} from './login/login.component';
import {AuthGuard} from './authguard.service';
const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: '', redirectTo: '/documents', pathMatch: 'full' },
// { path: 'find/:id/first', component: SrdomainLevelComponent },
// { path: 'find/:id/second', component: SrdomainLevelComponent },
// { path: 'find/:id/third', component: SrdomainLevelComponent },
//{ path: '', redirectTo: '/documents', pathMatch: 'full' },
{ path: '', redirectTo: 'documents', pathMatch: 'full' },
{ path: 'find/:id', component: DocumentDetailComponent,
children: [
......@@ -27,15 +23,11 @@ const routes: Routes = [
]
},
{ path: 'documents', component: DocumentsComponent },
{ path: 'documents', component: DocumentsComponent, canActivate: [AuthGuard]},
{ path: 'first_1', component: SrdomainLevelComponent},
{ path: 'second_2', component: SrdomainLevelComponent},
{ path: 'third_3', component: SrdomainLevelComponent},
{ path: 'third_3', component: SrdomainLevelComponent}
];
......
import { Component } from '@angular/core';
import {MatToolbarModule} from '@angular/material/toolbar';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
......
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { MenuComponent } from './menu/menu.component';
......@@ -17,7 +17,7 @@ import { HttpModule } from '@angular/http';
import {CookieService} from 'ngx-cookie-service';
import { PretoxsentencesTabulatorComponent } from './pretoxsentences-tabulator/pretoxsentences-tabulator.component';
import { SrdomaintemplateTabulatorComponent } from './srdomaintemplate-tabulator/srdomaintemplate-tabulator.component';
import { HttpInterceptorService } from './httpInterceptor.service';
import {MatToolbarModule} from '@angular/material/toolbar';
import {MatTabsModule} from '@angular/material/tabs';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
......@@ -48,7 +48,11 @@ import { SrdomainLevelComponent } from './srdomain-level/srdomain-level.componen
BrowserAnimationsModule,
MatToolbarModule
],
providers: [LoginService, CookieService],
providers: [LoginService, CookieService, {
provide: HTTP_INTERCEPTORS,
useClass: HttpInterceptorService,
multi: true
}],
bootstrap: [AppComponent],
exports: [HeaderComponent, FooterComponent, DocumentsComponent, DocumentDetailComponent, MessagesComponent]
})
......
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { LoginService } from './login.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: LoginService, private router: Router) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
let loged_in = this.authService.isUserLoggedIn();
//alert(loged_in);
if (!loged_in) {
//alert(1);
this.router.navigateByUrl('/login');
return false;
} else {
//alert(2);
return true;
}
}
}
\ No newline at end of file
<div class="w3-container">
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" routerLink="">Home</a>
<a class="fa fa-angle-left" title='Previous Document' routerLink="" style="color:white;padding: 10px 30px;text-decoration:none;" aria-hidden="true" tooltip='Previous Document'></a>
<a class="fa fa-angle-right" title='Next Document' routerLink="" style="color:white;padding: 10px 30px;text-decoration:none;" aria-hidden="true" tooltip='Next Document'></a>
<!-- <a class="fa fa-angle-left" title='Previous Document' routerLink="" style="color:white;padding: 10px 30px;text-decoration:none;" aria-hidden="true" tooltip='Previous Document'></a>
<a class="fa fa-angle-right" title='Next Document' routerLink="" style="color:white;padding: 10px 30px;text-decoration:none;" aria-hidden="true" tooltip='Next Document'></a> -->
</nav>
<div *ngIf="document" class="documentName">
<div class="card">
......
......@@ -367,7 +367,7 @@ export class DocumentDetailComponent implements OnInit {
setExportSRDomain(data) {
const id = +this.route.snapshot.paramMap.get('id');
//alert(data.id);
//alert(data);
//alert(data.export);
this.documentService.setExportSRDomain(id, data.srDomainId, data.export)
.subscribe(text => {
......
......@@ -16,11 +16,14 @@ const httpOptions = {
providedIn: 'root'
})
export class DocumentService {
private documentsUrl = environment.apiUrl; // URL to web api
private documentsUrl = environment.apiUrl + "/documents/";
//private documentsUrl = 'http://10.32.6.2:8090/documents/'; // URL to web api
constructor(private http: HttpClient, private messageService: MessageService) { }
getDocuments(): Observable<Document[]> {
//const headers = new HttpHeaders ({ Authorization: 'Basic '+ btoa('javi'+':'+'pass2')});
return this.http.get<Document[]>(this.documentsUrl).pipe(
tap(_ => this.log('fetched documents')),
catchError(this.handleError<Document[]>('getDocuments', []))
......@@ -36,7 +39,7 @@ export class DocumentService {
/** GET document by id. Will 404 if id not found */
getDocument(id: number): Observable<Document> {
const url = `${this.documentsUrl}/${id}`;
const url = `${this.documentsUrl}${id}`;
return this.http.get<Document>(url).pipe(
tap(_ => this.log(`fetched document id=${id}`)),
catchError(this.handleError<Document>(`getDocument id=${id}`))
......@@ -45,7 +48,7 @@ export class DocumentService {
/** GET document by id. Will 404 if id not found */
exportDocument(id: number): any {
const url = `${this.documentsUrl}/export/${id}`;
const url = `${this.documentsUrl}export/${id}`;
return this.http.get(url, {
responseType: 'blob',
})
......@@ -89,7 +92,7 @@ export class DocumentService {
/** GET Snipped of finding selected */
findingSelected(id: number, finding: Finding): Observable<string> {
const url = `${this.documentsUrl}/${id}/finding/${finding.findingId}`;
const url = `${this.documentsUrl}${id}/finding/${finding.findingId}`;
return this.http.get(url , {responseType: 'text'}).pipe(
tap(_ => this.log(`fetched finding id=${finding.findingId}`)),
catchError(this.handleError<string>(`getFinding id=${finding.findingId}`))
......@@ -99,7 +102,7 @@ export class DocumentService {
/** GET Snipped of findings selected just in case is needed, is not complete only the calls againt rest api is done*/
findingsSelected(id: number, finding: Finding): Observable<string> {
//const url = `${this.documentsUrl}/${id}/finding/${finding.findingId}`;
const url = `${this.documentsUrl}/${id}/findings/1,2`;
const url = `${this.documentsUrl}${id}/findings/1,2`;
return this.http.get(url , {responseType: 'text'}).pipe(
tap(_ => this.log(`fetched finding id=${finding.findingId}`)),
catchError(this.handleError<string>(`getFinding id=${finding.findingId}`))
......@@ -108,7 +111,7 @@ export class DocumentService {
/** GET Snipped of all finding evidence */
getAllEvidence(id: number): Observable<string> {
const url = `${this.documentsUrl}/${id}/evidence/all`;
const url = `${this.documentsUrl}${id}/evidence/all`;
return this.http.get(url , {responseType: 'text'}).pipe(
tap(_ => this.log(`fetched all evidence id=${id}`)),
catchError(this.handleError<string>(`getFindings id=${id}`))
......@@ -117,7 +120,7 @@ export class DocumentService {
pretoxSentenceSelected(id: number, pretoxSentence: Annotation): Observable<string> {
const url = `${this.documentsUrl}/${id}/sentence/${pretoxSentence.id}`;
const url = `${this.documentsUrl}${id}/sentence/${pretoxSentence.id}`;
//const url = `${this.documentsUrl}/${id}/sentence/1`;
return this.http.get(url , {responseType: 'text'}).pipe(
tap(_ => this.log(`fetched pretox sentence id=${pretoxSentence.id}`)),
......@@ -144,7 +147,7 @@ export class DocumentService {
/** DELETE: delete the document from the server */
deleteDocument(document: Document | number): Observable<Document> {
const id = typeof document === 'number' ? document : document.documentId;
const url = `${this.documentsUrl}/${id}`;
const url = `${this.documentsUrl}${id}`;
return this.http.delete<Document>(url, httpOptions).pipe(
tap(_ => this.log(`deleted document id=${id}`)),
......
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { LoginService } from './login.service';
@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
constructor(private authenticationService: LoginService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.authenticationService.isUserLoggedIn() && req.url.indexOf('basicauth') === -1) {
const authReq = req.clone({
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': sessionStorage.getItem('tokenUser')
//'Authorization': `Basic ${window.btoa(this.authenticationService.username + ":" + this.authenticationService.password)}`
})
});
return next.handle(authReq);
} else {
return next.handle(req);
}
}
}
\ No newline at end of file
import { Injectable} from '@angular/core';
import { Router } from '@angular/router';
import { Http, RequestOptions, Headers} from '@angular/http';
import { map} from 'rxjs/operators';
import {CookieService} from 'ngx-cookie-service';
@Injectable()
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
import { environment } from './../environments/environment';
@Injectable({
providedIn: 'root'
})
export class LoginService {
constructor(
private router: Router, private http: Http, private cookieService: CookieService) {}
obtainAccessToken(loginData) {
const params = new URLSearchParams();
params.append('username', loginData.username);
params.append('password', loginData.password);
params.append('grant_type', 'password');
params.append('client_id', 'R2dpxQ3vPrtfgF72');
const headers =
new Headers({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8',
'Authorization': 'Basic ' + btoa('R2dpxQ3vPrtfgF72:fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9')});
let options = new RequestOptions({ headers: headers });
this.http.post('http://localhost:8085/auth/login',
params.toString(), options).pipe(map(data => {}))
.subscribe(
data => this.saveToken(data),
err => alert('Invalid Credentials'));
private apiUrl = environment.apiUrl;
USER_NAME_SESSION_ATTRIBUTE_NAME = 'authenticatedUser';
USER_BASIC_TOKEN_ATTRIBUTE_NAME = 'tokenUser';
public username: String;
public password: String;
constructor(private http: HttpClient) {
}
saveToken(token) {
const expireDate = new Date().getTime() + (1000 * token.expires_in);
this.cookieService.set('access_token', token.access_token, expireDate);
this.router.navigate(['/']);
authenticationService(username: String, password: String) {
const url = `${this.apiUrl}/basicauth`;
return this.http.get(url,
{ headers: { authorization: this.createBasicAuthToken(username, password) } }).pipe(map((res) => {
this.username = username;
this.password = password;
this.registerSuccessfulLogin(username, password);
}));
}
createBasicAuthToken(username: String, password: String) {
return 'Basic ' + window.btoa(username + ":" + password)
}
checkCredentials() {
if (!this.cookieService.check('access_token')) {
this.router.navigate(['/login']);
}
registerSuccessfulLogin(username, password) {
sessionStorage.setItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME, username);
sessionStorage.setItem(this.USER_BASIC_TOKEN_ATTRIBUTE_NAME, this.createBasicAuthToken(username, password));
}
logout() {
this.cookieService.delete('access_token');
this.router.navigate(['/login']);
sessionStorage.removeItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME);
this.username = null;
this.password = null;
}
isUserLoggedIn() {
let user = sessionStorage.getItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME);
if (user === null) return false;
return true;
}
getLoggedInUserName() {
let user = sessionStorage.getItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME);
if (user === null) return '';
return user;
}
}
}
\ No newline at end of file
/* BASIC */
html {
background-color: #56baed;
}
body {
font-family: "Poppins", sans-serif;
height: 100vh;
}
a {
cursor: default;
color: #92badd;
display:inline-block;
text-decoration: none;
font-weight: 400;
}
h2 {
text-align: center;
font-size: 16px;
font-weight: 600;
display:inline-block;
margin: 40px 8px 10px 8px;
color: #cccccc;
}
/* STRUCTURE */
.wrapper {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
width: 100%;
min-height: 100%;
padding: 200px;
}
#formContent {
-webkit-border-radius: 10px 10px 10px 10px;
border-radius: 10px 10px 10px 10px;
background: #fff;
padding: 30px;
width: 90%;
max-width: 450px;
position: relative;
padding: 0px;
-webkit-box-shadow: 0 30px 60px 0 rgba(0,0,0,0.3);
box-shadow: 0 30px 60px 0 rgba(0,0,0,0.3);
text-align: center;
}
#formFooter {
background-color: #f6f6f6;
border-top: 1px solid #dce8f1;
padding: 25px;
text-align: center;
-webkit-border-radius: 0 0 10px 10px;
border-radius: 0 0 10px 10px;
}
/* TABS */
h2.inactive {
color: #cccccc;
}
h2.active {
color: #0d0d0d;
border-bottom: 2px solid #5fbae9;
}
/* FORM TYPOGRAPHY*/
input[type=button], input[type=submit], input[type=reset] {
background-color: #56baed;
border: none;
color: white;
padding: 15px 80px;
text-align: center;
text-decoration: none;
display: inline-block;
text-transform: uppercase;
font-size: 13px;
-webkit-box-shadow: 0 10px 30px 0 rgba(95,186,233,0.4);
box-shadow: 0 10px 30px 0 rgba(95,186,233,0.4);
-webkit-border-radius: 5px 5px 5px 5px;
border-radius: 5px 5px 5px 5px;
margin: 5px 20px 40px 20px;
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
-ms-transition: all 0.3s ease-in-out;
-o-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
input[type=button]:hover, input[type=submit]:hover, input[type=reset]:hover {
background-color: #39ace7;
}
input[type=button]:active, input[type=submit]:active, input[type=reset]:active {
-moz-transform: scale(0.95);
-webkit-transform: scale(0.95);
-o-transform: scale(0.95);
-ms-transform: scale(0.95);
transform: scale(0.95);
}
input[type=text], [type=password] {
background-color: #f6f6f6;
border: none;
color: #0d0d0d;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 5px;
width: 85%;
border: 2px solid #f6f6f6;
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-ms-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
-webkit-border-radius: 5px 5px 5px 5px;
border-radius: 5px 5px 5px 5px;
}
input[type=text]:focus {
background-color: #fff;
border-bottom: 2px solid #5fbae9;
}
input[type=text]:placeholder {
color: #cccccc;
}
/* ANIMATIONS */
/* Simple CSS3 Fade-in-down Animation */
.fadeInDown {
-webkit-animation-name: fadeInDown;
animation-name: fadeInDown;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
@-webkit-keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
100% {
opacity: 1;
-webkit-transform: none;
transform: none;
}
}
@keyframes fadeInDown {
0% {
opacity: 0;
-webkit-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
100% {
opacity: 1;
-webkit-transform: none;
transform: none;
}
}
/* Simple CSS3 Fade-in Animation */
@-webkit-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@-moz-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
.fadeIn {
opacity:0;
-webkit-animation:fadeIn ease-in 1;
-moz-animation:fadeIn ease-in 1;
animation:fadeIn ease-in 1;
-webkit-animation-fill-mode:forwards;
-moz-animation-fill-mode:forwards;
animation-fill-mode:forwards;
-webkit-animation-duration:1s;
-moz-animation-duration:1s;
animation-duration:1s;
}
.fadeIn.first {
-webkit-animation-delay: 0.4s;
-moz-animation-delay: 0.4s;
animation-delay: 0.4s;
}
.fadeIn.second {
-webkit-animation-delay: 0.6s;
-moz-animation-delay: 0.6s;
animation-delay: 0.6s;
}
.fadeIn.third {
-webkit-animation-delay: 0.8s;
-moz-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.fadeIn.fourth {
-webkit-animation-delay: 1s;
-moz-animation-delay: 1s;
animation-delay: 1s;
}
/* Simple CSS3 Fade-in Animation */
.underlineHover:after {
display: block;
left: 0;
bottom: -10px;
width: 0;
height: 2px;
background-color: #56baed;
content: "";
transition: width 0.2s;
}
.underlineHover:hover {
color: #0d0d0d;
}
.underlineHover:hover:after{
width: 100%;
}
/* OTHERS */
*:focus {
outline: none;
}
#icon { <