MyGolfClub is an implementation of a web-based management system. Users must log in using unique username and respected password to authenticate. All passwords are encrypted using bcrypt and stored securely in a database. Each user is associated with a given role: EMPLOYEE, MODERATOR or ADMIN. The role defines authorization level.
- EMPLOYEE can only view members of the golf club. (
READ
operation) - MODERATOR can view members and also add a new member to the club. (
CREATE
,READ
operations) - ADMIN can view, add, modify and remove a member of the club (Full
CRUD
support)
They are also authorized to add a new user.
Interaction with a system is done via web app and also extensively with RESTful API
after valid authentication and authorization.
Read further for more details.
- System management for your golf club - helping you with members' management
- Secured with user authentication and authorization
- Web-based UI
- RESTful API for extensibility
- CRUD operations support
- Included SQL scripts for creation of user, database, tables and records
- Java 17 (LTS)
- MySQL DB 8
- Gradle 8 Kotlin DSL
- Spring Boot 3.2.1
- BootStrap 5.3.2
Dependencies | Version |
---|---|
Spring Boot Starter Test | 3.2.1 |
Spring Boot Starter Data JPA | 3.2.1 |
Spring Boot Starter Web | 3.2.1 |
Spring Boot Starter HATEOAS | 3.2.1 |
Spring Boot Starter Security | 3.2.1 |
Spring Boot Starter Thymeleaf | 3.2.1 |
Thymeleaf Extras Spring Security6 | 3.1.2.RELEASE |
Spring Boot Starter Validation | 3.2.1 |
SpringDoc OpenAPI Starter WebMVC UI | 2.3.0 |
MySQL Connector/J | 8.2.0 |
Lombok | 1.18.30 |
Prerequisites: MySQL Server 8+, Git, JDK 17+, Gradle 8.3+.
Recommendations: MySQL Workbench 8 or other GUI database manager.
-
Make sure you run MySQL Server in the background.
-
Connect as root to MySQL Connection of your choice. (the best if you create a new one for this purpose)
-
You will need to run a few SQL scripts. You can find those in here.
-
Create a new user:
DROP USER if exists 'golfadmin'@'%';
CREATE USER 'golfadmin'@'%' IDENTIFIED BY 'golfadmin';
GRANT ALL PRIVILEGES ON * . * TO 'golfadmin'@'%';
-
Create a new connection with golfadmin user.
-
Create a database schema:
CREATE DATABASE IF NOT EXISTS `my_golf_club`;
USE `my_golf_club`;
- Create tables and insert records:
DROP TABLE IF EXISTS `golf_club_member`;
CREATE TABLE `golf_club_member` (
`id` int NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) NOT NULL,
`last_name` varchar(45) NOT NULL,
`email` varchar(45) NOT NULL,
`active_member` boolean DEFAULT FALSE NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
INSERT INTO `golf_club_member` VALUES
(1,'Emma','Green','emmagreen@mail.com',true),
(2,'Anna','Barsky','annab@mail.de',false),
(3,'Richard','Dunkins','rdunkins@mail.com',true),
(4,'Thomas','Terra','thomas@terra.me',true),
(5,'Edwin','Vega','edwin.vega@maily.com',false);
USE `my_golf_club`;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `users_roles`;
DROP TABLE IF EXISTS `role`;
DROP TABLE IF EXISTS `user`;
SET FOREIGN_KEY_CHECKS = 1;
CREATE TABLE `user` (
`username` varchar(50) NOT NULL UNIQUE,
`password` char(60) NOT NULL,
`enabled` tinyint NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `user` VALUES
('employee','$2a$12$mjbSTPLi/cLOxxdrFrwcKO5kwpkiRAiB85Hs39Pbj4bA9nfD/ZtFy',1),
('moderator','$2a$12$wd.0xHxzTtkZAEKFLM3/2eoXzkNcbcTZXEONdyy.udVvKyxXy.0La',1),
('admin','$2a$12$jGXj8Ve3VwaVrnfwYeB7HOHzPZa9dMPT.WT7cPWT.04o/x0HAplk2',1);
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
INSERT INTO `role` (`name`) VALUES
('ROLE_EMPLOYEE'),
('ROLE_MODERATOR'),
('ROLE_ADMIN');
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `users_roles` (
`username` varchar(50) NOT NULL,
`role_id` int(11) NOT NULL,
PRIMARY KEY (`username`, `role_id`),
KEY `FK_ROLE_idx` (`role_id`),
CONSTRAINT `FK_USER` FOREIGN KEY (`username`)
REFERENCES `user` (`username`)
ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_ROLE` FOREIGN KEY (`role_id`)
REFERENCES `role` (`id`)
ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET FOREIGN_KEY_CHECKS = 1;
INSERT INTO `users_roles` VALUES
('employee', 1),
('moderator', 1),
('moderator', 2),
('admin', 1),
('admin', 2),
('admin', 3);
- Open a terminal in your desired location.
- (Optional) Define a parent directory for a project.
Linux, macOS:
mkdir parent-dir && cd "$_"
Windows/Powershell:
($dir = "parent-dir") -and (mkdir $dir) -and (cd $dir)
You can use the name of your choice instead.
- Clone repository:
git clone https://github.com/lucasmalara/my-golf-club.git
- or using GitHub CLI:
gh repo clone lucasmalara/my-golf-club
- Open the main directory of a project
cd my-golf-club
The Name of this directory is inherited from this repository name.
- Run with Gradle:
gradle bootRun
- or if your environment variable
JAVA_HOME
uses jdk lower than 17, or you do not have it, then you should add:-D org.gradle.java.home='$JDK_PATH'
, where$JDK_PATH
is an absolute path to a root folder of jdk 17 or 17+.
gradle bootRun -D org.gradle.java.home='$JDK_PATH'
The following cases have to be followed:
If you do not authenticate, you will be redirected to a login page.
/login
/login?error
/my-golf-club
/my-golf-club/members/list
/my-golf-club/members/list/active
/my-golf-club/members/add
/my-golf-club/members/update?memberId=1
/my-golf-club/members/delete?memberId=1
/my-golf-club/users/add
/my-golf-club
/my-golf-club/members/list
/my-golf-club/members/list/active
/my-golf-club/members/add
/my-golf-club/members/list
/my-golf-club/members/list/active
/my-golf-club/members/save
/my-golf-club/members/update?memberId=1
/my-golf-club/members/delete?memberId=1
/my-golf-club/users/add
/my-golf-club
/my-golf-club/members/list
/my-golf-club/members/list/active
/my-golf-club/members/add
/my-golf-club/members/list
/my-golf-club/members/list/active
/my-golf-club/members/save
/my-golf-club/members/list
/my-golf-club/members/update?memberId=6
/my-golf-club/members/list
/my-golf-club/members/list/active
/my-golf-club/members/save
/my-golf-club/members/delete?memberId=6
/my-golf-club/members/list
/my-golf-club/members/list/active
/my-golf-club/users/add
/my-golf-club/users/save
We can verify if a user has been added.
-
Open
MySQL Command Line Client
-
You will be asked for a password to your
root
MySQL account. Provide correct password and pressenter
. -
Connect to database
my_golf_club
use my_golf_club
- List all users
SELECT * FROM user;
We can also list users via GUI application:
As we can see, all passwords are encrypted.
Now, we verify if user has declared role(s)
- List user with his role(s)
SELECT ur.username, replace(r.name,"ROLE_", '') as 'role'
FROM my_golf_club.users_roles ur
LEFT JOIN my_golf_club.role r
ON ur.role_id = r.id
WHERE ur.username=$username;
in this case $username = 'newEmployee'
/my-golf-club/members/save
e.g.: /my-golf-club/custom
/login?logout
To read official documentation, run the project, authenticate and go to address: http://localhost:9090/swagger-ui/index.html
You can also click on a proper button on the homepage, the page you are redirected to after successful authentication. ↓
Make sure you have 9090 port available, since configuration specifies to run on this server port. You could also change the configuration to your liking if necessary.
Default HOST
= http://localhost:9090
GET | Key (optional) | Value (if key is included) |
---|---|---|
HOST/my-golf-club/api/members |
active | boolean |
GET | Path variable (required) |
---|---|
HOST/my-golf-club/api/members/{int} |
int {1, ..} |
POST | Request body (required) |
---|---|
HOST/my-golf-club/api/members |
application/json see example in official documentation |
PUT | Path variable (required) | Request body (required) |
---|---|---|
HOST/my-golf-club/api/members/{int} |
int {1, ..} | application/json see example in official documentation |
DELETE | Path variable (required) |
---|---|
HOST/my-golf-club/api/members/{int} |
int {1, ..} |