diff --git a/backend/src/main/java/de/szut/casino/user/UserController.java b/backend/src/main/java/de/szut/casino/user/UserController.java new file mode 100644 index 0000000..7ee0739 --- /dev/null +++ b/backend/src/main/java/de/szut/casino/user/UserController.java @@ -0,0 +1,25 @@ +package de.szut.casino.user; + +import de.szut.casino.user.dto.CreateUserDto; +import jakarta.validation.Valid; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +public class UserController { + + @Autowired + private UserService userService; + + + @GetMapping("/user/{id}") + public ResponseEntity getUser(@PathVariable String id) { + return ResponseEntity.ok(userService.getUser(id)); + } + + @PostMapping("/user") + public ResponseEntity createUser(@RequestBody @Valid CreateUserDto userData) { + return ResponseEntity.ok(userService.createUser(userData)); + } +} diff --git a/backend/src/main/java/de/szut/casino/user/UserEntity.java b/backend/src/main/java/de/szut/casino/user/UserEntity.java new file mode 100644 index 0000000..3fb45a2 --- /dev/null +++ b/backend/src/main/java/de/szut/casino/user/UserEntity.java @@ -0,0 +1,18 @@ +package de.szut.casino.user; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@Entity +public class UserEntity { + @Id + @GeneratedValue + private Long id; + private String keycloakId; + private String username; +} diff --git a/backend/src/main/java/de/szut/casino/user/UserRepository.java b/backend/src/main/java/de/szut/casino/user/UserRepository.java new file mode 100644 index 0000000..f009b44 --- /dev/null +++ b/backend/src/main/java/de/szut/casino/user/UserRepository.java @@ -0,0 +1,16 @@ +package de.szut.casino.user; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public interface UserRepository extends JpaRepository { + boolean existsByUsername(String username); + + @Query("SELECT u FROM UserEntity u WHERE u.keycloakId = ?1") + Optional findOneByKeycloakId(String keycloakId); + +} diff --git a/backend/src/main/java/de/szut/casino/user/UserService.java b/backend/src/main/java/de/szut/casino/user/UserService.java new file mode 100644 index 0000000..95cb01a --- /dev/null +++ b/backend/src/main/java/de/szut/casino/user/UserService.java @@ -0,0 +1,37 @@ +package de.szut.casino.user; + +import de.szut.casino.user.dto.CreateUserDto; +import de.szut.casino.user.dto.GetUserDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class UserService { + @Autowired + private UserRepository userRepository; + + public UserEntity createUser(CreateUserDto createUserDto) { + UserEntity user = new UserEntity(); + user.setUsername(createUserDto.getUsername()); + user.setKeycloakId(createUserDto.getKeycloakId()); + userRepository.save(user); + + return user; + } + + public GetUserDto getUser(String keycloakId) { + Optional user = this.userRepository.findOneByKeycloakId(keycloakId); + if (user.isPresent()) { + System.out.println(user.get()); + GetUserDto getUserDto = new GetUserDto(); + getUserDto.setKeycloakId(user.get().getKeycloakId()); + getUserDto.setUsername(user.get().getUsername()); + return getUserDto; + } + System.out.println("User not found: "+keycloakId); + + return null; + } +} diff --git a/backend/src/main/java/de/szut/casino/user/dto/CreateUserDto.java b/backend/src/main/java/de/szut/casino/user/dto/CreateUserDto.java new file mode 100644 index 0000000..ff28427 --- /dev/null +++ b/backend/src/main/java/de/szut/casino/user/dto/CreateUserDto.java @@ -0,0 +1,15 @@ +package de.szut.casino.user.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class CreateUserDto { + private String keycloakId; + private String username; +} diff --git a/backend/src/main/java/de/szut/casino/user/dto/GetUserDto.java b/backend/src/main/java/de/szut/casino/user/dto/GetUserDto.java new file mode 100644 index 0000000..95855f1 --- /dev/null +++ b/backend/src/main/java/de/szut/casino/user/dto/GetUserDto.java @@ -0,0 +1,15 @@ +package de.szut.casino.user.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class GetUserDto { + private String keycloakId; + private String username; +} diff --git a/frontend/src/app/app.config.ts b/frontend/src/app/app.config.ts index 8401ece..cbe2fcf 100644 --- a/frontend/src/app/app.config.ts +++ b/frontend/src/app/app.config.ts @@ -27,7 +27,7 @@ export const initializeKeycloak = (keycloak: KeycloakService) => async () => onLoad: 'check-sso', silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html', checkLoginIframe: false, - redirectUri: 'http://localhost:4200', + redirectUri: window.location.origin + '/login/success', }, }); diff --git a/frontend/src/app/app.routes.ts b/frontend/src/app/app.routes.ts index 73ed20c..bbf1a56 100644 --- a/frontend/src/app/app.routes.ts +++ b/frontend/src/app/app.routes.ts @@ -2,12 +2,17 @@ import { Routes } from '@angular/router'; import { LandingComponent } from './feature/landing/landing.component'; import { HomeComponent } from './feature/home/home.component'; import { authGuard } from './auth.guard'; +import { LoginSuccessComponent } from './login-success/login-success.component'; export const routes: Routes = [ { path: '', component: LandingComponent, }, + { + path: 'login/success', + component: LoginSuccessComponent, + }, { path: 'home', component: HomeComponent, diff --git a/frontend/src/app/auth.guard.ts b/frontend/src/app/auth.guard.ts index 0743ff6..e97e4fc 100644 --- a/frontend/src/app/auth.guard.ts +++ b/frontend/src/app/auth.guard.ts @@ -1,4 +1,4 @@ -import { ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from '@angular/router'; import { inject } from '@angular/core'; import { KeycloakService } from 'keycloak-angular'; @@ -7,17 +7,13 @@ export const authGuard: CanActivateFn = async ( state: RouterStateSnapshot ) => { const keycloakService = inject(KeycloakService); - const isLoggedIn = keycloakService.isLoggedIn(); + const router = inject(Router); - if (isLoggedIn) { + if (keycloakService.isLoggedIn()) { return true; } - const baseurl = window.location.origin; - - keycloakService.login({ - redirectUri: `${baseurl}${state.url}`, - }); + router.navigate(['']); return false; }; diff --git a/frontend/src/app/login-success/login-success.component.css b/frontend/src/app/login-success/login-success.component.css new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/app/login-success/login-success.component.html b/frontend/src/app/login-success/login-success.component.html new file mode 100644 index 0000000..bf2b4b5 --- /dev/null +++ b/frontend/src/app/login-success/login-success.component.html @@ -0,0 +1 @@ +

