Skip to content

Commit

Permalink
Source Code Added: Java
Browse files Browse the repository at this point in the history
  • Loading branch information
akiltipu committed Mar 7, 2024
1 parent fb2acb7 commit f63d68f
Show file tree
Hide file tree
Showing 39 changed files with 1,654 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ buildNumber.properties
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
.vscode/
151 changes: 151 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.reljicd</groupId>
<artifactId>shopping-cart</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>shopping-cart</name>
<description>Demo project for Spring Boot Shopping Cart</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jacoco.version>0.8.6</jacoco.version>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
</properties>

<dependencies>
<!-- Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Data REST -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

<!--HAL REST Browser -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>

<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>

<!-- Spring MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- hot swapping, disable cache for template, enable live reload -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>

<!-- H2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

<!-- Tests -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- Optional, for bootstrap -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
</dependency>
<!-- Optional, for jQuery -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.4</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
12 changes: 12 additions & 0 deletions src/main/java/com/reljicd/ShoppingCartApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.reljicd;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ShoppingCartApplication {

public static void main(String[] args) {
SpringApplication.run(ShoppingCartApplication.class, args);
}
}
33 changes: 33 additions & 0 deletions src/main/java/com/reljicd/config/GlobalExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.reljicd.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

/**
* Global exception handler
*
* @author Dusan
*/
@ControllerAdvice
public class GlobalExceptionHandler {

private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

@ExceptionHandler(Throwable.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ModelAndView exception(final Throwable throwable, final Model model) {
logger.error("Exception during execution of SpringSecurity application", throwable);

ModelAndView modelAndView = new ModelAndView("/error");
String errorMessage = (throwable != null ? throwable.toString() : "Unknown error");
modelAndView.addObject("errorMessage", errorMessage);
return modelAndView;
}

}
39 changes: 39 additions & 0 deletions src/main/java/com/reljicd/config/MyAccessDeniedHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.reljicd.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* Custom 403 access denied handler
*/
@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {

private static Logger logger = LoggerFactory.getLogger(MyAccessDeniedHandler.class);

@Override
public void handle(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
AccessDeniedException e) throws IOException, ServletException {

Authentication auth
= SecurityContextHolder.getContext().getAuthentication();

if (auth != null) {
logger.info(String.format("User '%s' attempted to access the protected URL: %s", auth.getName(), httpServletRequest.getRequestURI()));
}

httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/403");

}
}
105 changes: 105 additions & 0 deletions src/main/java/com/reljicd/config/SpringSecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.reljicd.config;

import org.springframework.beans.factory.annotation.Autowired;
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.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.sql.DataSource;

/**
* Spring Security Configuration
* http://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html
* Switches off Spring Boot automatic security configuration
*
* @author Dusan
*/
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

private final AccessDeniedHandler accessDeniedHandler;

final DataSource dataSource;

@Value("${spring.admin.username}")
private String adminUsername;

@Value("${spring.admin.username}")
private String adminPassword;

@Value("${spring.queries.users-query}")
private String usersQuery;

@Value("${spring.queries.roles-query}")
private String rolesQuery;

@Autowired
public SpringSecurityConfig(AccessDeniedHandler accessDeniedHandler, DataSource dataSource) {
this.accessDeniedHandler = accessDeniedHandler;
this.dataSource = dataSource;
}

/**
* HTTPSecurity configurer
* - roles ADMIN allow to access /admin/**
* - roles USER allow to access /user/** and /newPost/**
* - anybody can visit /, /home, /about, /registration, /error, /blog/**, /post/**, /h2-console/**
* - every other page needs authentication
* - custom 403 access denied handler
*/
@Override
protected void configure(HttpSecurity http) throws Exception {

http.csrf().disable()
.authorizeRequests()
.antMatchers("/home", "/registration", "/error", "/h2-console/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
// Fix for H2 console
.and().headers().frameOptions().disable();
}


/**
* Authentication details
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

// Database authentication
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(passwordEncoder());

// In memory authentication
auth.inMemoryAuthentication()
.withUser(adminUsername).password(adminPassword).roles("ADMIN");
}

/**
* Configure and return BCrypt password encoder
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

}
28 changes: 28 additions & 0 deletions src/main/java/com/reljicd/controller/CustomErrorController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.reljicd.controller;

import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

@RestController
public class CustomErrorController implements ErrorController {

private static final String PATH = "/error";

@RequestMapping(PATH)
public ModelAndView error() {
return new ModelAndView("/error");
}

@GetMapping("/403")
public ModelAndView error403() {
return new ModelAndView("/403");
}

@Override
public String getErrorPath() {
return PATH;
}
}
Loading

0 comments on commit f63d68f

Please sign in to comment.