Added: Alembic for migrations

Moving from Pyramid to FastAPI
This commit is contained in:
2020-06-14 18:43:10 +05:30
parent 0c0a2990a8
commit fdfd3dcbfb
139 changed files with 4017 additions and 3397 deletions

View File

@ -1,12 +1,13 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatToolbarModule } from '@angular/material/toolbar';
import {RouterModule} from '@angular/router';
import {HTTP_INTERCEPTORS} from '@angular/common/http';
import {HttpAuthInterceptor} from './http-auth-interceptor';
import { RouterModule } from '@angular/router';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ErrorInterceptor } from './http-auth-interceptor';
import { JwtInterceptor } from './jwt.interceptor';
@NgModule({
imports: [
@ -19,11 +20,10 @@ import {HttpAuthInterceptor} from './http-auth-interceptor';
],
declarations: [
],
providers: [[{
provide: HTTP_INTERCEPTORS,
useClass: HttpAuthInterceptor,
multi: true
}]]
providers: [
{provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true},
]
})
export class CoreModule {
}

View File

@ -1,44 +1,51 @@
import {Injectable} from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import {catchError} from 'rxjs/operators';
import {ToasterService} from './toaster.service';
import {Router} from '@angular/router';
import {ConfirmDialogComponent} from '../shared/confirm-dialog/confirm-dialog.component';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Router } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
import { AuthService } from '../auth/auth.service';
import { ToasterService } from './toaster.service';
import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.component';
@Injectable()
export class HttpAuthInterceptor implements HttpInterceptor {
constructor(private router: Router, private dialog: MatDialog, private toaster: ToasterService) {
export class ErrorInterceptor implements HttpInterceptor {
constructor(private authService: AuthService, private router: Router, private dialog: MatDialog, private toaster: ToasterService) {
}
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
return next.handle(req)
.pipe(
catchError((error: any) => {
if (error.status === 401) {
this.toaster.show('Danger', 'User has been logged out');
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
width: '250px',
data: {
title: 'Logged out!',
content: 'You have been logged out.\n' +
'You can press Cancel to stay on page and login in another tab to resume here,' +
' or you can press Ok to navigate to the login page.'
}
});
dialogRef.afterClosed().subscribe((result: boolean) => {
if (result) {
this.router.navigate(['login']);
}
});
}
return throwError(error);
}
)
);
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
// We don't want to refresh token for some requests like login or refresh token itself
// So we verify url and we throw an error if it's the case
if (request.url.includes('/refresh') || request.url.includes('/token')) {
// We do another check to see if refresh token failed
// In this case we want to logout user and to redirect it to login page
if (request.url.includes('/refresh')) {
this.authService.logout();
}
return throwError(err);
}
// If error status is different than 401 we want to skip refresh token
// So we check that and throw the error if it's the case
if (err.status !== 401) {
const error = err.error.message || err.error.detail || err.statusText;
return throwError(error);
}
// auto logout if 401 response returned from api
this.authService.logout();
this.toaster.show('Danger', 'User has been logged out');
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
width: '250px',
data: {
title: 'Logged out!',
content: 'You have been logged out.\nYou can press Cancel to stay on page and login in another tab to resume here, or you can press Ok to navigate to the login page.'
}
});
dialogRef.afterClosed().subscribe((result: boolean) => {
if (result) {
this.router.navigate(['login']);
}
});
}));
}
}

View File

@ -0,0 +1,35 @@
import {Injectable} from '@angular/core';
import {HttpRequest, HttpHandler, HttpEvent, HttpInterceptor} from '@angular/common/http';
import {Observable} from 'rxjs';
import {AuthService} from '../auth/auth.service';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
private isRefreshing = false;
constructor(private authService: AuthService) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// add authorization header with jwt token if available
// We use this line to debug token refreshing
// console.log("intercepting:\nisRefreshing: ", this.isRefreshing, "\n user: ", this.authService.user,"\n needsRefreshing: ", this.authService.needsRefreshing());
if (!this.isRefreshing && this.authService.user && this.authService.needsRefreshing()) {
this.isRefreshing = true;
this.authService.refreshToken().subscribe( x=> this.isRefreshing = false);
}
const currentUser = this.authService.user;
if (currentUser?.access_token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${currentUser.access_token}`
}
});
}
return next.handle(request);
}
}

View File

@ -3,16 +3,18 @@ export class User {
name: string;
password: string;
lockedOut: boolean;
roles: UserRole[];
roles?: UserGroup[];
perms: string[];
isAuthenticated: boolean;
access_token?: string;
exp?: number;
public constructor(init?: Partial<User>) {
Object.assign(this, init);
}
}
export class UserRole {
export class UserGroup {
id: string;
name: string;
enabled: boolean;