1 | package mk.ukim.finki.busngobackend.service
|
---|
2 |
|
---|
3 | import mk.ukim.finki.busngobackend.api.requests.AuthRequest
|
---|
4 | import mk.ukim.finki.busngobackend.api.requests.RegisterRequest
|
---|
5 | import mk.ukim.finki.busngobackend.api.responses.AuthResponse
|
---|
6 | import mk.ukim.finki.busngobackend.config.JwtService
|
---|
7 | import mk.ukim.finki.busngobackend.domain.entities.*
|
---|
8 | import mk.ukim.finki.busngobackend.domain.enums.RoleEnum
|
---|
9 | import mk.ukim.finki.busngobackend.domain.enums.toId
|
---|
10 | import mk.ukim.finki.busngobackend.repository.*
|
---|
11 | import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
|
---|
12 | import mk.ukim.finki.busngobackend.service.exceptions.UnauthorizedAccessException
|
---|
13 | import org.springframework.data.repository.findByIdOrNull
|
---|
14 | import org.springframework.security.authentication.AuthenticationManager
|
---|
15 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
---|
16 | import org.springframework.security.core.GrantedAuthority
|
---|
17 | import org.springframework.security.core.context.SecurityContext
|
---|
18 | import org.springframework.security.core.context.SecurityContextHolder
|
---|
19 | import org.springframework.security.core.userdetails.UserDetailsService
|
---|
20 | import org.springframework.stereotype.Service
|
---|
21 |
|
---|
22 | @Service
|
---|
23 | class AuthService(
|
---|
24 | private val authenticationManager: AuthenticationManager,
|
---|
25 | private val userDetailsService: UserDetailsService,
|
---|
26 | private val jwtService: JwtService,
|
---|
27 | private val korisnikRepository: KorisnikRepository,
|
---|
28 | private val korisnikRoleRepository: KorisnikRoleRepository,
|
---|
29 | private val roleRepository: RoleRepository,
|
---|
30 | private val instancaNaLinijaRepository: InstancaNaLinijaRepository,
|
---|
31 | private val vrabotenRepository: VrabotenRepository,
|
---|
32 | private val vozacRepository: VozacRepository,
|
---|
33 | private val kondukterRepository: KondukterRepository,
|
---|
34 | private val patnikRepository: PatnikRepository,
|
---|
35 | ) {
|
---|
36 | fun getSecurityContext(): SecurityContext = SecurityContextHolder.getContext()
|
---|
37 |
|
---|
38 | fun getAuthenticatedUser(): Korisnik = userDetailsService.loadUserByUsername(getSecurityContext().authentication.name) as Korisnik
|
---|
39 |
|
---|
40 | fun hasAuthority(authority: RoleEnum): Boolean =
|
---|
41 | getAuthenticatedUser().authorities.contains(roleRepository.findByIdOrNull(authority.toId()) as GrantedAuthority)
|
---|
42 |
|
---|
43 | fun isAuthenticated(): Boolean {
|
---|
44 | if (getSecurityContext().authentication == null) {
|
---|
45 | throw UnauthorizedAccessException("User is not authenticated")
|
---|
46 | }
|
---|
47 | return true
|
---|
48 | }
|
---|
49 |
|
---|
50 | fun register(registerRequest: RegisterRequest): AuthResponse {
|
---|
51 | if (this.korisnikRepository.findByEmail(registerRequest.email) != null) {
|
---|
52 | throw RuntimeException("Invalid credentials")
|
---|
53 | }
|
---|
54 | if (registerRequest.password != registerRequest.confirmPassword) {
|
---|
55 | throw RuntimeException("Passwords do not match")
|
---|
56 | }
|
---|
57 |
|
---|
58 | val roles = this.roleRepository.findAllByNameLikeIgnoreCase("role_passenger")
|
---|
59 |
|
---|
60 | val user =
|
---|
61 | this.korisnikRepository.save(
|
---|
62 | Korisnik(
|
---|
63 | email = registerRequest.email,
|
---|
64 | lozinka = registerRequest.password,
|
---|
65 | ime = registerRequest.name,
|
---|
66 | id = 0L,
|
---|
67 | adresa = registerRequest.address,
|
---|
68 | admin = false,
|
---|
69 | telefon = registerRequest.phoneNumber,
|
---|
70 | roles = null,
|
---|
71 | ),
|
---|
72 | )
|
---|
73 |
|
---|
74 | val newRoles =
|
---|
75 | roles.map {
|
---|
76 | this.korisnikRoleRepository.save(
|
---|
77 | KorisnikRole(
|
---|
78 | id = 0,
|
---|
79 | role = it,
|
---|
80 | korisnik = user,
|
---|
81 | ),
|
---|
82 | )
|
---|
83 | }
|
---|
84 |
|
---|
85 | user.roles = newRoles
|
---|
86 |
|
---|
87 | val korisnik = this.korisnikRepository.save(user)
|
---|
88 | val patnik =
|
---|
89 | this.patnikRepository.save(
|
---|
90 | Patnik(
|
---|
91 | id = 0L,
|
---|
92 | korisnik = korisnik,
|
---|
93 | ),
|
---|
94 | )
|
---|
95 |
|
---|
96 | return this.authenticate(AuthRequest(user.email, user.lozinka))
|
---|
97 | }
|
---|
98 |
|
---|
99 | fun authenticate(authRequest: AuthRequest): AuthResponse {
|
---|
100 | authenticationManager.authenticate(
|
---|
101 | UsernamePasswordAuthenticationToken(
|
---|
102 | authRequest.email,
|
---|
103 | authRequest.password,
|
---|
104 | ),
|
---|
105 | )
|
---|
106 |
|
---|
107 | val user = userDetailsService.loadUserByUsername(authRequest.email)
|
---|
108 |
|
---|
109 | val token = jwtService.generateToken(userDetails = user)
|
---|
110 |
|
---|
111 | return AuthResponse(token)
|
---|
112 | }
|
---|
113 |
|
---|
114 | fun isDriverFree(): Boolean {
|
---|
115 | if (!this.hasAuthority(RoleEnum.ROLE_DRIVER)) throw UnauthorizedAccessException("User is not authorized")
|
---|
116 | val korisnik = this.userDetailsService.loadUserByUsername(this.getSecurityContext().authentication.name) as Korisnik
|
---|
117 | val vraboten = this.vrabotenRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Vraboten not found")
|
---|
118 | val vozac = this.vozacRepository.findByVraboten(vraboten) ?: throw NotFoundException("Vozac not found")
|
---|
119 |
|
---|
120 | return !this.instancaNaLinijaRepository.existsByVozacAndEndDateIsNull(vozac.id)
|
---|
121 | }
|
---|
122 |
|
---|
123 | fun getConductor(): Kondukter {
|
---|
124 | if (!this.isAuthenticated() || !this.hasAuthority(RoleEnum.ROLE_CONDUCTOR)) {
|
---|
125 | throw UnauthorizedAccessException("Unauthorized access")
|
---|
126 | }
|
---|
127 |
|
---|
128 | val korisnik = this.getAuthenticatedUser()
|
---|
129 | val vraboten = vrabotenRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Korisnik")
|
---|
130 | val kondukter = kondukterRepository.findByVraboten(vraboten) ?: throw NotFoundException("Kondukter")
|
---|
131 |
|
---|
132 | return kondukter
|
---|
133 | }
|
---|
134 |
|
---|
135 | fun getDriver(): Vozac {
|
---|
136 | if (!this.isAuthenticated() || !this.hasAuthority(RoleEnum.ROLE_DRIVER)) {
|
---|
137 | throw UnauthorizedAccessException("Unauthorized access")
|
---|
138 | }
|
---|
139 |
|
---|
140 | val korisnik = this.getAuthenticatedUser()
|
---|
141 | val vraboten = vrabotenRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Korisnik")
|
---|
142 | val vozac = vozacRepository.findByVraboten(vraboten) ?: throw NotFoundException("Vozac")
|
---|
143 |
|
---|
144 | return vozac
|
---|
145 | }
|
---|
146 |
|
---|
147 | fun getPassenger(): Patnik {
|
---|
148 | if (!this.isAuthenticated() || !this.hasAuthority(RoleEnum.ROLE_PASSENGER)) {
|
---|
149 | throw UnauthorizedAccessException("Unauthorized access")
|
---|
150 | }
|
---|
151 |
|
---|
152 | val korisnik = this.getAuthenticatedUser()
|
---|
153 | val patnik = patnikRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Patnik")
|
---|
154 |
|
---|
155 | return patnik
|
---|
156 | }
|
---|
157 | }
|
---|