diff --git a/pom.xml b/pom.xml
index 163ad53..f580e41 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,7 +47,40 @@
org.jetbrains.kotlin
kotlin-stdlib
-
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ runtime
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ runtime
+ 0.11.5
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ jakarta.inject
+ jakarta.inject-api
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.postgresql
+ postgresql
+ compile
+
org.springframework.boot
spring-boot-starter-test
diff --git a/src/main/kotlin/com/coded/spring/ordering/Application.kt b/src/main/kotlin/com/coded/spring/ordering/Application.kt
index 8554e49..8707209 100644
--- a/src/main/kotlin/com/coded/spring/ordering/Application.kt
+++ b/src/main/kotlin/com/coded/spring/ordering/Application.kt
@@ -1,10 +1,36 @@
package com.coded.spring.ordering
+import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.ComponentScan
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
+import org.springframework.security.crypto.password.PasswordEncoder
@SpringBootApplication
-class Application
+@ComponentScan("com.example.authentication")
+
+class Application{
+
+
+ @Bean
+ fun initUsers(userRepository: UsersRepository, passwordEncoder: PasswordEncoder) = CommandLineRunner {
+ val user = UserEntity(
+ name = "HelloUser",
+ username = "testuser",
+ password = passwordEncoder.encode("password123"),
+ age = 18,
+ role = Roles.USER
+ )
+ if (userRepository.findByUsername(user.username) == null) {
+ println("Creating user ${user.username}")
+ userRepository.save(user)
+ } else {
+ println("User ${user.username} already exists")
+ }
+ }
+}
fun main(args: Array) {
runApplication(*args)
diff --git a/src/main/kotlin/com/coded/spring/ordering/HelloWorld.kt b/src/main/kotlin/com/coded/spring/ordering/HelloWorld.kt
new file mode 100644
index 0000000..878f828
--- /dev/null
+++ b/src/main/kotlin/com/coded/spring/ordering/HelloWorld.kt
@@ -0,0 +1,13 @@
+package com.coded.spring.ordering
+
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+class HelloWorld {
+
+ @GetMapping("/Hello")
+ fun sayingHello(): String{
+ return "Hello World ,, najla"
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/coded/spring/ordering/OnlineOrdering.kt b/src/main/kotlin/com/coded/spring/ordering/OnlineOrdering.kt
new file mode 100644
index 0000000..10b516a
--- /dev/null
+++ b/src/main/kotlin/com/coded/spring/ordering/OnlineOrdering.kt
@@ -0,0 +1,46 @@
+package com.coded.spring.ordering
+
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+class OnlineOrdering (val ordersRepositry: OrdersRepositry){
+
+
+
+// var customerOrd://customerOrder("ali","pizza hut", listOf("pizza", "chicken wings" , "pepsi") )
+
+ var customerOrdList = mutableListOf()
+ @PostMapping("/order")
+ fun order(@RequestBody newOrder: customerOrder): String{
+ customerOrdList.add(newOrder)
+ return "your order submitted"
+ }
+
+ @GetMapping("/order")
+ fun allOrder (): List{
+ return customerOrdList
+ }
+
+ @PostMapping("/orderDB")
+ fun orderDB (@RequestBody newOrder: customerOrderDB){
+ var theOrder= OrdersEntity()
+ theOrder.userId = newOrder.userId
+ theOrder.resturant = newOrder.resturant
+ theOrder.items = newOrder.items
+ ordersRepositry.save(theOrder)
+
+ }
+
+ @GetMapping("/orderDB")
+ fun orderDB ():List{
+ var allOrderDB = OrdersEntity()
+ return ordersRepositry.findAll()
+ }
+}
+
+
+data class customerOrder(var user: String,var resturant: String , var items: List)
+data class customerOrderDB(var userId: Int,var resturant: String , var items: String)
\ No newline at end of file
diff --git a/src/main/kotlin/com/coded/spring/ordering/OrdersEntity.kt b/src/main/kotlin/com/coded/spring/ordering/OrdersEntity.kt
new file mode 100644
index 0000000..8e548b4
--- /dev/null
+++ b/src/main/kotlin/com/coded/spring/ordering/OrdersEntity.kt
@@ -0,0 +1,21 @@
+package com.coded.spring.ordering
+
+import jakarta.persistence.*
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface OrdersRepositry : JpaRepository
+@Entity
+@Table(name = "orders")
+data class OrdersEntity (
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ val id: Int,
+ var userId: Int,
+ var resturant: String,
+ var items: String
+ ){
+ constructor(): this (0,0,"","")
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/coded/spring/ordering/UserEntity.kt b/src/main/kotlin/com/coded/spring/ordering/UserEntity.kt
new file mode 100644
index 0000000..257ebd3
--- /dev/null
+++ b/src/main/kotlin/com/coded/spring/ordering/UserEntity.kt
@@ -0,0 +1,29 @@
+package com.coded.spring.ordering
+
+import jakarta.persistence.*
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.stereotype.Repository
+
+@Repository
+interface UsersRepository: JpaRepository{
+ fun findByUsername(username: String): UserEntity?
+}
+
+@Entity
+@Table(name = "users")
+data class UserEntity(
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ val id: Int? = null ,
+ var name: String,
+ var age: Int,
+ var username: String,
+ var password: String,
+ @Enumerated(EnumType.STRING)
+ val role: Roles = Roles.USER) {
+ constructor() : this(0, "name", 0, "username", "password", Roles.USER)
+}
+
+enum class Roles{
+ USER,ADMIN
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/example/authentication/CustomUserDetailsService.kt b/src/main/kotlin/com/example/authentication/CustomUserDetailsService.kt
new file mode 100644
index 0000000..9ab0434
--- /dev/null
+++ b/src/main/kotlin/com/example/authentication/CustomUserDetailsService.kt
@@ -0,0 +1,21 @@
+package com.example.authentication
+
+import com.coded.spring.ordering.UsersRepository
+import org.springframework.security.core.userdetails.*
+import org.springframework.stereotype.Service
+
+@Service
+class CustomUserDetailsService(
+ private val usersRepository: UsersRepository
+) : UserDetailsService {
+ override fun loadUserByUsername(username: String): UserDetails {
+ val user = usersRepository.findByUsername(username)
+ ?: throw UsernameNotFoundException("User not found")
+
+ return User.builder()
+ .username(user.username)
+ .password(user.password)
+ .roles(user.role.toString())
+ .build()
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/example/authentication/SecurityConfig.kt b/src/main/kotlin/com/example/authentication/SecurityConfig.kt
new file mode 100644
index 0000000..fc1d32c
--- /dev/null
+++ b/src/main/kotlin/com/example/authentication/SecurityConfig.kt
@@ -0,0 +1,58 @@
+package com.example.authentication
+
+import com.example.authentication.jwt.JwtAuthenticationFilter
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.security.authentication.AuthenticationManager
+import org.springframework.security.authentication.AuthenticationProvider
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider
+import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration
+import org.springframework.security.config.annotation.web.builders.HttpSecurity
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
+import org.springframework.security.config.http.SessionCreationPolicy
+import org.springframework.security.core.userdetails.UserDetailsService
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
+import org.springframework.security.crypto.password.PasswordEncoder
+import org.springframework.security.web.SecurityFilterChain
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
+
+
+
+@Configuration
+@EnableWebSecurity
+class SecurityConfig(
+ private val jwtAuthFilter: JwtAuthenticationFilter,
+ private val userDetailsService: UserDetailsService
+) {
+
+ @Bean
+ fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
+ http.csrf { it.disable() }
+ .authorizeHttpRequests {
+ it.requestMatchers("/auth/**").permitAll()
+ .anyRequest().authenticated()
+ }
+ .sessionManagement {
+ it.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ }
+ .authenticationProvider(authenticationProvider())
+ .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter::class.java)
+
+ return http.build()
+ }
+
+ @Bean
+ fun passwordEncoder(): PasswordEncoder = BCryptPasswordEncoder()
+
+ @Bean
+ fun authenticationManager(config: AuthenticationConfiguration): AuthenticationManager =
+ config.authenticationManager
+
+ @Bean
+ fun authenticationProvider(): AuthenticationProvider {
+ val provider = DaoAuthenticationProvider()
+ provider.setUserDetailsService(userDetailsService)
+ provider.setPasswordEncoder(passwordEncoder())
+ return provider
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/example/authentication/jwt/AuthenticationController.kt b/src/main/kotlin/com/example/authentication/jwt/AuthenticationController.kt
new file mode 100644
index 0000000..e96bfb9
--- /dev/null
+++ b/src/main/kotlin/com/example/authentication/jwt/AuthenticationController.kt
@@ -0,0 +1,39 @@
+package com.example.authentication.jwt
+
+import org.springframework.security.authentication.*
+import org.springframework.security.core.userdetails.UserDetailsService
+import org.springframework.security.core.userdetails.UsernameNotFoundException
+import org.springframework.web.bind.annotation.*
+
+
+@RestController
+@RequestMapping("/auth")
+class AuthenticationController(
+ private val authenticationManager: AuthenticationManager,
+ private val userDetailsService: UserDetailsService,
+ private val jwtService: JwtService
+) {
+
+ @PostMapping("/login")
+ fun login(@RequestBody authRequest: AuthenticationRequest): AuthenticationResponse {
+ val authToken = UsernamePasswordAuthenticationToken(authRequest.username, authRequest.password)
+ val authentication = authenticationManager.authenticate(authToken)
+
+ if (authentication.isAuthenticated) {
+ val userDetails = userDetailsService.loadUserByUsername(authRequest.username)
+ val token = jwtService.generateToken(userDetails.username)
+ return AuthenticationResponse (token)
+ } else {
+ throw UsernameNotFoundException("Invalid user request!")
+ }
+ }
+}
+
+data class AuthenticationRequest(
+ val username: String,
+ val password: String
+)
+
+data class AuthenticationResponse(
+ val token: String
+)
\ No newline at end of file
diff --git a/src/main/kotlin/com/example/authentication/jwt/JwtAuthenticationFilter.kt b/src/main/kotlin/com/example/authentication/jwt/JwtAuthenticationFilter.kt
new file mode 100644
index 0000000..f15819f
--- /dev/null
+++ b/src/main/kotlin/com/example/authentication/jwt/JwtAuthenticationFilter.kt
@@ -0,0 +1,45 @@
+package com.example.authentication.jwt
+
+import jakarta.servlet.FilterChain
+import jakarta.servlet.http.*
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
+import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.core.userdetails.UserDetailsService
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource
+import org.springframework.stereotype.Component
+import org.springframework.web.filter.OncePerRequestFilter
+
+@Component
+class JwtAuthenticationFilter(
+ private val jwtService: JwtService,
+ private val userDetailsService: UserDetailsService
+) : OncePerRequestFilter() {
+
+ override fun doFilterInternal(
+ request: HttpServletRequest,
+ response: HttpServletResponse,
+ filterChain: FilterChain
+ ) {
+ val authHeader = request.getHeader("Authorization")
+ if (authHeader == null || !authHeader.startsWith("Bearer ")) {
+ filterChain.doFilter(request, response)
+ return
+ }
+
+ val token = authHeader.substring(7)
+ val username = jwtService.extractUsername(token)
+
+ if (SecurityContextHolder.getContext().authentication == null) {
+ if (jwtService.isTokenValid(token, username)) {
+ val userDetails = userDetailsService.loadUserByUsername(username)
+ val authToken = UsernamePasswordAuthenticationToken(
+ userDetails, null, userDetails.authorities
+ )
+ authToken.details = WebAuthenticationDetailsSource().buildDetails(request)
+ SecurityContextHolder.getContext().authentication = authToken
+ }
+ }
+
+ filterChain.doFilter(request, response)
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/example/authentication/jwt/JwtService.kt b/src/main/kotlin/com/example/authentication/jwt/JwtService.kt
new file mode 100644
index 0000000..b1888ee
--- /dev/null
+++ b/src/main/kotlin/com/example/authentication/jwt/JwtService.kt
@@ -0,0 +1,42 @@
+package com.example.authentication.jwt
+
+import io.jsonwebtoken.*
+import io.jsonwebtoken.security.Keys
+import org.springframework.stereotype.Component
+import java.util.*
+import javax.crypto.SecretKey
+
+@Component
+class JwtService {
+
+ private val secretKey: SecretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256)
+ private val expirationMs: Long = 1000 * 60 * 60
+
+ fun generateToken(username: String): String {
+ val now = Date()
+ val expiry = Date(now.time + expirationMs)
+
+ return Jwts.builder()
+ .setSubject(username)
+ .setIssuedAt(now)
+ .setExpiration(expiry)
+ .signWith(secretKey)
+ .compact()
+ }
+
+ fun extractUsername(token: String): String =
+ Jwts.parserBuilder()
+ .setSigningKey(secretKey)
+ .build()
+ .parseClaimsJws(token)
+ .body
+ .subject
+
+ fun isTokenValid(token: String, username: String): Boolean {
+ return try {
+ extractUsername(token) == username
+ } catch (e: Exception) {
+ false
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 3704dc6..de82fb4 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1,7 @@
spring.application.name=Kotlin.SpringbootV2
+spring.jpa.show-sql= true
+
+spring.datasource.url=jdbc:postgresql://localhost:5432/ProjectDB
+spring.datasource.username=postgres
+spring.datasource.password=123456
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
\ No newline at end of file
diff --git a/src/test/kotlin/com/coded/spring/ordering/ApplicationTests.kt b/src/test/kotlin/com/coded/spring/ordering/ApplicationTests.kt
index b2e2320..ac6f51f 100644
--- a/src/test/kotlin/com/coded/spring/ordering/ApplicationTests.kt
+++ b/src/test/kotlin/com/coded/spring/ordering/ApplicationTests.kt
@@ -2,12 +2,18 @@ package com.coded.spring.ordering
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.web.client.RestTemplate
+import org.springframework.web.client.getForEntity
-@SpringBootTest
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ApplicationTests {
+ lateinit var restTemplate : RestTemplate
+
@Test
fun contextLoads() {
+
+
}
}