Compare commits

..

No commits in common. "49023d2237c8a0c097f807a624727f90c8a36545" and "ea9c700f373338f35c43694eaf0aa4b4af46a85d" have entirely different histories.

23 changed files with 64 additions and 103 deletions

View File

@ -1,11 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gradle" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

11
.gitmodules vendored
View File

@ -1,8 +1,3 @@
[submodule "cubetiq-security-core"] [submodule "cubetiq-security-jwt"]
path = cubetiq-security-core path = cubetiq-security-jwt
url = https://git.cubetiqs.com/cubetiq/cubetiq-security-core.git url = https://git.cubetiqs.com/CUBETIQ/cubetiq-security-jwt.git
branch = main
[submodule "cubetiq-security-web"]
path = cubetiq-security-web
url = https://git.cubetiqs.com/cubetiq/cubetiq-security-web.git
branch = main

View File

@ -1,7 +1,7 @@
# GraphQL & Spring Boot (Demo Project) # GraphQL & Spring Boot (Demo Project)
- Spring Boot - Spring Boot (2.6)
- DGS Framework - DGS Framework (4.5.0)
- Kotlin - Kotlin (1.5.21)
# Contributors # Contributors
- Sambo Chea <sombochea@cubetiqs.com> - Sambo Chea <sombochea@cubetiqs.com>

View File

