From d45139dd5841f221c2c112461977ddc93e249ddf Mon Sep 17 00:00:00 2001 From: Elex Date: Mon, 2 Aug 2021 17:02:06 +0900 Subject: [PATCH] 2021-08-02 --- .gitignore | 1 + README.md | 17 ++++ app/build.gradle.kts | 10 --- .../com/elex_project/sample/package-info.java | 1 - build.gradle.kts | 8 +- buildSrc/build.gradle.kts | 7 ++ .../main/kotlin/elex-application.gradle.kts | 17 ---- buildSrc/src/main/kotlin/elex-base.gradle.kts | 29 +++--- .../src/main/kotlin/elex-library.gradle.kts | 88 ------------------- .../main/kotlin/elex-spring-boot.gradle.kts | 18 ++++ file-upload/README.md | 1 + file-upload/build.gradle.kts | 28 ++++++ .../java/kr/pe/elex/examples/Application.java | 20 +++++ .../kr/pe/elex/examples/MyController.java | 72 +++++++++++++++ .../kr/pe/elex/examples/StorageService.java | 62 +++++++++++++ .../kr/pe/elex/examples/package-info.java | 8 ++ .../src/main/resources/application.yaml | 9 ++ file-upload/src/main/resources/banner.txt | 10 +++ .../src/main/resources/logback-spring.xml | 48 ++++++++++ .../main/resources/templates/main.mustache | 15 ++++ gradle/wrapper/gradle-wrapper.properties | 7 ++ gradlew | 15 +--- lib/build.gradle.kts | 7 -- .../com/elex_project/sample/package-info.java | 1 - logback.xml | 7 ++ security-with-jpa/README.md | 11 +++ security-with-jpa/build.gradle.kts | 33 +++++++ .../java/kr/pe/elex/examples/Application.java | 45 ++++++++++ .../kr/pe/elex/examples/MyController.java | 71 +++++++++++++++ .../kr/pe/elex/examples/SecurityConfig.java | 72 +++++++++++++++ .../java/kr/pe/elex/examples/UserService.java | 37 ++++++++ .../java/kr/pe/elex/examples/WebConfig.java | 28 ++++++ .../java/kr/pe/elex/examples/model/User.java | 76 ++++++++++++++++ .../elex/examples/model/UserRepository.java | 16 ++++ .../kr/pe/elex/examples/package-info.java | 8 ++ .../src/main/resources/application.yaml | 17 ++++ .../src/main/resources/banner.txt | 10 +++ .../src/main/resources/logback-spring.xml | 44 ++++++++++ .../main/resources/templates/home.mustache | 15 ++++ .../main/resources/templates/links.mustache | 7 ++ .../main/resources/templates/login.mustache | 11 +++ .../resources/templates/normal_info.mustache | 3 + .../resources/templates/secure_info.mustache | 4 + security/README.md | 7 ++ security/build.gradle.kts | 30 +++++++ .../java/kr/pe/elex/examples/Application.java | 20 +++++ .../kr/pe/elex/examples/MyController.java | 37 ++++++++ .../kr/pe/elex/examples/SecurityConfig.java | 55 ++++++++++++ .../java/kr/pe/elex/examples/WebConfig.java | 23 +++++ .../kr/pe/elex/examples/package-info.java | 8 ++ security/src/main/resources/application.yaml | 7 ++ security/src/main/resources/banner.txt | 10 +++ .../src/main/resources/logback-spring.xml | 44 ++++++++++ .../main/resources/templates/home.mustache | 4 + .../main/resources/templates/links.mustache | 6 ++ .../main/resources/templates/login.mustache | 11 +++ .../resources/templates/normal_info.mustache | 3 + .../resources/templates/secure_info.mustache | 8 ++ settings.gradle.kts | 9 +- testing/build.gradle.kts | 27 ++++++ .../java/kr/pe/elex/examples/Application.java | 20 +++++ .../kr/pe/elex/examples/MyController.java | 41 +++++++++ .../java/kr/pe/elex/examples/MyService.java | 17 ++++ .../kr/pe/elex/examples/package-info.java | 8 ++ .../main/resources/templates/main.mustache | 2 + .../kr/pe/elex/examples/ApplicationTest.java | 28 ++++++ .../kr/pe/elex/examples/ControllerTest1.java | 55 ++++++++++++ .../kr/pe/elex/examples/ControllerTest2.java | 51 +++++++++++ .../kr/pe/elex/examples/ControllerTest3.java | 51 +++++++++++ validation/README.md | 29 ++++++ validation/build.gradle.kts | 29 ++++++ .../java/kr/pe/elex/examples/Application.java | 20 +++++ .../kr/pe/elex/examples/MyController.java | 63 +++++++++++++ .../kr/pe/elex/examples/model/Person.java | 29 ++++++ .../kr/pe/elex/examples/package-info.java | 8 ++ .../src/main/resources/application.yaml | 5 ++ validation/src/main/resources/banner.txt | 10 +++ .../src/main/resources/logback-spring.xml | 47 ++++++++++ .../main/resources/templates/home.mustache | 1 + 79 files changed, 1685 insertions(+), 152 deletions(-) create mode 100644 README.md delete mode 100644 app/build.gradle.kts delete mode 100644 app/src/main/java/com/elex_project/sample/package-info.java delete mode 100644 buildSrc/src/main/kotlin/elex-application.gradle.kts delete mode 100644 buildSrc/src/main/kotlin/elex-library.gradle.kts create mode 100644 buildSrc/src/main/kotlin/elex-spring-boot.gradle.kts create mode 100644 file-upload/README.md create mode 100644 file-upload/build.gradle.kts create mode 100644 file-upload/src/main/java/kr/pe/elex/examples/Application.java create mode 100644 file-upload/src/main/java/kr/pe/elex/examples/MyController.java create mode 100644 file-upload/src/main/java/kr/pe/elex/examples/StorageService.java create mode 100644 file-upload/src/main/java/kr/pe/elex/examples/package-info.java create mode 100644 file-upload/src/main/resources/application.yaml create mode 100644 file-upload/src/main/resources/banner.txt create mode 100644 file-upload/src/main/resources/logback-spring.xml create mode 100644 file-upload/src/main/resources/templates/main.mustache delete mode 100644 lib/build.gradle.kts delete mode 100644 lib/src/main/java/com/elex_project/sample/package-info.java create mode 100644 security-with-jpa/README.md create mode 100644 security-with-jpa/build.gradle.kts create mode 100644 security-with-jpa/src/main/java/kr/pe/elex/examples/Application.java create mode 100644 security-with-jpa/src/main/java/kr/pe/elex/examples/MyController.java create mode 100644 security-with-jpa/src/main/java/kr/pe/elex/examples/SecurityConfig.java create mode 100644 security-with-jpa/src/main/java/kr/pe/elex/examples/UserService.java create mode 100644 security-with-jpa/src/main/java/kr/pe/elex/examples/WebConfig.java create mode 100644 security-with-jpa/src/main/java/kr/pe/elex/examples/model/User.java create mode 100644 security-with-jpa/src/main/java/kr/pe/elex/examples/model/UserRepository.java create mode 100644 security-with-jpa/src/main/java/kr/pe/elex/examples/package-info.java create mode 100644 security-with-jpa/src/main/resources/application.yaml create mode 100644 security-with-jpa/src/main/resources/banner.txt create mode 100644 security-with-jpa/src/main/resources/logback-spring.xml create mode 100644 security-with-jpa/src/main/resources/templates/home.mustache create mode 100644 security-with-jpa/src/main/resources/templates/links.mustache create mode 100644 security-with-jpa/src/main/resources/templates/login.mustache create mode 100644 security-with-jpa/src/main/resources/templates/normal_info.mustache create mode 100644 security-with-jpa/src/main/resources/templates/secure_info.mustache create mode 100644 security/README.md create mode 100644 security/build.gradle.kts create mode 100644 security/src/main/java/kr/pe/elex/examples/Application.java create mode 100644 security/src/main/java/kr/pe/elex/examples/MyController.java create mode 100644 security/src/main/java/kr/pe/elex/examples/SecurityConfig.java create mode 100644 security/src/main/java/kr/pe/elex/examples/WebConfig.java create mode 100644 security/src/main/java/kr/pe/elex/examples/package-info.java create mode 100644 security/src/main/resources/application.yaml create mode 100644 security/src/main/resources/banner.txt create mode 100644 security/src/main/resources/logback-spring.xml create mode 100644 security/src/main/resources/templates/home.mustache create mode 100644 security/src/main/resources/templates/links.mustache create mode 100644 security/src/main/resources/templates/login.mustache create mode 100644 security/src/main/resources/templates/normal_info.mustache create mode 100644 security/src/main/resources/templates/secure_info.mustache create mode 100644 testing/build.gradle.kts create mode 100644 testing/src/main/java/kr/pe/elex/examples/Application.java create mode 100644 testing/src/main/java/kr/pe/elex/examples/MyController.java create mode 100644 testing/src/main/java/kr/pe/elex/examples/MyService.java create mode 100644 testing/src/main/java/kr/pe/elex/examples/package-info.java create mode 100644 testing/src/main/resources/templates/main.mustache create mode 100644 testing/src/test/java/kr/pe/elex/examples/ApplicationTest.java create mode 100644 testing/src/test/java/kr/pe/elex/examples/ControllerTest1.java create mode 100644 testing/src/test/java/kr/pe/elex/examples/ControllerTest2.java create mode 100644 testing/src/test/java/kr/pe/elex/examples/ControllerTest3.java create mode 100644 validation/README.md create mode 100644 validation/build.gradle.kts create mode 100644 validation/src/main/java/kr/pe/elex/examples/Application.java create mode 100644 validation/src/main/java/kr/pe/elex/examples/MyController.java create mode 100644 validation/src/main/java/kr/pe/elex/examples/model/Person.java create mode 100644 validation/src/main/java/kr/pe/elex/examples/package-info.java create mode 100644 validation/src/main/resources/application.yaml create mode 100644 validation/src/main/resources/banner.txt create mode 100644 validation/src/main/resources/logback-spring.xml create mode 100644 validation/src/main/resources/templates/home.mustache diff --git a/.gitignore b/.gitignore index 37b747d..3ae393a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /buildSrc/build/ /.idea/ /build/ +/**/build/** diff --git a/README.md b/README.md new file mode 100644 index 0000000..917628b --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Spring-boot Examples + +## File Upload + +## Security + +## Security plus JPA + +## Testing + +## Validation + + +------ +developed by Elex + +https://www.elex-project.com/ diff --git a/app/build.gradle.kts b/app/build.gradle.kts deleted file mode 100644 index dc482ed..0000000 --- a/app/build.gradle.kts +++ /dev/null @@ -1,10 +0,0 @@ -plugins { - id("elex-application") -} -application{ - mainClass.set("com.elex_project.sample.Application") -} -dependencies { - - -} diff --git a/app/src/main/java/com/elex_project/sample/package-info.java b/app/src/main/java/com/elex_project/sample/package-info.java deleted file mode 100644 index f7a784a..0000000 --- a/app/src/main/java/com/elex_project/sample/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package com.elex_project.sample; diff --git a/build.gradle.kts b/build.gradle.kts index e4f4545..4d94bfc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,16 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + buildscript { repositories { maven { url = uri("https://repository.elex-project.com/repository/maven") } } - dependencies { classpath ("com.jaredsburrows:gradle-license-plugin:0.8.90") } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index d32bb9b..7020c37 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,3 +1,10 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + plugins{ `kotlin-dsl` } diff --git a/buildSrc/src/main/kotlin/elex-application.gradle.kts b/buildSrc/src/main/kotlin/elex-application.gradle.kts deleted file mode 100644 index 793b831..0000000 --- a/buildSrc/src/main/kotlin/elex-application.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ - -plugins { - id("elex-base") - application -} - -tasks.jar { - manifest { - attributes(mapOf( - "Implementation-Title" to project.name, - "Implementation-Version" to project.version, - "Implementation-Vendor" to "ELEX co.,pte.", - "Main-Class" to application.mainClass, - "Automatic-Module-Name" to "com.elex_project.${project.name}" - )) - } -} diff --git a/buildSrc/src/main/kotlin/elex-base.gradle.kts b/buildSrc/src/main/kotlin/elex-base.gradle.kts index 33e0f03..b0181a6 100644 --- a/buildSrc/src/main/kotlin/elex-base.gradle.kts +++ b/buildSrc/src/main/kotlin/elex-base.gradle.kts @@ -1,10 +1,19 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + + plugins { java + idea } -group = "com.elex-project" +group = "kr.pe.elex.examples" version = "1.0-SNAPSHOT" -description = ""//todo +description = "Examples: Spring-boot" repositories { maven { @@ -29,12 +38,11 @@ configurations { } tasks.jar { - manifest { // todo + manifest { attributes(mapOf( "Implementation-Title" to project.name, "Implementation-Version" to project.version, - "Implementation-Vendor" to "ELEX co.,pte.", - "Automatic-Module-Name" to "com.elex_project.${project.name}" + "Implementation-Vendor" to "ELEX co.,pte." )) } } @@ -60,16 +68,9 @@ tasks.javadoc { (options as StandardJavadocDocletOptions).docEncoding = "UTF-8" } + dependencies { - implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) - implementation("org.slf4j:slf4j-api:1.7.30") + implementation("org.jetbrains:annotations:21.0.1") - compileOnly("org.projectlombok:lombok:1.18.20") - annotationProcessor("org.projectlombok:lombok:1.18.20") - testAnnotationProcessor("org.projectlombok:lombok:1.18.20") - - testImplementation("ch.qos.logback:logback-classic:1.2.3") - testImplementation("org.junit.jupiter:junit-jupiter:5.7.0") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0") } diff --git a/buildSrc/src/main/kotlin/elex-library.gradle.kts b/buildSrc/src/main/kotlin/elex-library.gradle.kts deleted file mode 100644 index 860dd6a..0000000 --- a/buildSrc/src/main/kotlin/elex-library.gradle.kts +++ /dev/null @@ -1,88 +0,0 @@ -plugins { - id ("elex-base") - `java-library` - `maven-publish` -} - -publishing { - publications { - create("mavenJava") { - from(components["java"]) - pom { - // todo - name.set(project.name) - description.set(project.description) - url.set("https://") - inceptionYear.set("2021") - properties.set(mapOf( - "myProp" to "value", - "prop.with.dots" to "anotherValue" - )) - organization { - name.set("Elex co.,Pte.") - url.set("https://www.elex-project.com/") - } - licenses { - license { - // todo - name.set("BSD 3-Clause License") - url.set("licenseUrl") - comments.set("") - } - } - developers { - developer { - id.set("elex") - name.set("Elex") - url.set("https://www.elex.pe.kr/") - email.set("developer@elex-project.com") - organization.set("Elex Co.,Pte.") - organizationUrl.set("https://www.elex-project.com/") - roles.set(arrayListOf("Developer", "CEO")) - timezone.set("Asia/Seoul") - properties.set(mapOf("" to "")) - } - } - contributors { - contributor { - name.set("") - email.set("") - url.set("") - } - } - scm { - // todo - connection.set("scm:git:https://github.com/my-library.git") - developerConnection.set("scm:git:https://github.com/my-library.git") - url.set("https://github.com/my-library/") - } - } - } - } - - repositories { - maven { - name = "mavenElex" - val urlRelease = uri("https://repository.elex-project.com/repository/maven-releases") - val urlSnapshot = uri("https://repository.elex-project.com/repository/maven-snapshots") - url = if (version.toString().endsWith("SNAPSHOT")) urlSnapshot else urlRelease - // Repository credential, Must be defined in ~/.gradle/gradle.properties - credentials { - username = project.findProperty("repo.username") as String - password = project.findProperty("repo.password") as String - } - } - maven { //todo - name = "mavenGithub" - url = uri("https://maven.pkg.github.com/elex-project/tmpl-java-library") - credentials { - username = project.findProperty("github.username") as String - password = project.findProperty("github.token") as String - } - } - } -} - -dependencies { - -} diff --git a/buildSrc/src/main/kotlin/elex-spring-boot.gradle.kts b/buildSrc/src/main/kotlin/elex-spring-boot.gradle.kts new file mode 100644 index 0000000..84907f6 --- /dev/null +++ b/buildSrc/src/main/kotlin/elex-spring-boot.gradle.kts @@ -0,0 +1,18 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + + +plugins { + id("elex-base") + +} + +dependencies{ + implementation("org.jetbrains:annotations:21.0.1") + + +} diff --git a/file-upload/README.md b/file-upload/README.md new file mode 100644 index 0000000..704b492 --- /dev/null +++ b/file-upload/README.md @@ -0,0 +1 @@ +# 파일 업로드 diff --git a/file-upload/build.gradle.kts b/file-upload/build.gradle.kts new file mode 100644 index 0000000..596d7fe --- /dev/null +++ b/file-upload/build.gradle.kts @@ -0,0 +1,28 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +plugins { + id("elex-spring-boot") + + id("org.springframework.boot") version "2.5.3" + id("io.spring.dependency-management") version "1.0.11.RELEASE" +} + +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-mustache") + + compileOnly("org.projectlombok:lombok") + developmentOnly("org.springframework.boot:spring-boot-devtools") + runtimeOnly("org.mariadb.jdbc:mariadb-java-client") + + annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") + annotationProcessor("org.projectlombok:lombok") + + testImplementation("org.springframework.boot:spring-boot-starter-test") + +} diff --git a/file-upload/src/main/java/kr/pe/elex/examples/Application.java b/file-upload/src/main/java/kr/pe/elex/examples/Application.java new file mode 100644 index 0000000..7ff4bbf --- /dev/null +++ b/file-upload/src/main/java/kr/pe/elex/examples/Application.java @@ -0,0 +1,20 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/file-upload/src/main/java/kr/pe/elex/examples/MyController.java b/file-upload/src/main/java/kr/pe/elex/examples/MyController.java new file mode 100644 index 0000000..b565ef4 --- /dev/null +++ b/file-upload/src/main/java/kr/pe/elex/examples/MyController.java @@ -0,0 +1,72 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.ContentDisposition; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +@Slf4j +@Controller +public class MyController { + @Autowired + private StorageService storageService; + + @GetMapping(path = {"/"}) + public String index(@NotNull Model model) { + model.addAttribute("files", storageService.listFiles()); + return "main"; + } + + /** + * 파일 업로드 + * @param file + * @param redirectAttributes + * @return + */ + @PostMapping(path = {"/upload"}) + public String upload(final @RequestParam("file") MultipartFile file, + final @NotNull RedirectAttributes redirectAttributes) { + storageService.store(file); + + // 업로드 후 새로 고침 + redirectAttributes.addFlashAttribute("message", + "You successfully uploaded " + file.getOriginalFilename() + "!"); + return "redirect:/"; + } + + /** + * 파일 다운로드 + * @param filename + * @return + */ + @GetMapping("/files/{filename:.+}") + @ResponseBody + public ResponseEntity serveFile(@PathVariable String filename) { + + final Resource file = storageService.loadAsResource(filename); + + final ContentDisposition contentDisposition = ContentDisposition.attachment() + .filename(filename) + .build(); + + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, + contentDisposition.toString()) + .body(file); + } +} diff --git a/file-upload/src/main/java/kr/pe/elex/examples/StorageService.java b/file-upload/src/main/java/kr/pe/elex/examples/StorageService.java new file mode 100644 index 0000000..d7a45ca --- /dev/null +++ b/file-upload/src/main/java/kr/pe/elex/examples/StorageService.java @@ -0,0 +1,62 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +@Slf4j +@Service +public class StorageService { + /* + 테스트용 임시 파일 저장소 + 실제로는 파일시스템에 저장하거나 DB에 저장해야 한다. + */ + private final Map storage = new HashMap<>(); + + /** + * 저장된 파일 목록 + * @return + */ + Set listFiles(){ + return storage.keySet(); + } + + /** + * 파일을 저장 + * @param file + */ + void store(final @NotNull MultipartFile file) { + try { + storage.put(file.getOriginalFilename(), file.getBytes()); + log.info("File Uploaded... {}", file.getOriginalFilename()); + + } catch (IOException e) { + log.error("Unable to save a file.", e); + } + } + + /** + * 저장된 파일을 불러옴 + * @param filename + * @return + */ + Resource loadAsResource(final String filename) { + //return new FileSystemResource(new File(filename)); + return new ByteArrayResource(storage.get(filename)); + } +} diff --git a/file-upload/src/main/java/kr/pe/elex/examples/package-info.java b/file-upload/src/main/java/kr/pe/elex/examples/package-info.java new file mode 100644 index 0000000..ce9cc62 --- /dev/null +++ b/file-upload/src/main/java/kr/pe/elex/examples/package-info.java @@ -0,0 +1,8 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; diff --git a/file-upload/src/main/resources/application.yaml b/file-upload/src/main/resources/application.yaml new file mode 100644 index 0000000..8448219 --- /dev/null +++ b/file-upload/src/main/resources/application.yaml @@ -0,0 +1,9 @@ +spring: + application: + name: My spring-boot project + servlet: + multipart: + max-file-size: 128KB + max-request-size: 128KB +server: + port: 8080 diff --git a/file-upload/src/main/resources/banner.txt b/file-upload/src/main/resources/banner.txt new file mode 100644 index 0000000..f7a35db --- /dev/null +++ b/file-upload/src/main/resources/banner.txt @@ -0,0 +1,10 @@ + ('-. ('-. ) (`-. + _( OO) _( OO) ( OO ). +(,------.,--. (,------.(_/. \_)-. + | .---'| |.-') | .---' \ `.' / + | | | | OO ) | | \ /\ +(| '--. | |`-' |(| '--. \ \ | + | .--'(| '---.' | .--' .' \_) + | `---.| | | `---. / .'. \ + `------'`------' `------''--' '--' +powered by ELEX diff --git a/file-upload/src/main/resources/logback-spring.xml b/file-upload/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..19f023b --- /dev/null +++ b/file-upload/src/main/resources/logback-spring.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + + UTF-8 + ${FILE_LOG_PATTERN} + + ${LOG_PATH} + + ${LOG_DIR}/sebastian_%d{yyyy-MM-dd}_%i.log.gz + + 10MB + + 60 + + + + + + + + + + + + + diff --git a/file-upload/src/main/resources/templates/main.mustache b/file-upload/src/main/resources/templates/main.mustache new file mode 100644 index 0000000..811061b --- /dev/null +++ b/file-upload/src/main/resources/templates/main.mustache @@ -0,0 +1,15 @@ +

File Upload Example!!!

+
+ + +
+ +
+
+

Uploaded Files

+

Click to download.

+
    + {{#files}} +
  • {{.}}
  • + {{/files}} +
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index af7be50..137b49c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,3 +1,10 @@ +# +# Spring-boot Examples +# +# Copyright (c) 2021. Elex. All Rights Reserved. +# https://www.elex-project.com/ +# + distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-all.zip diff --git a/gradlew b/gradlew index 4f906e0..fe30a67 100755 --- a/gradlew +++ b/gradlew @@ -1,19 +1,10 @@ #!/usr/bin/env sh # -# Copyright 2015 the original author or authors. +# Spring-boot Examples # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (c) 2021. Elex. All Rights Reserved. +# https://www.elex-project.com/ # ############################################################################## diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts deleted file mode 100644 index 8367881..0000000 --- a/lib/build.gradle.kts +++ /dev/null @@ -1,7 +0,0 @@ -plugins { - id("elex-library") -} - -dependencies { - -} diff --git a/lib/src/main/java/com/elex_project/sample/package-info.java b/lib/src/main/java/com/elex_project/sample/package-info.java deleted file mode 100644 index f7a784a..0000000 --- a/lib/src/main/java/com/elex_project/sample/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package com.elex_project.sample; diff --git a/logback.xml b/logback.xml index 17e6b52..c332e77 100644 --- a/logback.xml +++ b/logback.xml @@ -1,4 +1,11 @@ + + diff --git a/security-with-jpa/README.md b/security-with-jpa/README.md new file mode 100644 index 0000000..dbd312d --- /dev/null +++ b/security-with-jpa/README.md @@ -0,0 +1,11 @@ +# Security Examples +with Spring-boot + JPA + +이 [예제](https://github.com/elex-project/spring-boot-security-examples)를 먼저 봐야 합니다. + + + +--- +developed by Elex + +https://www.elex-project.com diff --git a/security-with-jpa/build.gradle.kts b/security-with-jpa/build.gradle.kts new file mode 100644 index 0000000..9c6d3ba --- /dev/null +++ b/security-with-jpa/build.gradle.kts @@ -0,0 +1,33 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +plugins { + id("elex-spring-boot") + + id("org.springframework.boot") version "2.5.3" + id("io.spring.dependency-management") version "1.0.11.RELEASE" +} + +dependencies { + implementation("org.springframework.boot:spring-boot-starter-mustache") + implementation("org.springframework.boot:spring-boot-starter-web") + + implementation ("org.springframework.boot:spring-boot-starter-security") + testImplementation ("org.springframework.security:spring-security-test") + + implementation ("org.springframework.boot:spring-boot-starter-data-jpa") + runtimeOnly("com.h2database:h2") + + compileOnly("org.projectlombok:lombok") + developmentOnly("org.springframework.boot:spring-boot-devtools") + runtimeOnly("org.mariadb.jdbc:mariadb-java-client") + + annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") + annotationProcessor("org.projectlombok:lombok") + + testImplementation("org.springframework.boot:spring-boot-starter-test") +} diff --git a/security-with-jpa/src/main/java/kr/pe/elex/examples/Application.java b/security-with-jpa/src/main/java/kr/pe/elex/examples/Application.java new file mode 100644 index 0000000..e8a7668 --- /dev/null +++ b/security-with-jpa/src/main/java/kr/pe/elex/examples/Application.java @@ -0,0 +1,45 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import kr.pe.elex.examples.model.User; +import kr.pe.elex.examples.model.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +@SpringBootApplication +public class Application { + + @Autowired + private UserRepository repository; + @Autowired + private PasswordEncoder passwordEncoder; + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + /** + * 실제 프로젝트에서는 입력 폼을 통해서 회원 가입을 하겠지만, ... + * + */ + @Component + public class SetupUsers implements CommandLineRunner { + + @Override + public void run(String... args) throws Exception { + User user = new User("Charlie", "user1", passwordEncoder.encode("pw1")); + repository.save(user); + } + + } +} diff --git a/security-with-jpa/src/main/java/kr/pe/elex/examples/MyController.java b/security-with-jpa/src/main/java/kr/pe/elex/examples/MyController.java new file mode 100644 index 0000000..48618c4 --- /dev/null +++ b/security-with-jpa/src/main/java/kr/pe/elex/examples/MyController.java @@ -0,0 +1,71 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import kr.pe.elex.examples.model.User; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +@Slf4j +@Controller +public class MyController { + + /** + * 로그인한 사용자 정보를 가져오려면, Authentication을 사용합니다. + * 또는, @AuthenticationPrincipal를 사용합니다. + * + * @param authentication + * @param model + * @return + */ + @GetMapping({"/"}) + public String index(Authentication authentication, Model model) { + if (null != authentication) { + User user = (User) (authentication.getPrincipal()); + log.info("USER: {}", user.getName()); + + model.addAttribute("user", user); + } else { + log.info("NO USER: "); + } + return "home"; + } + + @GetMapping({"/login"}) + public String login() { + + return "login"; + } + + @GetMapping({"/info"}) + public String info() { + return "normal_info"; + } + + /** + * 로그인한 사용자 정보를 가져오기 위해, @AuthenticationPrincipal를 사용합니다. + * + * @param user + * @param model + * @return + */ + @GetMapping({"/secure"}) + public String secure(@AuthenticationPrincipal User user, Model model) { + if (null != user) { + log.info("USER: {}", user.getName()); + } else { + log.info("NO USER!!"); + } + model.addAttribute("user", user); + return "secure_info"; + } +} diff --git a/security-with-jpa/src/main/java/kr/pe/elex/examples/SecurityConfig.java b/security-with-jpa/src/main/java/kr/pe/elex/examples/SecurityConfig.java new file mode 100644 index 0000000..8b3aaad --- /dev/null +++ b/security-with-jpa/src/main/java/kr/pe/elex/examples/SecurityConfig.java @@ -0,0 +1,72 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +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.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private UserService userService; + + @Override + protected void configure(@NotNull HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/", "/info", "/h2-console").permitAll() // 아무나 접근 가능 + .antMatchers("/h2-console/**").permitAll() // H2콘솔을 쓰기 위해 추가했음 + //.antMatchers("/admin").hasAnyRole("ADMIN") + .anyRequest().authenticated() // 그 외에는 인증해야 접근 가능 + .and() + .formLogin()// 커스텀 로그인 폼 + .loginPage("/login") + .usernameParameter("user_id") // 로그인 폼 매개변수명 지정 + .passwordParameter("user_pw") + .permitAll() + .and() + .logout()// 로그아웃 + .logoutSuccessUrl("/") + .permitAll() + //.and().httpBasic(); + .and().csrf().ignoringAntMatchers("/h2-console/**")// H2콘솔을 쓰기 위해 추가했음 + .and().headers().frameOptions().sameOrigin()// H2콘솔을 쓰기 위해 추가했음 + //.and().csrf().disable() + ; + } + + + @Override + protected void configure(@NotNull AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userService) + .passwordEncoder(passwordEncoder()) + /*auth.inMemoryAuthentication() + .withUser("user1") + .password("{noop}pw1") + .authorities("ROLE_USER") + .and() + .withUser("user2") + .password("{noop}pw2") + .authorities("ROLE_USER")*/ + ; + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/security-with-jpa/src/main/java/kr/pe/elex/examples/UserService.java b/security-with-jpa/src/main/java/kr/pe/elex/examples/UserService.java new file mode 100644 index 0000000..88f1d9a --- /dev/null +++ b/security-with-jpa/src/main/java/kr/pe/elex/examples/UserService.java @@ -0,0 +1,37 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import kr.pe.elex.examples.model.User; +import kr.pe.elex.examples.model.UserRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +/** + * UserDetailsService를 구현해서 사용자를 조회할 수 있는 서비스를 만듭니다. + */ +@Slf4j +@Service +public class UserService implements UserDetailsService { + @Autowired + private UserRepository repository; + + @Override + public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException { + final User user = repository.findByUsername(username); + if (null == user) { + throw new UsernameNotFoundException("Unable to find a user with " + username); + } else { + return user; + } + } +} diff --git a/security-with-jpa/src/main/java/kr/pe/elex/examples/WebConfig.java b/security-with-jpa/src/main/java/kr/pe/elex/examples/WebConfig.java new file mode 100644 index 0000000..53bd0a3 --- /dev/null +++ b/security-with-jpa/src/main/java/kr/pe/elex/examples/WebConfig.java @@ -0,0 +1,28 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import kr.pe.elex.examples.model.User; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.Authentication; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Slf4j +@Configuration +public class WebConfig implements WebMvcConfigurer { + /* + @Override + public void addViewControllers(@NotNull ViewControllerRegistry registry) { + registry.addViewController("/login"); + } + */ + +} diff --git a/security-with-jpa/src/main/java/kr/pe/elex/examples/model/User.java b/security-with-jpa/src/main/java/kr/pe/elex/examples/model/User.java new file mode 100644 index 0000000..b263cc2 --- /dev/null +++ b/security-with-jpa/src/main/java/kr/pe/elex/examples/model/User.java @@ -0,0 +1,76 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples.model; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import javax.persistence.*; +import java.util.*; + +/** + * UserDetails를 구현해서 데이터 모델을 만듭니다. + */ +@Table(name = "User") +@Entity +@Getter +@Setter +@RequiredArgsConstructor +@ToString +public class User implements UserDetails { + @Column(nullable = false) + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String username; + private String password; + private String name; + private String role; + private boolean enabled; + + public User(String name, String username, String password){ + this(); + this.username = username; + this.password = password; + this.name = name; + this.role = "ROLE_USER"; + this.enabled = true; + + } + + @Override + public Collection getAuthorities() { + return Arrays.asList(new SimpleGrantedAuthority(role)); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return enabled; + } +} diff --git a/security-with-jpa/src/main/java/kr/pe/elex/examples/model/UserRepository.java b/security-with-jpa/src/main/java/kr/pe/elex/examples/model/UserRepository.java new file mode 100644 index 0000000..459bb2b --- /dev/null +++ b/security-with-jpa/src/main/java/kr/pe/elex/examples/model/UserRepository.java @@ -0,0 +1,16 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples.model; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserRepository extends JpaRepository { + User findByUsername(String username); +} diff --git a/security-with-jpa/src/main/java/kr/pe/elex/examples/package-info.java b/security-with-jpa/src/main/java/kr/pe/elex/examples/package-info.java new file mode 100644 index 0000000..ce9cc62 --- /dev/null +++ b/security-with-jpa/src/main/java/kr/pe/elex/examples/package-info.java @@ -0,0 +1,8 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; diff --git a/security-with-jpa/src/main/resources/application.yaml b/security-with-jpa/src/main/resources/application.yaml new file mode 100644 index 0000000..505f7d1 --- /dev/null +++ b/security-with-jpa/src/main/resources/application.yaml @@ -0,0 +1,17 @@ +spring: + application: + name: My spring-boot project + mustache: + expose-request-attributes: true # 뷰에서 CSRF를 뿌려주기 위해서 필요합니다. + h2: + console: + enabled: true + datasource: + url: jdbc:h2:mem:testdb + driverClassName: org.h2.Driver + username: sa + password: pw + jpa: + database-platform: org.hibernate.dialect.H2Dialect +server: + port: 8080 diff --git a/security-with-jpa/src/main/resources/banner.txt b/security-with-jpa/src/main/resources/banner.txt new file mode 100644 index 0000000..f7a35db --- /dev/null +++ b/security-with-jpa/src/main/resources/banner.txt @@ -0,0 +1,10 @@ + ('-. ('-. ) (`-. + _( OO) _( OO) ( OO ). +(,------.,--. (,------.(_/. \_)-. + | .---'| |.-') | .---' \ `.' / + | | | | OO ) | | \ /\ +(| '--. | |`-' |(| '--. \ \ | + | .--'(| '---.' | .--' .' \_) + | `---.| | | `---. / .'. \ + `------'`------' `------''--' '--' +powered by ELEX diff --git a/security-with-jpa/src/main/resources/logback-spring.xml b/security-with-jpa/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..6a38996 --- /dev/null +++ b/security-with-jpa/src/main/resources/logback-spring.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + + UTF-8 + ${FILE_LOG_PATTERN} + + ${LOG_PATH} + + ${LOG_DIR}/sebastian_%d{yyyy-MM-dd}_%i.log.gz + + 10MB + + 60 + + + + + + + + + diff --git a/security-with-jpa/src/main/resources/templates/home.mustache b/security-with-jpa/src/main/resources/templates/home.mustache new file mode 100644 index 0000000..642ccd7 --- /dev/null +++ b/security-with-jpa/src/main/resources/templates/home.mustache @@ -0,0 +1,15 @@ +

+

테스트 페이지입니다.

+{{#user}} + 안녕, {{name}}. + +
+ {{! CSRF 토큰이 없으면 에러 남. }} + + +
+{{/user}} +{{^user}} + +{{/user}} +{{> links}} diff --git a/security-with-jpa/src/main/resources/templates/links.mustache b/security-with-jpa/src/main/resources/templates/links.mustache new file mode 100644 index 0000000..f5601cb --- /dev/null +++ b/security-with-jpa/src/main/resources/templates/links.mustache @@ -0,0 +1,7 @@ +
+ | + 일반 | + 중요 | + 로그인 | + DB +
diff --git a/security-with-jpa/src/main/resources/templates/login.mustache b/security-with-jpa/src/main/resources/templates/login.mustache new file mode 100644 index 0000000..642875e --- /dev/null +++ b/security-with-jpa/src/main/resources/templates/login.mustache @@ -0,0 +1,11 @@ +

로그인

+
+ + + + + + +
+ +{{> links}} diff --git a/security-with-jpa/src/main/resources/templates/normal_info.mustache b/security-with-jpa/src/main/resources/templates/normal_info.mustache new file mode 100644 index 0000000..551c0cf --- /dev/null +++ b/security-with-jpa/src/main/resources/templates/normal_info.mustache @@ -0,0 +1,3 @@ +

아무나 볼 수 있는 페이지

+

This page doesn't contain any Important messages.

+{{> links}} diff --git a/security-with-jpa/src/main/resources/templates/secure_info.mustache b/security-with-jpa/src/main/resources/templates/secure_info.mustache new file mode 100644 index 0000000..0b3353a --- /dev/null +++ b/security-with-jpa/src/main/resources/templates/secure_info.mustache @@ -0,0 +1,4 @@ +

로그인해야 볼 수 있는 페이지

+

This page contains a Important message.

+{{#user}}Hello, {{name}}{{/user}} +{{> links}} diff --git a/security/README.md b/security/README.md new file mode 100644 index 0000000..f0ce32e --- /dev/null +++ b/security/README.md @@ -0,0 +1,7 @@ +# Security Examples +with Spring-boot + +--- +developed by Elex + +https://www.elex-project.com diff --git a/security/build.gradle.kts b/security/build.gradle.kts new file mode 100644 index 0000000..c36bd2c --- /dev/null +++ b/security/build.gradle.kts @@ -0,0 +1,30 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +plugins { + id("elex-spring-boot") + + id("org.springframework.boot") version "2.5.3" + id("io.spring.dependency-management") version "1.0.11.RELEASE" +} + +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-mustache") + + implementation ("org.springframework.boot:spring-boot-starter-security") + testImplementation ("org.springframework.security:spring-security-test") + + compileOnly("org.projectlombok:lombok") + developmentOnly("org.springframework.boot:spring-boot-devtools") + runtimeOnly("org.mariadb.jdbc:mariadb-java-client") + + annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") + annotationProcessor("org.projectlombok:lombok") + + testImplementation("org.springframework.boot:spring-boot-starter-test") +} diff --git a/security/src/main/java/kr/pe/elex/examples/Application.java b/security/src/main/java/kr/pe/elex/examples/Application.java new file mode 100644 index 0000000..7ff4bbf --- /dev/null +++ b/security/src/main/java/kr/pe/elex/examples/Application.java @@ -0,0 +1,20 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/security/src/main/java/kr/pe/elex/examples/MyController.java b/security/src/main/java/kr/pe/elex/examples/MyController.java new file mode 100644 index 0000000..ed38ca9 --- /dev/null +++ b/security/src/main/java/kr/pe/elex/examples/MyController.java @@ -0,0 +1,37 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Slf4j +@Controller +public class MyController { + + @GetMapping({"/"}) + public String index() { + return "home"; + } + + @GetMapping({"/login"}) + public String login() { + return "login"; + } + + @GetMapping({"/info"}) + public String info() { + return "normal_info"; + } + + @GetMapping({"/secure"}) + public String secure() { + return "secure_info"; + } +} diff --git a/security/src/main/java/kr/pe/elex/examples/SecurityConfig.java b/security/src/main/java/kr/pe/elex/examples/SecurityConfig.java new file mode 100644 index 0000000..90e399b --- /dev/null +++ b/security/src/main/java/kr/pe/elex/examples/SecurityConfig.java @@ -0,0 +1,55 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.jetbrains.annotations.NotNull; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +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; + +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(@NotNull HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/", "/info").permitAll() // 아무나 접근 가능 + //.antMatchers("/admin").hasAnyRole("ADMIN") + .anyRequest().authenticated() // 그 외에는 인증해야 접근 가능 + .and() + .formLogin()// 커스텀 로그인 폼 + .loginPage("/login") + .usernameParameter("user_id") // 로그인 폼 매개변수명 지정 + .passwordParameter("user_pw") + .permitAll() + .and() + .logout()// 로그아웃 + .logoutSuccessUrl("/") + .permitAll() + //.and().httpBasic(); + //.and().csrf().disable() + ; + } + + + @Override + protected void configure(@NotNull AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("user1") + .password("{noop}pw1") + .authorities("ROLE_USER") + .and() + .withUser("user2") + .password("{noop}pw2") + .authorities("ROLE_USER") + ; + } +} diff --git a/security/src/main/java/kr/pe/elex/examples/WebConfig.java b/security/src/main/java/kr/pe/elex/examples/WebConfig.java new file mode 100644 index 0000000..d3f3e28 --- /dev/null +++ b/security/src/main/java/kr/pe/elex/examples/WebConfig.java @@ -0,0 +1,23 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Slf4j +@Configuration +public class WebConfig implements WebMvcConfigurer { + /* + @Override + public void addViewControllers(@NotNull ViewControllerRegistry registry) { + registry.addViewController("/login"); + } + */ +} diff --git a/security/src/main/java/kr/pe/elex/examples/package-info.java b/security/src/main/java/kr/pe/elex/examples/package-info.java new file mode 100644 index 0000000..ce9cc62 --- /dev/null +++ b/security/src/main/java/kr/pe/elex/examples/package-info.java @@ -0,0 +1,8 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; diff --git a/security/src/main/resources/application.yaml b/security/src/main/resources/application.yaml new file mode 100644 index 0000000..432ccba --- /dev/null +++ b/security/src/main/resources/application.yaml @@ -0,0 +1,7 @@ +spring: + application: + name: My spring-boot project + mustache: + expose-request-attributes: true # 뷰에서 CSRF를 뿌려주기 위해서 필요합니다. +server: + port: 8080 diff --git a/security/src/main/resources/banner.txt b/security/src/main/resources/banner.txt new file mode 100644 index 0000000..f7a35db --- /dev/null +++ b/security/src/main/resources/banner.txt @@ -0,0 +1,10 @@ + ('-. ('-. ) (`-. + _( OO) _( OO) ( OO ). +(,------.,--. (,------.(_/. \_)-. + | .---'| |.-') | .---' \ `.' / + | | | | OO ) | | \ /\ +(| '--. | |`-' |(| '--. \ \ | + | .--'(| '---.' | .--' .' \_) + | `---.| | | `---. / .'. \ + `------'`------' `------''--' '--' +powered by ELEX diff --git a/security/src/main/resources/logback-spring.xml b/security/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..6a38996 --- /dev/null +++ b/security/src/main/resources/logback-spring.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + + UTF-8 + ${FILE_LOG_PATTERN} + + ${LOG_PATH} + + ${LOG_DIR}/sebastian_%d{yyyy-MM-dd}_%i.log.gz + + 10MB + + 60 + + + + + + + + + diff --git a/security/src/main/resources/templates/home.mustache b/security/src/main/resources/templates/home.mustache new file mode 100644 index 0000000..ecf6671 --- /dev/null +++ b/security/src/main/resources/templates/home.mustache @@ -0,0 +1,4 @@ +

+

테스트 페이지입니다.

+ +{{> links}} diff --git a/security/src/main/resources/templates/links.mustache b/security/src/main/resources/templates/links.mustache new file mode 100644 index 0000000..2a4aa15 --- /dev/null +++ b/security/src/main/resources/templates/links.mustache @@ -0,0 +1,6 @@ +
+ | + 일반 | + 중요 | + 로그인 +
diff --git a/security/src/main/resources/templates/login.mustache b/security/src/main/resources/templates/login.mustache new file mode 100644 index 0000000..642875e --- /dev/null +++ b/security/src/main/resources/templates/login.mustache @@ -0,0 +1,11 @@ +

로그인

+
+ + + + + + +
+ +{{> links}} diff --git a/security/src/main/resources/templates/normal_info.mustache b/security/src/main/resources/templates/normal_info.mustache new file mode 100644 index 0000000..551c0cf --- /dev/null +++ b/security/src/main/resources/templates/normal_info.mustache @@ -0,0 +1,3 @@ +

아무나 볼 수 있는 페이지

+

This page doesn't contain any Important messages.

+{{> links}} diff --git a/security/src/main/resources/templates/secure_info.mustache b/security/src/main/resources/templates/secure_info.mustache new file mode 100644 index 0000000..1b097fd --- /dev/null +++ b/security/src/main/resources/templates/secure_info.mustache @@ -0,0 +1,8 @@ +

로그인해야 볼 수 있는 페이지

+

This page contains a Important message.

+
+ {{! CSRF 토큰이 없으면 에러 남. }} + + +
+{{> links}} diff --git a/settings.gradle.kts b/settings.gradle.kts index c7cfc52..2262f90 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,2 +1,9 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + rootProject.name = "spring-boot-examples" -include("lib", "app") +include("file-upload", "security", "security-with-jpa", "validation", "testing") diff --git a/testing/build.gradle.kts b/testing/build.gradle.kts new file mode 100644 index 0000000..e2a34d5 --- /dev/null +++ b/testing/build.gradle.kts @@ -0,0 +1,27 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +plugins { + id("elex-spring-boot") + + id("org.springframework.boot") version "2.5.3" + id("io.spring.dependency-management") version "1.0.11.RELEASE" +} + +dependencies { + implementation("org.springframework.boot:spring-boot-starter-mustache") + implementation("org.springframework.boot:spring-boot-starter-web") + + compileOnly("org.projectlombok:lombok") + developmentOnly("org.springframework.boot:spring-boot-devtools") + runtimeOnly("org.mariadb.jdbc:mariadb-java-client") + + annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") + annotationProcessor("org.projectlombok:lombok") + + testImplementation("org.springframework.boot:spring-boot-starter-test") +} diff --git a/testing/src/main/java/kr/pe/elex/examples/Application.java b/testing/src/main/java/kr/pe/elex/examples/Application.java new file mode 100644 index 0000000..7ff4bbf --- /dev/null +++ b/testing/src/main/java/kr/pe/elex/examples/Application.java @@ -0,0 +1,20 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/testing/src/main/java/kr/pe/elex/examples/MyController.java b/testing/src/main/java/kr/pe/elex/examples/MyController.java new file mode 100644 index 0000000..444dc60 --- /dev/null +++ b/testing/src/main/java/kr/pe/elex/examples/MyController.java @@ -0,0 +1,41 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class MyController { + + @Autowired + private MyService service; + + @GetMapping({"/"}) + public String index(Model model) { + model.addAttribute("name", "World"); + return "main"; + } + + @GetMapping({"/{name}"}) + public String index(@PathVariable @ModelAttribute String name) { + if (null == name) name = "World"; + return "main"; + } + + @GetMapping("/greetings") + @ResponseBody + public String greetings() { + return service.sayHello(); + } +} diff --git a/testing/src/main/java/kr/pe/elex/examples/MyService.java b/testing/src/main/java/kr/pe/elex/examples/MyService.java new file mode 100644 index 0000000..998a35f --- /dev/null +++ b/testing/src/main/java/kr/pe/elex/examples/MyService.java @@ -0,0 +1,17 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.springframework.stereotype.Service; + +@Service +public class MyService { + public String sayHello() { + return "Hello, World."; + } +} diff --git a/testing/src/main/java/kr/pe/elex/examples/package-info.java b/testing/src/main/java/kr/pe/elex/examples/package-info.java new file mode 100644 index 0000000..ce9cc62 --- /dev/null +++ b/testing/src/main/java/kr/pe/elex/examples/package-info.java @@ -0,0 +1,8 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; diff --git a/testing/src/main/resources/templates/main.mustache b/testing/src/main/resources/templates/main.mustache new file mode 100644 index 0000000..4372910 --- /dev/null +++ b/testing/src/main/resources/templates/main.mustache @@ -0,0 +1,2 @@ +

HOME

+

Hello, {{name}}!

diff --git a/testing/src/test/java/kr/pe/elex/examples/ApplicationTest.java b/testing/src/test/java/kr/pe/elex/examples/ApplicationTest.java new file mode 100644 index 0000000..52f7f0f --- /dev/null +++ b/testing/src/test/java/kr/pe/elex/examples/ApplicationTest.java @@ -0,0 +1,28 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +/** + * 통합 테스트. 모든 빈을 로드한 다음, 테스트가 수행된다. + */ +@SpringBootTest(classes = Application.class) +class ApplicationTest { + @Autowired + private MyController controller; + + @Test + void test() { + assertThat(controller).isNotNull(); + } +} diff --git a/testing/src/test/java/kr/pe/elex/examples/ControllerTest1.java b/testing/src/test/java/kr/pe/elex/examples/ControllerTest1.java new file mode 100644 index 0000000..a342b83 --- /dev/null +++ b/testing/src/test/java/kr/pe/elex/examples/ControllerTest1.java @@ -0,0 +1,55 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * MvcMock을 사용해서 웹 요청과 응답을 테스트할 수 있다. + */ +@SpringBootTest//(classes = Application.class) +@AutoConfigureMockMvc +class ControllerTest1 { + + @Autowired + private MockMvc mockMvc; + + @Test + void getTest() throws Exception { + this.mockMvc.perform(get("/")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("Hello, World"))); + } + + @Test + void getTest2() throws Exception { + this.mockMvc.perform(get("/charlie")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("Hello, charlie"))); + } + + @Test + void postTest() throws Exception { + this.mockMvc.perform(post("/")) + .andDo(print()) + .andExpect(status().isMethodNotAllowed()); + } +} diff --git a/testing/src/test/java/kr/pe/elex/examples/ControllerTest2.java b/testing/src/test/java/kr/pe/elex/examples/ControllerTest2.java new file mode 100644 index 0000000..d7184bc --- /dev/null +++ b/testing/src/test/java/kr/pe/elex/examples/ControllerTest2.java @@ -0,0 +1,51 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.containsString; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Mockito를 사용해서 테스트용 서비스를 모킹한다. + */ +@WebMvcTest(MyController.class) +class ControllerTest2 { + @Autowired + private MockMvc mockMvc; + + @MockBean + private MyService service; + + @BeforeEach + void beforeAll() { + Mockito.when(service.sayHello()) + .thenReturn("Hello, Mock"); + } + + @Test + void greetingsTest() throws Exception { + this.mockMvc.perform(get("/greetings")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("Hello, Mock"))); + } + +} diff --git a/testing/src/test/java/kr/pe/elex/examples/ControllerTest3.java b/testing/src/test/java/kr/pe/elex/examples/ControllerTest3.java new file mode 100644 index 0000000..6854165 --- /dev/null +++ b/testing/src/test/java/kr/pe/elex/examples/ControllerTest3.java @@ -0,0 +1,51 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * 테스트 설정 클래스를 만든 다음, 테스트용 빈을 등록한다. + */ +@WebMvcTest(MyController.class) +class ControllerTest3 { + @TestConfiguration + static class TestConfig { + @Bean + MyService myService() { + return new MyService() { + @Override + public String sayHello() { + return "Hello, Mock"; + } + }; + } + } + + @Autowired + private MockMvc mockMvc; + + @Test + void greetingsTest() throws Exception { + this.mockMvc.perform(get("/greetings")) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("Hello, Mock"))); + } +} diff --git a/validation/README.md b/validation/README.md new file mode 100644 index 0000000..072391b --- /dev/null +++ b/validation/README.md @@ -0,0 +1,29 @@ +# spring-boot-validation-examples + +```kotlin +implementation ("org.springframework.boot:spring-boot-starter-validation") +``` + +## Annotations + +* @Digits +* @Email +* @Max +* @Min +* @Negative +* @NotBlank +* @NotEmpty +* @NotNull +* @Null +* @Pattern +* @Positive +* @Size + +https://docs.jboss.org/hibernate/beanvalidation/spec/2.0/api/ + + + +--- +developed by Elex + +https://www.elex-project.com diff --git a/validation/build.gradle.kts b/validation/build.gradle.kts new file mode 100644 index 0000000..0f28179 --- /dev/null +++ b/validation/build.gradle.kts @@ -0,0 +1,29 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +plugins { + id("elex-spring-boot") + + id("org.springframework.boot") version "2.5.3" + id("io.spring.dependency-management") version "1.0.11.RELEASE" +} + +dependencies { + implementation("org.springframework.boot:spring-boot-starter-mustache") + implementation("org.springframework.boot:spring-boot-starter-web") + + implementation ("org.springframework.boot:spring-boot-starter-validation") + + compileOnly("org.projectlombok:lombok") + developmentOnly("org.springframework.boot:spring-boot-devtools") + runtimeOnly("org.mariadb.jdbc:mariadb-java-client") + + annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") + annotationProcessor("org.projectlombok:lombok") + + testImplementation("org.springframework.boot:spring-boot-starter-test") +} diff --git a/validation/src/main/java/kr/pe/elex/examples/Application.java b/validation/src/main/java/kr/pe/elex/examples/Application.java new file mode 100644 index 0000000..7ff4bbf --- /dev/null +++ b/validation/src/main/java/kr/pe/elex/examples/Application.java @@ -0,0 +1,20 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/validation/src/main/java/kr/pe/elex/examples/MyController.java b/validation/src/main/java/kr/pe/elex/examples/MyController.java new file mode 100644 index 0000000..5986c60 --- /dev/null +++ b/validation/src/main/java/kr/pe/elex/examples/MyController.java @@ -0,0 +1,63 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; + +import kr.pe.elex.examples.model.Person; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Controller +public class MyController { + @GetMapping({"/"}) + public String index() { + return "home"; + } + + @PostMapping(value = {"/test1"}) + @ResponseBody + public ResponseEntity test1(@Valid @RequestBody Person person, BindingResult bindingResult) { + + if (bindingResult.hasErrors()) { + log.info("ERROR: {}", person); + return ResponseEntity.badRequest().body("BAD"); + } else { + log.info("OK: {}", person); + return ResponseEntity.ok("GOOD"); + } + } + + @PostMapping(value = {"/test2"}) + @ResponseBody + public ResponseEntity test2(@Valid @RequestBody Person person) { + + return ResponseEntity.ok("GOOD"); + } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler({MethodArgumentNotValidException.class}) + @ResponseBody + public Map handleValidation(MethodArgumentNotValidException e) { + Map result = new HashMap<>(); + e.getBindingResult().getAllErrors().forEach(item -> { + result.put(((FieldError) item).getField(), + item.getDefaultMessage()); + }); + return result; + } +} diff --git a/validation/src/main/java/kr/pe/elex/examples/model/Person.java b/validation/src/main/java/kr/pe/elex/examples/model/Person.java new file mode 100644 index 0000000..fb223e5 --- /dev/null +++ b/validation/src/main/java/kr/pe/elex/examples/model/Person.java @@ -0,0 +1,29 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import javax.validation.constraints.Email; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Data +public class Person { + @NotNull @NotEmpty + @JsonProperty + private String name; + @Min(13) + @JsonProperty + private int age; + @Email + @JsonProperty + private String email; +} diff --git a/validation/src/main/java/kr/pe/elex/examples/package-info.java b/validation/src/main/java/kr/pe/elex/examples/package-info.java new file mode 100644 index 0000000..ce9cc62 --- /dev/null +++ b/validation/src/main/java/kr/pe/elex/examples/package-info.java @@ -0,0 +1,8 @@ +/* + * Spring-boot Examples + * + * Copyright (c) 2021. Elex. All Rights Reserved. + * https://www.elex-project.com/ + */ + +package kr.pe.elex.examples; diff --git a/validation/src/main/resources/application.yaml b/validation/src/main/resources/application.yaml new file mode 100644 index 0000000..e5957b9 --- /dev/null +++ b/validation/src/main/resources/application.yaml @@ -0,0 +1,5 @@ +spring: + application: + name: My spring-boot project +server: + port: 8080 diff --git a/validation/src/main/resources/banner.txt b/validation/src/main/resources/banner.txt new file mode 100644 index 0000000..f7a35db --- /dev/null +++ b/validation/src/main/resources/banner.txt @@ -0,0 +1,10 @@ + ('-. ('-. ) (`-. + _( OO) _( OO) ( OO ). +(,------.,--. (,------.(_/. \_)-. + | .---'| |.-') | .---' \ `.' / + | | | | OO ) | | \ /\ +(| '--. | |`-' |(| '--. \ \ | + | .--'(| '---.' | .--' .' \_) + | `---.| | | `---. / .'. \ + `------'`------' `------''--' '--' +powered by ELEX diff --git a/validation/src/main/resources/logback-spring.xml b/validation/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..7267292 --- /dev/null +++ b/validation/src/main/resources/logback-spring.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + + UTF-8 + ${FILE_LOG_PATTERN} + + ${LOG_PATH} + + ${LOG_DIR}/sebastian_%d{yyyy-MM-dd}_%i.log.gz + + 10MB + + 60 + + + + + + + + + + + + + diff --git a/validation/src/main/resources/templates/home.mustache b/validation/src/main/resources/templates/home.mustache new file mode 100644 index 0000000..e583759 --- /dev/null +++ b/validation/src/main/resources/templates/home.mustache @@ -0,0 +1 @@ +

Test