Skip to content
Snippets Groups Projects
Commit 76d062fd authored by Paulo Pimenta's avatar Paulo Pimenta
Browse files

feature(swagger and custom page) : Add swagger and custom 401 page

parent ca7ae74a
No related branches found
No related tags found
No related merge requests found
Showing
with 183 additions and 71 deletions
package com.smartharvester.config;
import com.smartharvester.security.handler.SmartHarvesterCustomAccessDeniedHandler;
import com.smartharvester.security.jwt.AuthEntryPointJwt;
import com.smartharvester.security.jwt.AuthTokenFilter;
import com.smartharvester.security.services.UserServiceImpl;
......@@ -13,6 +12,7 @@ import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
......@@ -53,9 +53,10 @@ public class SmartHarvesterSecurityConfiguration extends WebSecurityConfigurerAd
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/auth/**").permitAll()
.antMatchers("/harvest/**").authenticated();
.authorizeRequests().antMatchers("/harvester/auth/**").permitAll().and()
.authorizeRequests().antMatchers("/resources/**", "/public/error/css/**").permitAll()
.antMatchers("/harvester/api/**").authenticated()
.antMatchers("/public/error/css/**").permitAll();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
......@@ -65,8 +66,4 @@ public class SmartHarvesterSecurityConfiguration extends WebSecurityConfigurerAd
return new BCryptPasswordEncoder();
}
@Bean
public AccessDeniedHandler accessDeniedHandler(){
return new SmartHarvesterCustomAccessDeniedHandler();
}
}
......@@ -8,7 +8,12 @@ import com.smartharvester.model.login.response.MessageResponse;
import com.smartharvester.model.user.SmartHarvesterUser;
import com.smartharvester.security.jwt.JwtUtils;
import com.smartharvester.security.services.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
......@@ -23,7 +28,7 @@ import java.util.UUID;
import java.util.stream.Collectors;
@CrossOrigin(origins = "*")
@RequestMapping("/api/auth")
@Api(value = "SmartHarvesterAuthController", description = "REST Apis related to User Entity!!!!")
@RestController
public class SmartHarvesterAuthController {
......@@ -39,6 +44,7 @@ public class SmartHarvesterAuthController {
@Autowired
JwtUtils jwtUtils;
@ApiOperation(value = "Get list of Students in the System ", response = Iterable.class, tags = "getStudents")
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
......
......@@ -10,6 +10,7 @@ import com.smartharvester.dao.OpenApiDaoRepository;
import com.smartharvester.exception.ResourceNotFoundException;
import com.smartharvester.model.openapi.OpenApi;
import com.smartharvester.service.OpenApiService;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.parser.OpenAPIV3Parser;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
......@@ -40,7 +41,8 @@ import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
@CrossOrigin(origins = "*")
@RequestMapping("/harvest")
@Api(tags="OpenApi")
@RequestMapping("/harvester/api")
@RestController
public class SmartHarvesterController {
......
......@@ -9,9 +9,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
@CrossOrigin(origins = "*")
@Controller
public class SmartHarvesterErrorController implements ErrorController {
//@CrossOrigin(origins = "*")
//@Controller
public class SmartHarvesterErrorController {
@RequestMapping("/error")
public String handleError(HttpServletRequest request) {
......@@ -23,16 +23,19 @@ public class SmartHarvesterErrorController implements ErrorController {
Integer statusCode = Integer.valueOf(status.toString());
if(statusCode == HttpStatus.NOT_FOUND.value()) {
return "error-404";
return "404";
}
else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error-500";
return "500";
}
else if(statusCode == HttpStatus.UNAUTHORIZED.value()) {
return "401";
}
}
return "error";
}
@Override
//@Override
public String getErrorPath() {
return null;
}
......
......@@ -20,7 +20,7 @@ import java.util.*;
@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/harvest/user")
@RequestMapping("/harvester/api")
public class SmartHarvesterUserController {
......@@ -34,7 +34,7 @@ public class SmartHarvesterUserController {
* Method to fetch all users.
* @return
*/
@GetMapping("/all")
@GetMapping("/allusers")
public String getAllUsers() {
MongoDatabase db = mongoTemplate.getDb();
MongoIterable<String> names = db.listCollectionNames();
......@@ -73,22 +73,11 @@ public class SmartHarvesterUserController {
* @return
*/
@GetMapping("/all2")
@GetMapping("/allusers2")
public Collection<SmartHarvesterUser> getAll2() {
//logger.debug("Getting all OpenApi from database...");
List<SmartHarvesterUser> response = userDaoRepository.findAll();
return response;
}
//@GetMapping("/all2")
//List<SmartHarvesterUser> getAllUsers2() throws ResourceNotFoundException {
// Collection<SmartHarvesterUser> users = userDaoRepository.findAll();
//if (users.isEmpty()) {
// throw new ResourceNotFoundException("No users found !");
// }
//return ResponseEntity.ok().body(users);
//return userDaoRepository.findAll();
//}
}
package com.smartharvester.security.handler;
import java.io.IOException;
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 javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SmartHarvesterCustomAccessDeniedHandler implements AccessDeniedHandler {
public static final Logger LOG = LoggerFactory.getLogger(SmartHarvesterCustomAccessDeniedHandler.class);
@Override
public void handle(
HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException exc) throws IOException, ServletException {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
LOG.warn("User: "
+ auth.getName()
+ " attempted to access the protected URL: "
+ request.getRequestURI());
}
response.sendRedirect(request.getContextPath() + "/denied.html");
}
}
......@@ -17,8 +17,9 @@ public class UserServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String userName) {
SmartHarvesterUser user = userRepository.findByEmail(userName).
orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + userName));
SmartHarvesterUser user = userRepository
.findByEmail(userName)
.orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + userName));
return UserService.build(user);
}
......
......@@ -28,7 +28,11 @@ smartharvester.app.jwt.route.authentication.refresh=/refresh
# 7. Swagger
springdoc.api-docs.path=/smart-docs
springdoc.swagger-ui.path=/smart-harvester/open-api.html
springdoc.swagger-ui.operationsSorter=method
# 8. Error Handling
server.error.whitelabel.enabled=true
server.error.whitelabel.enabled=false
server.error.path=/error
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>401 HTML Template by Colorlib</title>
<!-- Google font -->
<link href="https://fonts.googleapis.com/css?family=Cabin:400,700" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Montserrat:900" rel="stylesheet">
<!-- Custom stlylesheet -->
<!--<link type="text/css" rel="stylesheet" href="../static/css/style.css" />-->
<style>
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
padding: 0;
margin: 0;
}
#notfound {
position: relative;
height: 100vh;
}
#notfound .notfound {
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.notfound {
max-width: 520px;
width: 100%;
line-height: 1.4;
text-align: center;
}
.notfound .notfound-404 {
position: relative;
height: 240px;
}
.notfound .notfound-404 h1 {
font-family: 'Montserrat', sans-serif;
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
font-size: 252px;
font-weight: 900;
margin: 0px;
color: #262626;
text-transform: uppercase;
letter-spacing: -40px;
margin-left: -20px;
}
.notfound .notfound-404 h1>span {
text-shadow: -8px 0px 0px #fff;
}
.notfound .notfound-404 h3 {
font-family: 'Cabin', sans-serif;
position: relative;
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
color: #262626;
margin: 0px;
letter-spacing: 3px;
padding-left: 6px;
}
.notfound h2 {
font-family: 'Cabin', sans-serif;
font-size: 20px;
font-weight: 400;
text-transform: uppercase;
color: #000;
margin-top: 0px;
margin-bottom: 25px;
}
@media only screen and (max-width: 767px) {
.notfound .notfound-404 {
height: 200px;
}
.notfound .notfound-404 h1 {
font-size: 200px;
}
}
@media only screen and (max-width: 480px) {
.notfound .notfound-404 {
height: 162px;
}
.notfound .notfound-404 h1 {
font-size: 162px;
height: 150px;
line-height: 162px;
}
.notfound h2 {
font-size: 16px;
}
}
</style>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div id="notfound">
<div class="notfound">
<div class="notfound-404">
<h3>You Shall not Pass !</h3>
<h1><span>4</span><span>0</span><span>1</span></h1>
</div>
<h2>We are sorry, but you are not authorized to acesss this resource</h2>
</div>
</div>
</body><!-- This templates was made by Colorlib (https://colorlib.com) -->
</html>
......@@ -14,7 +14,7 @@
<link href="https://fonts.googleapis.com/css?family=Montserrat:900" rel="stylesheet">
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="css/style.css" />
<link type="text/css" rel="stylesheet"/>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment