Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
Sambo Chea | 455b916720 | ||
Sambo Chea | a1ace59338 | ||
Sambo Chea | 2a83907be1 | ||
Sambo Chea | eedeb3abfa | ||
Sambo Chea | 7cd9ccd87b | ||
Sambo Chea | 404d626194 | ||
Sambo Chea | c0bb5a7930 | ||
Sambo Chea | a27388320f | ||
Sambo Chea | 294110af96 | ||
Sambo Chea | cfe8efdf5a | ||
Sambo Chea | 981f074049 | ||
Sambo Chea | 97d3934905 | ||
Sambo Chea | 68642dc16f | ||
Sambo Chea | 9bdb8487eb | ||
Sambo Chea | b25dfaa656 | ||
Sambo Chea | bf4ce4c02e | ||
Sambo Chea | f06a64767c |
|
@ -35,3 +35,5 @@ out/
|
||||||
|
|
||||||
### VS Code ###
|
### VS Code ###
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
.DS_Store
|
|
@ -1,9 +1,9 @@
|
||||||
# Sample Modules
|
# Sample Modules
|
||||||
- Including parent deps
|
- Including parent deps
|
||||||
- Spring Boot
|
- Spring Boot (2.4.1)
|
||||||
- Spring Dependency Management
|
- Spring Dependency Management
|
||||||
- Gradle with Kotlin DSL (6.6.1)
|
- Gradle with Kotlin DSL (6.6.1)
|
||||||
- Kotlin Langauge
|
- Kotlin Langauge (1.4.21)
|
||||||
|
|
||||||
# Development
|
# Development
|
||||||
- Clone the modules
|
- Clone the modules
|
||||||
|
@ -25,4 +25,4 @@ include("gradle-sample-module-example")
|
||||||
### Implementation module in ```build.gradle.kts```
|
### Implementation module in ```build.gradle.kts```
|
||||||
```gradle
|
```gradle
|
||||||
implementation(project(":gradle-sample-module-example"))
|
implementation(project(":gradle-sample-module-example"))
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
|
val springBootVersion = "2.4.2"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("org.springframework.boot") version "2.4.0" apply false
|
id("org.springframework.boot") version "2.4.2" apply false
|
||||||
id("io.spring.dependency-management") version "1.0.10.RELEASE" apply false
|
id("io.spring.dependency-management") version "1.0.11.RELEASE" apply false
|
||||||
kotlin("jvm") version "1.4.10" apply false
|
kotlin("jvm") version "1.4.21" apply false
|
||||||
kotlin("plugin.spring") version "1.4.10" apply false
|
kotlin("plugin.spring") version "1.4.21" apply false
|
||||||
|
kotlin("plugin.jpa") version "1.4.21" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
@ -38,4 +45,14 @@ subprojects {
|
||||||
apply {
|
apply {
|
||||||
plugin("io.spring.dependency-management")
|
plugin("io.spring.dependency-management")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
the<io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension>().apply {
|
||||||
|
imports {
|
||||||
|
mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<org.springframework.boot.gradle.tasks.bundling.BootJar> {
|
||||||
|
enabled = false
|
||||||
}
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
bash gradlew clean && bash gradlew build -x test
|
|
@ -0,0 +1,37 @@
|
||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
|
@ -0,0 +1,27 @@
|
||||||
|
plugins {
|
||||||
|
id("org.springframework.boot")
|
||||||
|
id("io.spring.dependency-management")
|
||||||
|
kotlin("jvm")
|
||||||
|
kotlin("plugin.spring")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
|
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Jar> {
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<org.springframework.boot.gradle.tasks.bundling.BootJar> {
|
||||||
|
enabled = false
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
|
@ -0,0 +1,71 @@
|
||||||
|
package com.example.customerapi
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.CommandLineRunner
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
|
import org.springframework.boot.runApplication
|
||||||
|
import org.springframework.data.annotation.Id
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Document
|
||||||
|
import org.springframework.data.mongodb.repository.MongoRepository
|
||||||
|
import org.springframework.stereotype.Repository
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
import java.io.Serializable
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
class CustomerApiApplication @Autowired constructor(
|
||||||
|
private val customerRepository: CustomerRepository,
|
||||||
|
) : CommandLineRunner {
|
||||||
|
override fun run(vararg args: String?) {
|
||||||
|
|
||||||
|
val customer = Customer.create("Sambo - ${Random.nextInt(1000)}", "Chea - ${Random.nextInt(1000)}")
|
||||||
|
|
||||||
|
val saved = customerRepository.save(customer)
|
||||||
|
|
||||||
|
println(saved)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
runApplication<CustomerApiApplication>(*args)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Document
|
||||||
|
data class Customer(
|
||||||
|
@Id
|
||||||
|
val id: String? = null,
|
||||||
|
var firstName: String,
|
||||||
|
var lastName: String,
|
||||||
|
) : Serializable {
|
||||||
|
companion object {
|
||||||
|
fun create(
|
||||||
|
firstName: String,
|
||||||
|
lastName: String
|
||||||
|
): Customer {
|
||||||
|
return Customer(null, firstName, lastName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
interface CustomerRepository : MongoRepository<Customer, String>
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/customers")
|
||||||
|
class CustomerController @Autowired constructor(
|
||||||
|
private val customerRepository: CustomerRepository
|
||||||
|
) {
|
||||||
|
@GetMapping
|
||||||
|
fun getAllCustomers(): Collection<Customer> {
|
||||||
|
return customerRepository.findAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/create")
|
||||||
|
fun createCustomer(): Customer? {
|
||||||
|
val customer = Customer.create("Sambo - ${Random.nextInt(1000)}", "Chea - ${Random.nextInt(1000)}")
|
||||||
|
return customerRepository.save(customer)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
spring.data.mongodb.uri=mongodb://192.168.0.202:27017/db-customer-api
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.example.customerapi
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class CustomerApiApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
|
@ -0,0 +1,31 @@
|
||||||
|
plugins {
|
||||||
|
id("org.springframework.boot")
|
||||||
|
id("io.spring.dependency-management")
|
||||||
|
kotlin("jvm")
|
||||||
|
kotlin("plugin.spring")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(project(":lib"))
|
||||||
|
api(project(":customer-api"))
|
||||||
|
api(project(":login-api"))
|
||||||
|
|
||||||
|
implementation("org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.3.4.RELEASE")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-security")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
|
||||||
|
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
|
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tasks.withType<org.springframework.boot.gradle.tasks.bundling.BootJar> {
|
||||||
|
enabled = true
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.example.demo
|
||||||
|
|
||||||
|
import com.example.lib.MyLib
|
||||||
|
import com.example.lib.MyUtils
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.CommandLineRunner
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
|
import org.springframework.boot.runApplication
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize
|
||||||
|
import org.springframework.security.core.Authentication
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
|
@SpringBootApplication (scanBasePackages = ["com.example.demo", "com.example.loginapi","com.example.customerapi"])
|
||||||
|
class DemoApplication @Autowired constructor(
|
||||||
|
//customerRepository: CustomerRepository,
|
||||||
|
) : CommandLineRunner {
|
||||||
|
override fun run(vararg args: String?) {
|
||||||
|
MyLib.doOnMe()
|
||||||
|
|
||||||
|
println()
|
||||||
|
|
||||||
|
println("Hello JJKK: ${MyUtils.helloWorld()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
runApplication<DemoApplication>(*args)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/oauth")
|
||||||
|
@PreAuthorize("isAuthenticated()")
|
||||||
|
class OAuthController {
|
||||||
|
@GetMapping
|
||||||
|
fun getMe(authentication: Authentication) : Any? {
|
||||||
|
return authentication
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.example.demo
|
||||||
|
|
||||||
|
import com.example.loginapi.OauthResourceServerSecurity
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sombochea <Sambo Chea>
|
||||||
|
* @email sombochea@cubetiqs.com
|
||||||
|
* @date 15/10/19
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableResourceServer
|
||||||
|
class SecurityConfig : OauthResourceServerSecurity() {
|
||||||
|
@Throws(Exception::class)
|
||||||
|
override fun configure(http: HttpSecurity) {
|
||||||
|
http.exceptionHandling()
|
||||||
|
.and()
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/api/**", "/oauth", "/customers")
|
||||||
|
.access("#oauth2.hasAnyScope('read','write')")
|
||||||
|
.antMatchers("/actuator/**")
|
||||||
|
.hasAnyRole("SUPER_ADMIN", "SYS_ADMIN","ACTUATOR")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
spring.data.mongodb.uri=mongodb://192.168.0.202:27017/db-customer-api
|
||||||
|
spring.main.allow-bean-definition-overriding=true
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.example.demo
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class DemoApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
|
@ -0,0 +1,12 @@
|
||||||
|
plugins {
|
||||||
|
id("java-library")
|
||||||
|
id("io.spring.dependency-management")
|
||||||
|
kotlin("jvm")
|
||||||
|
kotlin("plugin.spring")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.example.lib;
|
||||||
|
|
||||||
|
public final class MyUtils {
|
||||||
|
public static String helloWorld() {
|
||||||
|
return "Hello World";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.example.lib
|
||||||
|
|
||||||
|
object MyLib {
|
||||||
|
fun doOnMe() = print("hello")
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
|
@ -0,0 +1,35 @@
|
||||||
|
plugins {
|
||||||
|
id("org.springframework.boot")
|
||||||
|
id("io.spring.dependency-management")
|
||||||
|
kotlin("jvm")
|
||||||
|
kotlin("plugin.spring")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.3.4.RELEASE")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-security")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
|
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||||
|
testImplementation("org.springframework.security:spring-security-test")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Jar> {
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<org.springframework.boot.gradle.tasks.bundling.BootJar> {
|
||||||
|
enabled = false
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.example.loginapi
|
||||||
|
|
||||||
|
import org.springframework.security.oauth2.provider.OAuth2Authentication
|
||||||
|
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sombochea <Sambo Chea>
|
||||||
|
* @email sombochea@cubetiqs.com
|
||||||
|
* @date 16/10/19
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
class CubeJwtAccessTokenConverter : DefaultAccessTokenConverter() {
|
||||||
|
override fun extractAuthentication(map: Map<String?, *>?): OAuth2Authentication {
|
||||||
|
val authentication = super.extractAuthentication(map)
|
||||||
|
authentication.details = map
|
||||||
|
return authentication
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.example.loginapi
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
|
import org.springframework.boot.runApplication
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
class LoginApiApplication
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
runApplication<LoginApiApplication>(*args)
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.example.loginapi
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/login")
|
||||||
|
class LoginController {
|
||||||
|
@GetMapping
|
||||||
|
fun get(): Any? {
|
||||||
|
return RestClientUtils.getRestTemplate().getForObject("https://api-clinic.cubetiqs.com/info", Any::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
fun login(
|
||||||
|
@RequestParam(value = "username") username: String,
|
||||||
|
@RequestParam(value = "password") password: String,
|
||||||
|
): Any? {
|
||||||
|
return RestClientUtils.login(username, password)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.example.loginapi
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer
|
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter
|
||||||
|
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer
|
||||||
|
import org.springframework.security.oauth2.provider.token.DefaultTokenServices
|
||||||
|
import org.springframework.security.oauth2.provider.token.TokenStore
|
||||||
|
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter
|
||||||
|
import org.springframework.security.oauth2.provider.token.store.jwk.JwkTokenStore
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sombochea
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableResourceServer
|
||||||
|
open class OauthResourceServerSecurity :
|
||||||
|
ResourceServerConfigurerAdapter() {
|
||||||
|
private val jwtAccessTokenConverter: CubeJwtAccessTokenConverter = CubeJwtAccessTokenConverter()
|
||||||
|
|
||||||
|
@Value("\${spring.security.oauth2.resourceserver.jwt.public-key}")
|
||||||
|
var publicKey: String? = null
|
||||||
|
|
||||||
|
@Value("\${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
|
||||||
|
var jwkSetUri: String? = null
|
||||||
|
|
||||||
|
private var tokenStore: TokenStore? = null
|
||||||
|
|
||||||
|
override fun configure(resources: ResourceServerSecurityConfigurer) {
|
||||||
|
val resourceId = "cubetiq-clinic-dev"
|
||||||
|
println("Loaded system with resource id: $resourceId")
|
||||||
|
resources
|
||||||
|
.tokenStore(tokenStore())
|
||||||
|
.resourceId(resourceId)
|
||||||
|
.stateless(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(Exception::class)
|
||||||
|
override fun configure(http: HttpSecurity) {
|
||||||
|
http.exceptionHandling()
|
||||||
|
.and()
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/api/**")
|
||||||
|
.access("#oauth2.hasAnyScope('read','write')")
|
||||||
|
.antMatchers("/actuator/**")
|
||||||
|
.hasAnyRole("SUPER_ADMIN", "SYS_ADMIN","ACTUATOR")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun tokenServices(tokenStore: TokenStore?): DefaultTokenServices {
|
||||||
|
val tokenServices = DefaultTokenServices()
|
||||||
|
tokenServices.setTokenStore(tokenStore)
|
||||||
|
return tokenServices
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun tokenStore(): TokenStore? {
|
||||||
|
if (tokenStore == null) {
|
||||||
|
tokenStore = JwkTokenStore(jwkSetUri, jwtAccessTokenConverter)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenStore
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun jwtAccessTokenConverter(): JwtAccessTokenConverter {
|
||||||
|
val converter = JwtAccessTokenConverter()
|
||||||
|
converter.accessTokenConverter = jwtAccessTokenConverter
|
||||||
|
converter.setVerifierKey(publicKey)
|
||||||
|
return converter
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
@file:Suppress("unused", "unused")
|
||||||
|
|
||||||
|
package com.example.loginapi
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import org.springframework.http.*
|
||||||
|
import org.springframework.util.LinkedMultiValueMap
|
||||||
|
import org.springframework.util.MultiValueMap
|
||||||
|
import org.springframework.web.client.RestTemplate
|
||||||
|
import java.io.Serializable
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sombochea
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
object RestClientUtils {
|
||||||
|
private const val BEAN_NAME = "restTemplate"
|
||||||
|
|
||||||
|
private var restTemplate: RestTemplate? = null
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun setRestTemplate(restTemplate: RestTemplate?) {
|
||||||
|
RestClientUtils.restTemplate = restTemplate
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getRestTemplate(): RestTemplate {
|
||||||
|
if (restTemplate == null) {
|
||||||
|
restTemplate = RestTemplate()
|
||||||
|
}
|
||||||
|
return restTemplate ?: throw Exception("rest client service load failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun login(username: String, password: String): OAuthToken? {
|
||||||
|
val authEndpoint = "https://preprod-api-auth.staging.cubetiqs.com/api/oauth/token"
|
||||||
|
val httpHeaders = getHttpHeadersConfig()
|
||||||
|
val body: MultiValueMap<String, String> = LinkedMultiValueMap()
|
||||||
|
body.add("grant_type", "password")
|
||||||
|
body.add("username", username)
|
||||||
|
body.add("password", password)
|
||||||
|
|
||||||
|
val httpEntity = HttpEntity(body, httpHeaders)
|
||||||
|
|
||||||
|
println(httpEntity)
|
||||||
|
|
||||||
|
return getRestTemplate().postForEntity(authEndpoint, httpEntity, OAuthToken::class.java).body
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getHttpHeadersConfig(): HttpHeaders {
|
||||||
|
val httpHeaders = HttpHeaders()
|
||||||
|
val client = "cubetiq-clinic-dev"
|
||||||
|
val secret = "123456"
|
||||||
|
httpHeaders.contentType = MediaType.APPLICATION_FORM_URLENCODED
|
||||||
|
val clientDetail = "$client:$secret"
|
||||||
|
val oauthCodes = Base64.getEncoder().encode(clientDetail.toByteArray(StandardCharsets.US_ASCII))
|
||||||
|
httpHeaders["Authorization"] = "Basic " + String(oauthCodes)
|
||||||
|
httpHeaders["Tenant-ID"] = "TNA-00013067"
|
||||||
|
httpHeaders["User-Type"] = "INTERNAL"
|
||||||
|
return httpHeaders
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
data class OAuthToken(
|
||||||
|
@JsonProperty(value = "access_token")
|
||||||
|
var accessToken: String? = null,
|
||||||
|
@JsonProperty(value = "token_type")
|
||||||
|
var tokenType: String? = null,
|
||||||
|
@JsonProperty(value = "refresh_token")
|
||||||
|
var refreshToken: String? = null,
|
||||||
|
@JsonProperty(value = "expires_in")
|
||||||
|
var expiresIn: Long? = null,
|
||||||
|
@JsonProperty(value = "scope")
|
||||||
|
var scope: String? = null,
|
||||||
|
@JsonProperty(value = "auditor")
|
||||||
|
var auditor: String? = null,
|
||||||
|
@JsonProperty(value = "tenant")
|
||||||
|
var tenant: String? = null,
|
||||||
|
@JsonProperty(value = "user_id")
|
||||||
|
var userId: String? = null,
|
||||||
|
@JsonProperty(value = "username")
|
||||||
|
var username: String? = null,
|
||||||
|
@JsonProperty(value = "jti")
|
||||||
|
var jti: String? = null,
|
||||||
|
|
||||||
|
var passcode: Boolean? = null,
|
||||||
|
var configs: Map<String, Any?>? = null,
|
||||||
|
|
||||||
|
@JsonProperty(value = "current_branch_id")
|
||||||
|
var currentBranchId: String? = null,
|
||||||
|
@JsonProperty(value = "current_branch")
|
||||||
|
var currentBranch: String? = null,
|
||||||
|
) : Serializable {
|
||||||
|
@JsonIgnore
|
||||||
|
fun addConfig(key: String, value: Any?) = apply {
|
||||||
|
if (this.configs == null) {
|
||||||
|
this.configs = mutableMapOf()
|
||||||
|
}
|
||||||
|
(this.configs as MutableMap)[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
fun addConfigs(configs: Map<String, Any?>?) = apply {
|
||||||
|
if (this.configs == null) {
|
||||||
|
this.configs = mutableMapOf()
|
||||||
|
}
|
||||||
|
if (configs != null) {
|
||||||
|
(this.configs as MutableMap).putAll(configs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.example.loginapi
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/users")
|
||||||
|
class UserController {
|
||||||
|
@GetMapping("/me")
|
||||||
|
fun getMe(
|
||||||
|
authentication: Authentication,
|
||||||
|
): Any {
|
||||||
|
return authentication
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.example.loginapi
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
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.configuration.EnableWebSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sombochea <Sambo Chea>
|
||||||
|
* @email sombochea@cubetiqs.com
|
||||||
|
* @date 15/10/19
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
class WebSecurityConfig : WebSecurityConfigurerAdapter() {
|
||||||
|
@Throws(Exception::class)
|
||||||
|
override fun configure(http: HttpSecurity) {
|
||||||
|
http
|
||||||
|
.sessionManagement()
|
||||||
|
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
server:
|
||||||
|
port: 8015
|
||||||
|
|
||||||
|
spring:
|
||||||
|
security:
|
||||||
|
oauth2:
|
||||||
|
resourceserver:
|
||||||
|
jwt:
|
||||||
|
jwk-set-uri: ${JWK_SET_URI:https://preprod-api-auth.staging.cubetiqs.com/.well-known/jwks.json}
|
||||||
|
public-key: |
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhLjm/+1Maitij0pV4IVD
|
||||||
|
gpLZ7IAvlXxKyToTCRusFwsto3T5jZIr5pNFEPJN6XuO/2fHGlcIioRD6pC1xdHu
|
||||||
|
qoYwImNHjYrS2vRrVboBiMHgOqZ2/Qk2knyNC98vp6sBp8PDSAWSPkWgKPDR2RV0
|
||||||
|
sFoPVT+0TCtXPVrdOCPkHDvrg2M4H8NwRtec3bzv3KkIpf2TSuSSHwL9JENaXpJn
|
||||||
|
2POnZwjBADa2xIU4K3k9XdYrTDqqlnIfnj/irT8aUCQzyo5vfqy4n9eQjj/lSmhT
|
||||||
|
L76pnrIEvl0UjnfRfZ9prE6+bS2pF6d4cYXfATwC0lKkIgKjHPoyUnyleJ6qHDyN
|
||||||
|
CwIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.example.loginapi
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class LoginApiApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1 +1,3 @@
|
||||||
rootProject.name = "sample-modules"
|
rootProject.name = "sample-modules"
|
||||||
|
|
||||||
|
include("demo", "lib", "customer-api", "login-api")
|
Loading…
Reference in New Issue
Block a user