Skip to content

Commit

Permalink
Merge pull request #18 from devondragon/issue-16-Add_Tailwind_CSS_and…
Browse files Browse the repository at this point in the history
…_styled_pages

Issue 16 add tailwind css and styled pages
  • Loading branch information
devondragon authored Apr 22, 2023
2 parents cb9938f + 3c65fff commit 1fd19d8
Show file tree
Hide file tree
Showing 60 changed files with 7,401 additions and 345 deletions.
5 changes: 5 additions & 0 deletions .hintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": [
"development"
]
}
25 changes: 18 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
An Easy to leverage Java Spring Boot User Management Framework based on [Spring Security](https://spring.io/projects/spring-security)

## Summary
This is an easy to use starter application or framework for handling basic user management features for your [Spring](https://spring.io/) based Web Application. It provides registration, with optional email verification, login, logout, and forgot password flows. There are basic example pages for everything, unstyled, to allow for the easiest integration to your application.
This is an easy to use starter application or framework for handling basic user management features for your [Spring](https://spring.io/) based Web Application. It provides registration, with optional email verification, login, logout, and forgot password flows. There are basic example pages for everything, unstyled, to allow for the easiest integration to your application.

## Goals
- To build an easy to use starting point for any Spring based web application that needs user features.
Expand All @@ -15,7 +15,7 @@ This is an easy to use starter application or framework for handling basic user
- To use email address as the username by default.

## Features
At the highest level the framework provides support for, and working examples of, registration, with or without email verification, log in, log out, and forgot password flows.
At the highest level the framework provides support for, and working examples of, registration, with or without email verification, log in, log out, and forgot password flows.

It uses a database for the user store, and leverages Spring JPA to make it easy to use any database you like.

Expand All @@ -25,7 +25,7 @@ CSRF is enabled by default and the example jQuery AJAX calls pass the CSRF token

An audit event and listener are implmented to allow for recording security events, or any type of event you like, and logging them to a seperate file. You can easily replace the logging listener with your own and store audit events in a database, publish them to a REST API, or anything else.

There is Role and Privilege setup service, which allows you to easily define Roles, associated Privileges, and Role inheritance hierachy in your application.yml. Check out the application.yml for the basic OOTB configuration, and look at the RolePrivilegeSetupService component. You can still create and leverage roles and privileges programatically, but this makes it easy to define and see the associations.
There is Role and Privilege setup service, which allows you to easily define Roles, associated Privileges, and Role inheritance hierachy in your application.yml. Check out the application.yml for the basic OOTB configuration, and look at the RolePrivilegeSetupService component. You can still create and leverage roles and privileges programatically, but this makes it easy to define and see the associations.


## How To Get Started
Expand All @@ -38,22 +38,33 @@ You can do this using docker with a command like this:
docker run -p 127.0.0.1:3306:3306 --name springuserframework -e MARIADB_ROOT_PASSWORD=springuserroot -e MARIADB_DATABASE=springuser -e MARIADB_USER=springuser -e MARIADB_PASSWORD=springuser -d mariadb:latest

### Mail Sending (SMTP)
The framework sends emails for verficiation links, forgot password flow, etc... so you need to configure the outbound SMTP server and authentication information.
The framework sends emails for verficiation links, forgot password flow, etc... so you need to configure the outbound SMTP server and authentication information.

### New Relic
Out of the box the project includes the New Relic Telemetry module, and as such requires a New Relic account id, and associated API key. If you don't use New Relic you can remove the dependancy from the build.gradle file and ignore the configuration values.

Beyond that the default configurations should be all you need, although of course you can customize things however you like.
Beyond that the default configurations should be all you need, although of course you can customize things however you like.

## Docker

After running 'gradle build', you can build a simple docker image with the application using the included Dockerfile. It's very basic and is not using layering, buildpacks, or other things you may want for real applications.

I have also included a docker-compose file which will launch a stack with the Spring Boot Application, MariaDB Database, and Postfix Mail Server, with basic configurations in place to make everything work. Sending email from your computer (via the docker Postfix Mail Server) will likely get blocked by GMail, Outlook, etc... due to spam checks. You can always test by using [10MinuteMail.com](https://10MinuteMail.com) addresses, but for real use you should probably leave off the mail server entirely and configure the Spring Boot application to use a real mail server for outbound transactional emails.
I have also included a docker-compose file which will launch a stack with the Spring Boot Application, MariaDB Database, and Postfix Mail Server, with basic configurations in place to make everything work. Sending email from your computer (via the docker Postfix Mail Server) will likely get blocked by GMail, Outlook, etc... due to spam checks. You can always test by using [10MinuteMail.com](https://10MinuteMail.com) addresses, but for real use you should probably leave off the mail server entirely and configure the Spring Boot application to use a real mail server for outbound transactional emails.


## Dev Tools
### Live Reload over HTTPS Setup
If you are running your local dev env using HTTPS or referencing it from a ngrok tunnel using HTTPS, you will need to make a few changes to get Live Reload to work. First you need to comment out the LiveReload HTTP line near the bottom of the index.html Thymeleaf template file. And uncomment the HTTPS line just below.

You then need to install mitmproxy and configure it to intercept the HTTPS traffic. You can do this by running the following command:

mitmproxy --mode reverse:http://localhost:35729 -p 35739

By default, mitmproxy uses self-signed SSL certificates, so you need to tell your browser to trust them before this will work. You can do this by opening https://localhost:35739/livereload.js in your browser and going through the steps to trust the server and certificate. Alternatively, you can configure mitmproxy to use real certificates and avoid this step. Follow these directions: https://docs.mitmproxy.org/stable/concepts-certificates/

## Notes
Much of this is based on the [Baeldung course on Spring Security](https://www.baeldung.com/learn-spring-security-course). If you want to learn more about Spring Security or you'd like to add an SSO integration or add 2FA, that guide is a great place to get started!

You will see examples of different ways to to serve and consume the APIs in the codebase. For example some of the APIs return 200 response for all queries with a success flag and status codes to convey success or failures. Whereas others only use the 200 response on success, and use 409 or 500 for various error scenarios. Some AJAX client JS will trigger a redirect to a new page, whereas other client JS will display messaging directly on the current page. I think there are good reasons you may wish to use one or another approach, so I wanted to provide working examples of each.
You will see examples of different ways to to serve and consume the APIs in the codebase. For example some of the APIs return 200 response for all queries with a success flag and status codes to convey success or failures. Whereas others only use the 200 response on success, and use 409 or 500 for various error scenarios. Some AJAX client JS will trigger a redirect to a new page, whereas other client JS will display messaging directly on the current page. I think there are good reasons you may wish to use one or another approach, so I wanted to provide working examples of each.

There is no warranty or garantee of functionaltiy, quality, performance, or security made by the author. This code is availble freely but you take all responsibilty and liabilty for your application.
10 changes: 6 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.3'
id 'org.springframework.boot' version '3.0.6'
id 'io.spring.dependency-management' version '1.1.0'
}

Expand Down Expand Up @@ -34,13 +34,15 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.1.RELEASE'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6:3.1.1.RELEASE'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'

// Other dependencies
runtimeOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'io.micrometer:micrometer-registry-new-relic'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
runtimeOnly 'org.postgresql:postgresql'
Expand Down Expand Up @@ -73,8 +75,8 @@ bootJar {

bootRun {
// Use Spring Boot DevTool only when we run Gradle bootRun task
classpath = sourceSets.main.runtimeClasspath + configurations.dev

classpath = sourceSets.main.runtimeClasspath + configurations.developmentOnly
sourceResources sourceSets.main
if (project.hasProperty('profiles')) {
environment SPRING_PROFILES_ACTIVE: profiles
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import lombok.extern.slf4j.Slf4j;

/**
* The Class UserApplication. Basic Spring Boot Application Setup. Adds Async support and Scheduling support to the
* default Spring Boot stack.
* The Class UserApplication. Basic Spring Boot Application Setup. Adds Async support and Scheduling support to the default Spring Boot stack.
*/
@Slf4j
@EnableAsync
@EnableScheduling
@SpringBootApplication
Expand All @@ -17,11 +18,12 @@ public class UserApplication {
/**
* The main method.
*
* @param args
* the arguments
* @param args the arguments
*/
public static void main(String[] args) {
log.info("Starting UserApplication...");
SpringApplication.run(UserApplication.class, args);
log.info("UserApplication started.");
}

}
Loading

0 comments on commit 1fd19d8

Please sign in to comment.