@ -1,23 +1,23 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
id("org.springframework.boot") version "3.0.0" apply false id("org.springframework.boot") version "2.5.3" apply false
id("io.spring.dependency-management") version "1.1.0" apply false id("io.spring.dependency-management") version "1.0.11.RELEASE" apply false
kotlin("jvm") version "1.7.22" apply false kotlin("jvm") version "1.5.21" apply false
kotlin("plugin.spring") version "1.7.22" apply false kotlin("plugin.spring") version "1.5.21" apply false
kotlin("plugin.jpa") version "1.7.22" apply false kotlin("plugin.jpa") version "1.5.21" apply false
id("com.netflix.dgs.codegen") version "5.6.3" apply false id("com.netflix.dgs.codegen") version "5.0.5" apply false
} }
allprojects { allprojects {
repositories { repositories {
mavenCentral() maven { url = uri("https://m.ctdn.net") }
} }
group = "com.cubetiqs" group = "com.cubetiqs"
version = "0.0.1-SNAPSHOT" version = "0.0.1-SNAPSHOT"
val javaVersion = "17" val javaVersion = "11"
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {
sourceCompatibility = javaVersion sourceCompatibility = javaVersion

@ -1 +0,0 @@
Subproject commit 612bafe9af476798a40a536c82112c63c8627f4f

1
cubetiq-security-jwt Submodule

@ -0,0 +1 @@
Subproject commit d69f52fee0d6c8c0fad3eab64dc0645470168a49

@ -1 +0,0 @@
Subproject commit 62d0e718e59af79db15871bde67affd8c38b15e5

View File

@ -7,12 +7,13 @@ plugins {
id("com.netflix.dgs.codegen") id("com.netflix.dgs.codegen")
} }
dependencies { extra["dgsVersion"] = "4.5.0"
api(project(":cubetiq-security-web"))
implementation(platform("com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:5.4.3")) dependencies {
implementation("com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter") api(project(":cubetiq-security-jwt"))
runtimeOnly("com.netflix.graphql.dgs:graphql-dgs-subscriptions-websockets-autoconfigure")
implementation("com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter:${property("dgsVersion")}")
runtimeOnly("com.netflix.graphql.dgs:graphql-dgs-subscriptions-websockets-autoconfigure:${property("dgsVersion")}")
implementation("org.springframework.boot:spring-boot-starter-security") implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-actuator") implementation("org.springframework.boot:spring-boot-starter-actuator")

View File

@ -1,19 +1,10 @@
package com.cubetiqs.graphql.demo package com.cubetiqs.graphql.demo
import com.cubetiqs.sp.security.util.PasswordUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication import org.springframework.boot.runApplication
import org.springframework.security.crypto.password.PasswordEncoder
@SpringBootApplication @SpringBootApplication
class GraphqlDemoApplication @Autowired constructor( class GraphqlDemoApplication
private val passwordEncoder: PasswordEncoder,
) {
init {
PasswordUtils.setEncoder(passwordEncoder)
}
}
fun main(args: Array<String>) { fun main(args: Array<String>) {
runApplication<GraphqlDemoApplication>(*args) runApplication<GraphqlDemoApplication>(*args)

View File

@ -1,44 +1,37 @@
package com.cubetiqs.graphql.demo.config package com.cubetiqs.graphql.demo.config
import com.cubetiqs.graphql.demo.security.AuthService import com.cubetiqs.graphql.demo.security.AuthService
import com.cubetiqs.sp.security.EnableCubetiqSecurityModule import com.cubetiqs.security.jwt.AuthenticationExceptionEntryPoint
import com.cubetiqs.sp.security.jwt.CubetiqJwtProperties import com.cubetiqs.security.jwt.JwtSecurityConfigurer
import com.cubetiqs.sp.security.jwt.JwtSecurityConfigurer
import com.cubetiqs.sp.security.support.AuthenticationExceptionEntryPoint
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.config.http.SessionCreationPolicy import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.web.SecurityFilterChain
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableCubetiqSecurityModule class WebSecurityConfig : WebSecurityConfigurerAdapter() {
class WebSecurityConfig @Autowired constructor( @Autowired
private val authService: AuthService, private lateinit var authService: AuthService
private val cubetiqJwtProperties: CubetiqJwtProperties,
) {
@Bean
fun passwordEncoder(): PasswordEncoder {
return BCryptPasswordEncoder(10)
}
@Bean override fun configure(http: HttpSecurity) {
fun filterChain(http: HttpSecurity): SecurityFilterChain { http.csrf().disable()
http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
http.exceptionHandling().authenticationEntryPoint(AuthenticationExceptionEntryPoint()) http
.exceptionHandling()
.authenticationEntryPoint(AuthenticationExceptionEntryPoint())
http.apply(JwtSecurityConfigurer(authService, cubetiqJwtProperties)) http
.apply(JwtSecurityConfigurer(authService))
http.authorizeHttpRequests().anyRequest().permitAll() http
.authorizeRequests()
return http.build() .anyRequest().permitAll()
} }
} }

View File

@ -2,8 +2,8 @@ package com.cubetiqs.graphql.demo.domain
import org.springframework.data.jpa.domain.support.AuditingEntityListener import org.springframework.data.jpa.domain.support.AuditingEntityListener
import java.io.Serializable import java.io.Serializable
import jakarta.persistence.EntityListeners import javax.persistence.EntityListeners
import jakarta.persistence.MappedSuperclass import javax.persistence.MappedSuperclass
@MappedSuperclass @MappedSuperclass
@EntityListeners(AuditingEntityListener::class) @EntityListeners(AuditingEntityListener::class)

View File

@ -8,7 +8,7 @@ import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.LastModifiedDate import org.springframework.data.annotation.LastModifiedDate
import java.math.BigDecimal import java.math.BigDecimal
import java.util.* import java.util.*
import jakarta.persistence.* import javax.persistence.*
@Entity @Entity
@Table(name = "accounts", indexes = [ @Table(name = "accounts", indexes = [

View File

@ -1,9 +1,9 @@
package com.cubetiqs.graphql.demo.domain.account package com.cubetiqs.graphql.demo.domain.account
import java.util.* import java.util.*
import jakarta.persistence.PostPersist import javax.persistence.PostPersist
import jakarta.persistence.PrePersist import javax.persistence.PrePersist
import jakarta.persistence.PreUpdate import javax.persistence.PreUpdate
class AccountEntityListener { class AccountEntityListener {
@PrePersist @PrePersist

View File

@ -7,7 +7,7 @@ import org.hibernate.Hibernate
import org.springframework.data.annotation.CreatedDate import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.LastModifiedDate import org.springframework.data.annotation.LastModifiedDate
import java.util.* import java.util.*
import jakarta.persistence.* import javax.persistence.*
@Entity @Entity
@Table( @Table(

View File

@ -1,8 +1,8 @@
package com.cubetiqs.graphql.demo.domain.user package com.cubetiqs.graphql.demo.domain.user
import java.util.* import java.util.*
import jakarta.persistence.PrePersist import javax.persistence.PrePersist
import jakarta.persistence.PreUpdate import javax.persistence.PreUpdate
class UserEntityListener { class UserEntityListener {
@PrePersist @PrePersist

View File

@ -4,7 +4,7 @@ import com.cubetiqs.graphql.demo.context.GMutation
import com.cubetiqs.graphql.demo.dgmodel.DgsConstants import com.cubetiqs.graphql.demo.dgmodel.DgsConstants
import com.cubetiqs.graphql.demo.dgmodel.types.LoginResponse import com.cubetiqs.graphql.demo.dgmodel.types.LoginResponse
import com.cubetiqs.graphql.demo.security.AuthService import com.cubetiqs.graphql.demo.security.AuthService
import com.cubetiqs.sp.security.jwt.util.JwtTokenUtils import com.cubetiqs.security.jwt.util.JwtUtils
import com.netflix.graphql.dgs.DgsMutation import com.netflix.graphql.dgs.DgsMutation
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
@ -16,10 +16,7 @@ class LoginMutationResolver {
@DgsMutation(field = DgsConstants.MUTATION.Login) @DgsMutation(field = DgsConstants.MUTATION.Login)
fun login(username: String, password: String): LoginResponse { fun login(username: String, password: String): LoginResponse {
val auth = authService.login(username, password) val auth = authService.login(username, password)
val token = JwtTokenUtils.createTokens(auth) val token = JwtUtils.encryptToken(auth)
return LoginResponse( return LoginResponse(token)
accessToken = token.accessToken,
refreshToken = token.refreshToken,
)
} }
} }

View File

@ -7,7 +7,7 @@ import com.cubetiqs.graphql.demo.domain.user.User
import com.cubetiqs.graphql.demo.domain.user.UserInput import com.cubetiqs.graphql.demo.domain.user.UserInput
import com.cubetiqs.graphql.demo.domain.user.UserMapper import com.cubetiqs.graphql.demo.domain.user.UserMapper
import com.cubetiqs.graphql.demo.repository.UserRepository import com.cubetiqs.graphql.demo.repository.UserRepository
import com.cubetiqs.sp.security.util.PasswordUtils import com.cubetiqs.security.jwt.util.JwtUtils
import com.netflix.graphql.dgs.DgsMutation import com.netflix.graphql.dgs.DgsMutation
import com.netflix.graphql.dgs.exceptions.DgsEntityNotFoundException import com.netflix.graphql.dgs.exceptions.DgsEntityNotFoundException
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
@ -30,7 +30,7 @@ class UserMutationResolver @Autowired constructor(
@DgsMutation(field = DgsConstants.MUTATION.ChangeUserPassword) @DgsMutation(field = DgsConstants.MUTATION.ChangeUserPassword)
fun changePassword(input: UserChangePasswordInput): User { fun changePassword(input: UserChangePasswordInput): User {
val user = userRepository.queryByUsername(input.username).orElse(null) ?: throw DgsEntityNotFoundException("User not found!") val user = userRepository.queryByUsername(input.username).orElse(null) ?: throw DgsEntityNotFoundException("User not found!")
user.password = PasswordUtils.encode(input.password) user.password = JwtUtils.passwordEncoder().encode(input.password)
return userRepository.save(user) return userRepository.save(user)
} }
} }

View File

@ -1,8 +1,7 @@
package com.cubetiqs.graphql.demo.security package com.cubetiqs.graphql.demo.security
import com.cubetiqs.graphql.demo.domain.user.User import com.cubetiqs.graphql.demo.domain.user.User
import com.cubetiqs.sp.security.jwt.util.JwtTokenUtils import com.cubetiqs.security.jwt.util.JwtUtils
import com.cubetiqs.sp.security.util.PasswordUtils
import org.springframework.security.core.GrantedAuthority import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.core.userdetails.UserDetails
@ -48,7 +47,7 @@ data class AuthDetails(
} }
fun isPasswordValid(password: String): Boolean { fun isPasswordValid(password: String): Boolean {
return PasswordUtils.matches(password, this.getPassword()) return JwtUtils.passwordEncoder().matches(password, this.getPassword())
} }
companion object { companion object {

View File

@ -1 +0,0 @@
application-local.yml

View File

@ -3,8 +3,6 @@ server:
# Spring Boot # Spring Boot
spring: spring:
profiles:
active: ${APP_PROFILE:}
datasource: datasource:
url: jdbc:postgresql://${DB_HOST:localhost}:5432/${DB_NAME:graphql-demo} url: jdbc:postgresql://${DB_HOST:localhost}:5432/${DB_NAME:graphql-demo}
username: ${DB_USER:your-username} username: ${DB_USER:your-username}

View File

@ -14,8 +14,7 @@ input UserInput {
} }
type LoginResponse { type LoginResponse {
accessToken: String token: String
refreshToken: String
} }
input UserChangePasswordInput { input UserChangePasswordInput {

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -1,3 +1,4 @@
rootProject.name = "spring-graphql-demo" rootProject.name = "graphql-demo"
include("cubetiq-security-core", "cubetiq-security-web", "dgs-graphql") include("dgs-graphql")
include("cubetiq-security-jwt")