login-success works!

diff --git a/frontend/src/app/login-success/login-success.component.ts b/frontend/src/app/login-success/login-success.component.ts new file mode 100644 index 0000000..5da8136 --- /dev/null +++ b/frontend/src/app/login-success/login-success.component.ts @@ -0,0 +1,25 @@ +import { Component, inject, OnInit } from '@angular/core'; +import { UserService } from '../service/user.service'; +import { KeycloakService } from 'keycloak-angular'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-login-success', + standalone: true, + imports: [], + templateUrl: './login-success.component.html', + styleUrl: './login-success.component.css' +}) +export class LoginSuccessComponent implements OnInit{ + private userService: UserService = inject(UserService); + private keycloakService: KeycloakService = inject(KeycloakService); + private router: Router = inject(Router); + + async ngOnInit() { + const userProfile = await this.keycloakService.loadUserProfile(); + const user = this.userService.getCurrentUser(userProfile); + sessionStorage.setItem('user', JSON.stringify(user)); + + // this.router.navigate(['']); + } +} diff --git a/frontend/src/app/service/user.service.ts b/frontend/src/app/service/user.service.ts new file mode 100644 index 0000000..a195238 --- /dev/null +++ b/frontend/src/app/service/user.service.ts @@ -0,0 +1,34 @@ +import { inject, Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { KeycloakProfile } from 'keycloak-js'; +import { async } from 'rxjs'; + +@Injectable({ + providedIn: 'root', +}) +export class UserService { + private http: HttpClient = inject(HttpClient); + + public getUser(id: string) { + return this.http.get<{ keycloakId: string, username: string } | null>(`/backend/user/${id}`); + } + + public createUser(id: string, username: string) { + return this.http.post<{ keycloakId: string, username: string }>('/backend/user', { + keycloakId: id, + username: username, + }); + } + + public async getCurrentUser(userProfile: KeycloakProfile) { + if (userProfile.id == null) { + return; + } + return await this.getUser(userProfile.id).toPromise().then(async user => { + if (user) { + return user; + } + return await this.createUser(userProfile.id ?? '', userProfile.username ?? '').toPromise(); + }); + } +}