BAEL-797 changing the UI to make requests without passing credentials. Updating serurity config to always use the default redirect url. Adding a super simple landing page also forcing all 404s to land on the angular app.
This commit is contained in:
+1
-14
@@ -6,20 +6,7 @@
|
||||
<div class="collapse navbar-collapse" id="navbarCollapse">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
</ul>
|
||||
<div *ngIf="!principal.authenticated; then loginForm else loginMessage"></div>
|
||||
<ng-template #loginForm>
|
||||
<form (ngSubmit)="onLogin(f)" class="form-inline mt-2 mt-md-0" #f="ngForm">
|
||||
<input name="username" [(ngModel)]="credentials.username" required class="form-control mr-sm-2" type="text" placeholder="Username">
|
||||
<input name="password" [(ngModel)]="credentials.password" required class="form-control mr-sm-2" type="password" placeholder="Password">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" [disabled]="!f.valid">Login</button>
|
||||
</form>
|
||||
</ng-template>
|
||||
<ng-template #loginMessage>
|
||||
<button type="button" class="btn btn-link" (click)="onLogout()">Logout</button>
|
||||
</ng-template>
|
||||
<div *ngIf="loginFailed">
|
||||
<div class="alert alert-warning">Login Failed</div>
|
||||
</div>
|
||||
<button *ngIf="principal.authenticated" type="button" class="btn btn-link" (click)="onLogout()">Logout</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
+8
-18
@@ -1,7 +1,6 @@
|
||||
import {Component} from "@angular/core";
|
||||
import {Principal} from "./principal";
|
||||
import {Response} from "@angular/http";
|
||||
import {NgForm} from "@angular/forms";
|
||||
import {Book} from "./book";
|
||||
import {HttpService} from "./http.service";
|
||||
|
||||
@@ -11,38 +10,29 @@ import {HttpService} from "./http.service";
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
credentials = {
|
||||
username: '',
|
||||
password: ''
|
||||
};
|
||||
selectedBook: Book = null;
|
||||
principal: Principal = new Principal(false, [], null);
|
||||
principal: Principal = new Principal(false, []);
|
||||
loginFailed: boolean = false;
|
||||
|
||||
constructor(private httpService: HttpService){}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
onLogin(form: NgForm) {
|
||||
this.loginFailed = false;
|
||||
this.credentials = {username: form.value.username, password: form.value.password};
|
||||
this.httpService.login(this.credentials)
|
||||
ngOnInit(): void {
|
||||
this.httpService.me()
|
||||
.subscribe((response: Response) => {
|
||||
let principalJson = response.json();
|
||||
this.principal = new Principal(principalJson.authenticated, principalJson.authorities, this.credentials);
|
||||
this.principal = new Principal(principalJson.authenticated, principalJson.authorities);
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
onLogout() {
|
||||
this.httpService.logout(this.principal.credentials)
|
||||
this.httpService.logout()
|
||||
.subscribe((response: Response) => {
|
||||
if (response.status === 204) {
|
||||
if (response.status === 200) {
|
||||
this.loginFailed = false;
|
||||
this.credentials.username = '';
|
||||
this.credentials.password = '';
|
||||
this.principal = new Principal(false, [], null);
|
||||
this.principal = new Principal(false, []);
|
||||
window.location.replace(response.url);
|
||||
}
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
|
||||
+3
-3
@@ -56,7 +56,7 @@ export class BookListComponent implements OnInit {
|
||||
saveBook(bookIndex: number, newBook: Book) {
|
||||
console.log(newBook);
|
||||
//save the book to the database
|
||||
this.httpService.updateBook(newBook, this.principal.credentials)
|
||||
this.httpService.updateBook(newBook)
|
||||
.subscribe((response: Response) => {
|
||||
let bookJson = response.json();
|
||||
let book: Book = new Book(bookJson.id, bookJson.author, bookJson.title);
|
||||
@@ -74,7 +74,7 @@ export class BookListComponent implements OnInit {
|
||||
|
||||
delete(bookIndex: number) {
|
||||
let book: Book = this.books[bookIndex];
|
||||
this.httpService.deleteBook(book, this.principal.credentials)
|
||||
this.httpService.deleteBook(book)
|
||||
.subscribe(() => {
|
||||
if (this.selectedBook !== null && this.books[bookIndex].id === this.selectedBook.id) {
|
||||
this.selectedBook = null;
|
||||
@@ -95,7 +95,7 @@ export class BookListComponent implements OnInit {
|
||||
|
||||
addNewBook(newBook: Book, element: any) {
|
||||
//write new book to db
|
||||
this.httpService.createBook(newBook, this.principal.credentials)
|
||||
this.httpService.createBook(newBook)
|
||||
.subscribe((response: Response) => {
|
||||
let bookJson = response.json();
|
||||
let book: Book = new Book(bookJson.id, bookJson.author, bookJson.title);
|
||||
|
||||
+37
-50
@@ -9,61 +9,48 @@ export class HttpService {
|
||||
|
||||
constructor(private http: Http) { }
|
||||
|
||||
login(user: any): Observable<Response> {
|
||||
let options = this.makeAuthOptions(user);
|
||||
return this.http.get("/me", options)
|
||||
me(): Observable<Response> {
|
||||
return this.http.get("/me", this.makeOptions())
|
||||
}
|
||||
|
||||
logout(user: any): Observable<Response> {
|
||||
let options = this.makeAuthOptions(user);
|
||||
return this.http.post("/logout", '', options)
|
||||
logout(): Observable<Response> {
|
||||
return this.http.post("/logout", '', this.makeOptions())
|
||||
}
|
||||
|
||||
getBooks(): Observable<Response> {
|
||||
return this.http.get("/book-service/books", this.makeOptions())
|
||||
}
|
||||
|
||||
updateBook(newBook: Book): Observable<Response> {
|
||||
return this.http.put("/book-service/books/" + newBook.id, newBook, this.makeOptions())
|
||||
}
|
||||
|
||||
deleteBook(book: Book): Observable<Response> {
|
||||
return this.http.delete("/book-service/books/" + book.id, this.makeOptions())
|
||||
}
|
||||
|
||||
createBook(newBook: Book): Observable<Response> {
|
||||
return this.http.post("/book-service/books", newBook, this.makeOptions())
|
||||
}
|
||||
|
||||
getRatings(bookId: number): Observable<Response> {
|
||||
return this.http.get("/rating-service/ratings?bookId=" + bookId, this.makeOptions())
|
||||
}
|
||||
|
||||
createRating(rating: Rating): Observable<Response> {
|
||||
return this.http.post("/rating-service/ratings", rating, this.makeOptions())
|
||||
}
|
||||
|
||||
deleteRating(ratingId: number) {
|
||||
return this.http.delete("/rating-service/ratings/" + ratingId, this.makeOptions())
|
||||
}
|
||||
|
||||
updateRating(rating: Rating) {
|
||||
return this.http.put("/rating-service/ratings/" + rating.id, rating, this.makeOptions())
|
||||
}
|
||||
|
||||
private makeOptions(): RequestOptions {
|
||||
let headers = new Headers({'Content-Type': 'application/json'});
|
||||
let options = new RequestOptions({headers: headers});
|
||||
return this.http.get("/book-service/books", options)
|
||||
}
|
||||
|
||||
updateBook(newBook: Book, user: any): Observable<Response> {
|
||||
let options = this.makeAuthOptions(user);
|
||||
return this.http.put("/book-service/books/" + newBook.id, newBook, options)
|
||||
}
|
||||
|
||||
deleteBook(book: Book, user: any): Observable<Response> {
|
||||
let options = this.makeAuthOptions(user);
|
||||
return this.http.delete("/book-service/books/" + book.id, options)
|
||||
}
|
||||
|
||||
createBook(newBook: Book, user: any): Observable<Response> {
|
||||
let options = this.makeAuthOptions(user);
|
||||
return this.http.post("/book-service/books", newBook, options)
|
||||
}
|
||||
|
||||
getRatings(bookId: number, user: any): Observable<Response> {
|
||||
let options = this.makeAuthOptions(user);
|
||||
return this.http.get("/rating-service/ratings?bookId=" + bookId, options)
|
||||
}
|
||||
|
||||
createRating(rating: Rating, user: any): Observable<Response> {
|
||||
let options = this.makeAuthOptions(user);
|
||||
return this.http.post("/rating-service/ratings", rating, options)
|
||||
}
|
||||
|
||||
deleteRating(ratingId: number, user: any) {
|
||||
let options = this.makeAuthOptions(user);
|
||||
return this.http.delete("/rating-service/ratings/" + ratingId, options)
|
||||
}
|
||||
|
||||
updateRating(rating: Rating, user: any) {
|
||||
let options = this.makeAuthOptions(user);
|
||||
return this.http.put("/rating-service/ratings/" + rating.id, rating, options)
|
||||
}
|
||||
|
||||
private makeAuthOptions(user: any): RequestOptions {
|
||||
let headers = new Headers({'Content-Type': 'application/json'});
|
||||
headers.append('Authorization','Basic ' + btoa(user.username + ':' + user.password));
|
||||
headers.append('X-Requested-With','XMLHttpRequest');
|
||||
return new RequestOptions({headers: headers});;
|
||||
return new RequestOptions({headers: headers});
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,12 +1,10 @@
|
||||
export class Principal {
|
||||
public authenticated: boolean;
|
||||
public authorities: Authority[] = [];
|
||||
public credentials: any;
|
||||
|
||||
constructor(authenticated: boolean, authorities: any[], credentials: any) {
|
||||
constructor(authenticated: boolean, authorities: any[]) {
|
||||
this.authenticated = authenticated;
|
||||
authorities.map(auth => this.authorities.push(new Authority(auth.authority)))
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
isAdmin() {
|
||||
|
||||
+4
-4
@@ -33,7 +33,7 @@ export class RatingComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
private loadRatings() {
|
||||
this.httpService.getRatings(this.bookId, this.principal.credentials)
|
||||
this.httpService.getRatings(this.bookId)
|
||||
.subscribe((response: Response) => {
|
||||
let responseJson: any[] = response.json();
|
||||
responseJson.forEach(rating => this.ratings.push(new Rating(rating.id, rating.bookId, rating.stars)))
|
||||
@@ -45,7 +45,7 @@ export class RatingComponent implements OnInit, OnChanges {
|
||||
onSaveRating() {
|
||||
console.log(this.newRating);
|
||||
let ratingCopy: Rating = Object.assign({}, this.newRating);
|
||||
this.httpService.createRating(ratingCopy, this.principal.credentials)
|
||||
this.httpService.createRating(ratingCopy)
|
||||
.subscribe((response: Response) => {
|
||||
let ratingJson = response.json()
|
||||
this.ratings.push(new Rating(ratingJson.id, ratingJson.bookId, ratingJson.stars))
|
||||
@@ -55,7 +55,7 @@ export class RatingComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
updateRating() {
|
||||
this.httpService.updateRating(this.newRating, this.principal.credentials)
|
||||
this.httpService.updateRating(this.newRating)
|
||||
.subscribe(() => {
|
||||
this.newRating = new Rating(null, this.bookId, 1);
|
||||
}, (error) => {
|
||||
@@ -75,7 +75,7 @@ export class RatingComponent implements OnInit, OnChanges {
|
||||
|
||||
deleteRating(index: number) {
|
||||
let rating = this.ratings[index];
|
||||
this.httpService.deleteRating(rating.id, this.principal.credentials)
|
||||
this.httpService.deleteRating(rating.id)
|
||||
.subscribe(() => {
|
||||
if (this.ratings[index] === this.newRating) {
|
||||
this.newRating = new Rating(null, this.bookId, 1);
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
|
||||
public class ErrorPageConfig implements ErrorPageRegistrar {
|
||||
@Override
|
||||
public void registerErrorPages(ErrorPageRegistry registry) {
|
||||
registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/"));
|
||||
registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/home/index.html"));
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -29,10 +29,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
.formLogin()
|
||||
.loginPage("/login.html")
|
||||
.loginProcessingUrl("/login")
|
||||
.defaultSuccessUrl("/home/index.html")
|
||||
.defaultSuccessUrl("/home/index.html", true)
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/book-service/**", "/rating-service/**", "/login*").permitAll()
|
||||
.antMatchers("/book-service/**", "/rating-service/**", "/login*", "/").permitAll()
|
||||
.antMatchers("/eureka/**").hasRole("ADMIN")
|
||||
.antMatchers("/home/*").authenticated()
|
||||
.anyRequest().authenticated()
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+45
-68
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Book Rater Landing</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Book Rater</h1>
|
||||
<p>So many great things about the books</p>
|
||||
<a href="/login.html">Login</a>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user