added some javadocs

This commit is contained in:
Fabio Formosa
2018-06-22 13:46:23 +02:00
parent e04311914b
commit dc081a1bed
19 changed files with 955 additions and 927 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/.project

View File

@@ -1,99 +1,105 @@
package it.fabioformosa.quartzmanager.configuration;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import it.fabioformosa.quartzmanager.security.ComboEntryPoint;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler;
import it.fabioformosa.quartzmanager.security.auth.LogoutSuccess;
import it.fabioformosa.quartzmanager.security.auth.RestAuthenticationEntryPoint;
import it.fabioformosa.quartzmanager.security.auth.TokenAuthenticationFilter;
import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService;
//@Configuration
//@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
@Value("${jwt.cookie}")
private String TOKEN_COOKIE;
@Autowired
private CustomUserDetailsService jwtUserDetailsService;
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Resource
private ComboEntryPoint comboEntryPoint;
@Autowired
private LogoutSuccess logoutSuccess;
@Autowired
private AuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)
throws Exception {
authenticationManagerBuilder.userDetailsService(jwtUserDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
return new TokenAuthenticationFilter();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// http.csrf().ignoringAntMatchers("/api/login", "/api/signup")
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
http.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.exceptionHandling().authenticationEntryPoint(comboEntryPoint).and()
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class)
.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/api/login")
.successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler)
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/api/logout"))
.logoutSuccessHandler(logoutSuccess).deleteCookies(TOKEN_COOKIE);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
package it.fabioformosa.quartzmanager.configuration;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import it.fabioformosa.quartzmanager.security.ComboEntryPoint;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler;
import it.fabioformosa.quartzmanager.security.auth.LogoutSuccess;
import it.fabioformosa.quartzmanager.security.auth.TokenAuthenticationFilter;
import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService;
/**
* JWT Temporary disabled
*
* @author Fabio.Formosa
*
*/
//@Configuration
//@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
@Value("${jwt.cookie}")
private String TOKEN_COOKIE;
@Autowired
private CustomUserDetailsService jwtUserDetailsService;
// @Autowired
// private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Resource
private ComboEntryPoint comboEntryPoint;
@Autowired
private LogoutSuccess logoutSuccess;
@Autowired
private AuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)
throws Exception {
authenticationManagerBuilder.userDetailsService(jwtUserDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
return new TokenAuthenticationFilter();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// http.csrf().ignoringAntMatchers("/api/login", "/api/signup")
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
http.cors().and().csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.exceptionHandling().authenticationEntryPoint(comboEntryPoint).and()
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class)
.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/api/login")
.successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler)
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/api/logout"))
.logoutSuccessHandler(logoutSuccess).deleteCookies(TOKEN_COOKIE);
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}

View File

@@ -1,75 +1,82 @@
package it.fabioformosa.quartzmanager.controllers;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import it.fabioformosa.quartzmanager.security.TokenHelper;
import it.fabioformosa.quartzmanager.security.model.UserTokenState;
import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService;
//@RestController
//@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE )
public class AuthenticationController {
static class PasswordChanger {
public String oldPassword;
public String newPassword;
}
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
TokenHelper tokenHelper;
@Value("${jwt.expires_in}")
private int EXPIRES_IN;
@Value("${jwt.cookie}")
private String TOKEN_COOKIE;
@RequestMapping(value = "/changePassword", method = RequestMethod.POST)
@PreAuthorize("hasRole('USER')")
public ResponseEntity<?> changePassword(@RequestBody PasswordChanger passwordChanger) {
userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword);
Map<String, String> result = new HashMap<>();
result.put( "result", "success" );
return ResponseEntity.accepted().body(result);
}
@RequestMapping(value = "/refresh", method = RequestMethod.GET)
public ResponseEntity<?> refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) {
String authToken = tokenHelper.getToken( request );
if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) {
// TODO check user password last update
String refreshedToken = tokenHelper.refreshToken(authToken);
Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken );
authCookie.setPath( "/" );
authCookie.setHttpOnly( true );
authCookie.setMaxAge( EXPIRES_IN );
// Add cookie to response
response.addCookie( authCookie );
UserTokenState userTokenState = new UserTokenState(refreshedToken, EXPIRES_IN);
return ResponseEntity.ok(userTokenState);
} else {
UserTokenState userTokenState = new UserTokenState();
return ResponseEntity.accepted().body(userTokenState);
}
}
}
package it.fabioformosa.quartzmanager.controllers;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import it.fabioformosa.quartzmanager.security.TokenHelper;
import it.fabioformosa.quartzmanager.security.model.UserTokenState;
import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService;
/**
* JWT Temporary disabled
*
* @author Fabio.Formosa
*
*/
//@RestController
//@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE )
public class AuthenticationController {
static class PasswordChanger {
public String oldPassword;
public String newPassword;
}
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
TokenHelper tokenHelper;
@Value("${jwt.expires_in}")
private int EXPIRES_IN;
@Value("${jwt.cookie}")
private String TOKEN_COOKIE;
@RequestMapping(value = "/changePassword", method = RequestMethod.POST)
@PreAuthorize("hasRole('USER')")
public ResponseEntity<?> changePassword(@RequestBody PasswordChanger passwordChanger) {
userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword);
Map<String, String> result = new HashMap<>();
result.put( "result", "success" );
return ResponseEntity.accepted().body(result);
}
@RequestMapping(value = "/refresh", method = RequestMethod.GET)
public ResponseEntity<?> refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) {
String authToken = tokenHelper.getToken( request );
if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) {
// TODO check user password last update
String refreshedToken = tokenHelper.refreshToken(authToken);
Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken );
authCookie.setPath( "/" );
authCookie.setHttpOnly( true );
authCookie.setMaxAge( EXPIRES_IN );
// Add cookie to response
response.addCookie( authCookie );
UserTokenState userTokenState = new UserTokenState(refreshedToken, EXPIRES_IN);
return ResponseEntity.ok(userTokenState);
} else {
UserTokenState userTokenState = new UserTokenState();
return ResponseEntity.accepted().body(userTokenState);
}
}
}

View File

@@ -1,46 +0,0 @@
package it.fabioformosa.quartzmanager.controllers;
import javax.annotation.Resource;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/manager")
public class ManagerController {
public enum SchedulerStates {
RUNNING, STOPPED, PAUSED
}
@Resource
private Scheduler scheduler;
@RequestMapping
public ModelAndView getPanelView() throws SchedulerException {
ModelAndView mav = new ModelAndView("panelView");
String schedulerState;
if (scheduler.isShutdown() || !scheduler.isStarted())
schedulerState = SchedulerStates.STOPPED.toString();
else if (scheduler.isStarted() && scheduler.isInStandbyMode())
schedulerState = SchedulerStates.PAUSED.toString();
else
schedulerState = SchedulerStates.RUNNING.toString();
mav.addObject("schedulerState", schedulerState.toLowerCase());
return mav;
}
// @MessageMapping("/updates")
// @SendTo("/topic/greetings")
// public String greeting(String message) throws Exception {
// Thread.sleep(3000); // simulated delay
// return "Hello";
// }
}

View File

@@ -1,156 +1,152 @@
package it.fabioformosa.quartzmanager.controllers;
import java.util.Collections;
import java.util.Map;
import javax.annotation.Resource;
import org.quartz.DailyTimeIntervalTrigger;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.triggers.SimpleTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import it.fabioformosa.quartzmanager.controllers.ManagerController.SchedulerStates;
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
import it.fabioformosa.quartzmanager.dto.TriggerProgress;
import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor;
@RestController
@RequestMapping("/scheduler")
public class SchedulerController {
private static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24;
private static final int SEC_IN_A_DAY = 60 * 60 * 24;
private final Logger log = LoggerFactory.getLogger(SchedulerController.class);
@Resource
private Scheduler scheduler;
@Resource
private TriggerMonitor triggerMonitor;
@RequestMapping(value = "/config", method = RequestMethod.GET)
public SchedulerConfigParam getConfig() {
SchedulerConfigParam config = new SchedulerConfigParam();
int maxCount = 0;
long repeatIntervalInMills = 0;
if (triggerMonitor.getTrigger() instanceof SimpleTrigger) {
SimpleTrigger simpleTrigger = (SimpleTrigger) triggerMonitor.getTrigger();
maxCount = simpleTrigger.getRepeatCount() + 1;
repeatIntervalInMills = fromTriggerPerDayToMillSecInterval(simpleTrigger.getRepeatInterval());
} else if (triggerMonitor.getTrigger() instanceof DailyTimeIntervalTrigger) {
DailyTimeIntervalTrigger dailyTimeIntervalTrigger = (DailyTimeIntervalTrigger) triggerMonitor
.getTrigger();
maxCount = dailyTimeIntervalTrigger.getRepeatCount() + 1;
repeatIntervalInMills = fromTriggerPerDayToSecInterval(
dailyTimeIntervalTrigger.getRepeatInterval());
}
config.setMaxCount(maxCount);
config.setTriggerPerDay(repeatIntervalInMills);
return config;
}
@RequestMapping("/progress")
public TriggerProgress getProgressInfo() throws SchedulerException {
SimpleTriggerImpl jobTrigger = (SimpleTriggerImpl) scheduler
.getTrigger(triggerMonitor.getTrigger().getKey());
TriggerProgress progress = new TriggerProgress();
if (jobTrigger != null && jobTrigger.getJobKey() != null) {
progress.setJobKey(jobTrigger.getJobKey().getName());
progress.setJobClass(jobTrigger.getClass().getSimpleName());
progress.setTimesTriggered(jobTrigger.getTimesTriggered());
progress.setRepeatCount(jobTrigger.getRepeatCount());
progress.setFinalFireTime(jobTrigger.getFinalFireTime());
progress.setNextFireTime(jobTrigger.getNextFireTime());
progress.setPreviousFireTime(jobTrigger.getPreviousFireTime());
}
return progress;
}
@GetMapping(produces = "application/json")
public Map<String, String> getStatus() throws SchedulerException {
String schedulerState = "";
if (scheduler.isShutdown() || !scheduler.isStarted())
schedulerState = SchedulerStates.STOPPED.toString();
else if (scheduler.isStarted() && scheduler.isInStandbyMode())
schedulerState = SchedulerStates.PAUSED.toString();
else
schedulerState = SchedulerStates.RUNNING.toString();
return Collections.singletonMap("data", schedulerState.toLowerCase());
}
@RequestMapping("/pause")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void pause() throws SchedulerException {
scheduler.standby();
}
@RequestMapping(value = "/config", method = RequestMethod.POST)
public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config)
throws SchedulerException {
SimpleTrigger trigger = (SimpleTrigger) triggerMonitor.getTrigger();
TriggerBuilder<SimpleTrigger> triggerBuilder = trigger.getTriggerBuilder();
int intervalInSeconds = fromTriggerPerDayToMillSecInterval(config.getTriggerPerDay());
Trigger newTrigger = triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(intervalInSeconds).withRepeatCount(config.getMaxCount() - 1))
.build();
scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger);
triggerMonitor.setTrigger(newTrigger);
return config;
}
@RequestMapping("/resume")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void resume() throws SchedulerException {
scheduler.start();
}
@RequestMapping("/run")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void run() throws SchedulerException {
log.info("Starting scheduler...");
scheduler.start();
}
@ResponseStatus(HttpStatus.NO_CONTENT)
@RequestMapping("/stop")
public void stop() throws SchedulerException {
log.info("Stopping scheduler...");
scheduler.shutdown(true);
}
@SuppressWarnings("unused")
private long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) {
return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills);
}
private int fromTriggerPerDayToMillSecInterval(long triggerPerDay) {
return (int) Math.ceil(Long.valueOf(MILLS_IN_A_DAY) / triggerPerDay); //with ceil the triggerPerDay is a max value
}
private int fromTriggerPerDayToSecInterval(long triggerPerDay) {
return (int) Math.ceil(Long.valueOf(SEC_IN_A_DAY) / triggerPerDay);
}
}
package it.fabioformosa.quartzmanager.controllers;
import java.util.Collections;
import java.util.Map;
import javax.annotation.Resource;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.triggers.SimpleTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
import it.fabioformosa.quartzmanager.dto.TriggerProgress;
import it.fabioformosa.quartzmanager.enums.SchedulerStates;
import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor;
/**
* This controller provides scheduler info about config and status. It provides
* also methods to set new config and start/stop/resume the scheduler.
*
* @author Fabio.Formosa
*
*/
@RestController
@RequestMapping("/scheduler")
public class SchedulerController {
private static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24;
private static final int SEC_IN_A_DAY = 60 * 60 * 24;
private final Logger log = LoggerFactory.getLogger(SchedulerController.class);
@Resource
private Scheduler scheduler;
@Resource
private TriggerMonitor triggerMonitor;
@RequestMapping(value = "/config", method = RequestMethod.GET)
public SchedulerConfigParam getConfig() {
log.debug("SCHEDULER - GET CONFIG params");
SimpleTrigger simpleTrigger = (SimpleTrigger) triggerMonitor.getTrigger();
int maxCount = simpleTrigger.getRepeatCount() + 1;
long triggersPerDay = fromMillsIntervalToTriggerPerDay(simpleTrigger.getRepeatInterval());
return new SchedulerConfigParam(triggersPerDay, maxCount);
}
@RequestMapping("/progress")
public TriggerProgress getProgressInfo() throws SchedulerException {
log.trace("SCHEDULER - GET PROGRESS INFO");
TriggerProgress progress = new TriggerProgress();
SimpleTriggerImpl jobTrigger = (SimpleTriggerImpl) scheduler.getTrigger(triggerMonitor.getTrigger().getKey());
if (jobTrigger != null && jobTrigger.getJobKey() != null) {
progress.setJobKey(jobTrigger.getJobKey().getName());
progress.setJobClass(jobTrigger.getClass().getSimpleName());
progress.setTimesTriggered(jobTrigger.getTimesTriggered());
progress.setRepeatCount(jobTrigger.getRepeatCount());
progress.setFinalFireTime(jobTrigger.getFinalFireTime());
progress.setNextFireTime(jobTrigger.getNextFireTime());
progress.setPreviousFireTime(jobTrigger.getPreviousFireTime());
}
return progress;
}
@GetMapping(produces = "application/json")
public Map<String, String> getStatus() throws SchedulerException {
log.trace("SCHEDULER - GET STATUS");
String schedulerState = "";
if (scheduler.isShutdown() || !scheduler.isStarted())
schedulerState = SchedulerStates.STOPPED.toString();
else if (scheduler.isStarted() && scheduler.isInStandbyMode())
schedulerState = SchedulerStates.PAUSED.toString();
else
schedulerState = SchedulerStates.RUNNING.toString();
return Collections.singletonMap("data", schedulerState.toLowerCase());
}
@RequestMapping("/pause")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void pause() throws SchedulerException {
log.info("SCHEDULER - PAUSE COMMAND");
scheduler.standby();
}
@RequestMapping(value = "/config", method = RequestMethod.POST)
public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) throws SchedulerException {
log.info("SCHEDULER - NEW CONFIG {}", config);
SimpleTrigger trigger = (SimpleTrigger) triggerMonitor.getTrigger();
TriggerBuilder<SimpleTrigger> triggerBuilder = trigger.getTriggerBuilder();
int intervalInMills = fromTriggerPerDayToMillsInterval(config.getTriggerPerDay());
Trigger newTrigger = triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMilliseconds(intervalInMills).withRepeatCount(config.getMaxCount() - 1)).build();
scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger);
triggerMonitor.setTrigger(newTrigger);
return config;
}
@RequestMapping("/resume")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void resume() throws SchedulerException {
log.info("SCHEDULER - RESUME COMMAND");
scheduler.start();
}
@RequestMapping("/run")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void run() throws SchedulerException {
log.info("SCHEDULER - START COMMAND");
scheduler.start();
}
@ResponseStatus(HttpStatus.NO_CONTENT)
@RequestMapping("/stop")
public void stop() throws SchedulerException {
log.info("SCHEDULER - STOP COMMAND");
scheduler.shutdown(true);
}
private long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) {
return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills);
}
private int fromTriggerPerDayToMillsInterval(long triggerPerDay) {
return (int) Math.ceil(Long.valueOf(MILLS_IN_A_DAY) / triggerPerDay); // with ceil the triggerPerDay is a max value
}
@SuppressWarnings("unused")
private int fromTriggerPerDayToSecInterval(long triggerPerDay) {
return (int) Math.ceil(Long.valueOf(SEC_IN_A_DAY) / triggerPerDay);
}
}

View File

@@ -10,25 +10,26 @@ import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
@Controller
@RequestMapping("/session")
public class SessionController {
private final Logger log = LoggerFactory.getLogger(SessionController.class);
private final Logger log = LoggerFactory.getLogger(SessionController.class);
@RequestMapping("/invalidate")
@PreAuthorize("hasAuthority('ADMIN')")
public String invalidateSession(HttpSession session) {
session.invalidate();
log.info("Invalidated current session!");
return "redirect:/manager";
}
@RequestMapping("/invalidate")
@PreAuthorize("hasAuthority('ADMIN')")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void invalidateSession(HttpSession session) {
session.invalidate();
log.info("Invalidated current session!");
}
@RequestMapping("/refresh")
@PreAuthorize("hasAuthority('ADMIN')")
public HttpEntity<Void> refreshSession(HttpSession session) {
return new ResponseEntity<>(HttpStatus.OK);
}
@RequestMapping("/refresh")
@PreAuthorize("hasAuthority('ADMIN')")
public HttpEntity<Void> refreshSession(HttpSession session) {
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -1,65 +1,72 @@
package it.fabioformosa.quartzmanager.controllers;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController {
// @Autowired
// private UserService userService;
// @RequestMapping(method = POST, value = "/signup")
// public ResponseEntity<?> addUser(@RequestBody UserRequest userRequest,
// UriComponentsBuilder ucBuilder) {
//
// User existUser = this.userService.findByUsername(userRequest.getUsername());
// if (existUser != null)
// throw new ResourceConflictException(userRequest.getId(), "Username already exists");
// User user = this.userService.save(userRequest);
// HttpHeaders headers = new HttpHeaders();
// headers.setLocation(ucBuilder.path("/api/user/{userId}").buildAndExpand(user.getId()).toUri());
// return new ResponseEntity<>(user, HttpStatus.CREATED);
// }
//
// @RequestMapping(method = GET, value = "/user/all")
// public List<User> loadAll() {
// return this.userService.findAll();
// }
//
// @RequestMapping(method = GET, value = "/user/{userId}")
// public User loadById(@PathVariable Long userId) {
// return this.userService.findById(userId);
// }
//
//
// @RequestMapping(method = GET, value = "/user/reset-credentials")
// public ResponseEntity<Map> resetCredentials() {
// this.userService.resetCredentials();
// Map<String, String> result = new HashMap<>();
// result.put("result", "success");
// return ResponseEntity.accepted().body(result);
// }
/*
* We are not using userService.findByUsername here(we could), so it is good that we are making
* sure that the user has role "ROLE_USER" to access this endpoint.
*/
// @RequestMapping("/whoami")
// // @PreAuthorize("hasRole('USER')")
// public User user() {
// return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
// }
@RequestMapping("/whoami")
@PreAuthorize("isAuthenticated()")
public Object user() {
return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
}
package it.fabioformosa.quartzmanager.controllers;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController {
/**
* JWT Temporary disabled
*
* @author Fabio.Formosa
*
*/
// @Autowired
// private UserService userService;
// @RequestMapping(method = POST, value = "/signup")
// public ResponseEntity<?> addUser(@RequestBody UserRequest userRequest,
// UriComponentsBuilder ucBuilder) {
//
// User existUser = this.userService.findByUsername(userRequest.getUsername());
// if (existUser != null)
// throw new ResourceConflictException(userRequest.getId(), "Username already exists");
// User user = this.userService.save(userRequest);
// HttpHeaders headers = new HttpHeaders();
// headers.setLocation(ucBuilder.path("/api/user/{userId}").buildAndExpand(user.getId()).toUri());
// return new ResponseEntity<>(user, HttpStatus.CREATED);
// }
//
// @RequestMapping(method = GET, value = "/user/all")
// public List<User> loadAll() {
// return this.userService.findAll();
// }
//
// @RequestMapping(method = GET, value = "/user/{userId}")
// public User loadById(@PathVariable Long userId) {
// return this.userService.findById(userId);
// }
//
//
// @RequestMapping(method = GET, value = "/user/reset-credentials")
// public ResponseEntity<Map> resetCredentials() {
// this.userService.resetCredentials();
// Map<String, String> result = new HashMap<>();
// result.put("result", "success");
// return ResponseEntity.accepted().body(result);
// }
/*
* We are not using userService.findByUsername here(we could), so it is good that we are making
* sure that the user has role "ROLE_USER" to access this endpoint.
*/
// @RequestMapping("/whoami")
// // @PreAuthorize("hasRole('USER')")
// public User user() {
// return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
// }
@RequestMapping("/whoami")
@PreAuthorize("isAuthenticated()")
public Object user() {
return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
}

View File

@@ -2,29 +2,39 @@ package it.fabioformosa.quartzmanager.dto;
public class SchedulerConfigParam {
public long triggerPerDay;
public int maxCount;
public long triggerPerDay;
public int maxCount;
public int getMaxCount() {
return maxCount;
}
public SchedulerConfigParam() {
super();
}
public long getTriggerPerDay() {
return triggerPerDay;
}
public SchedulerConfigParam(long triggerPerDay, int maxCount) {
super();
this.triggerPerDay = triggerPerDay;
this.maxCount = maxCount;
}
public void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
public int getMaxCount() {
return maxCount;
}
public void setTriggerPerDay(long triggerPerDay) {
this.triggerPerDay = triggerPerDay;
}
public long getTriggerPerDay() {
return triggerPerDay;
}
@Override
public String toString() {
return "SchedulerConfigParam [triggerPerDay=" + triggerPerDay
+ ", maxCount=" + maxCount + "]";
}
public void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
public void setTriggerPerDay(long triggerPerDay) {
this.triggerPerDay = triggerPerDay;
}
@Override
public String toString() {
return "SchedulerConfigParam [triggerPerDay=" + triggerPerDay
+ ", maxCount=" + maxCount + "]";
}
}

View File

@@ -0,0 +1,5 @@
package it.fabioformosa.quartzmanager.enums;
public enum SchedulerStates {
RUNNING, STOPPED, PAUSED
}

View File

@@ -1,15 +1,14 @@
package it.fabioformosa.quartzmanager.exceptions;
public class ResourceConflictException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1791564636123821405L;
private Long resourceId;
public ResourceConflictException(Long resourceId, String message) {
super(message);
this.setResourceId(resourceId);
setResourceId(resourceId);
}
public Long getResourceId() {

View File

@@ -13,38 +13,45 @@ import org.springframework.messaging.simp.SimpMessageSendingOperations;
import it.fabioformosa.quartzmanager.aspects.ProgressUpdater;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord;
/**
* Extends this class to create a job that produces LogRecord to be displayed
* into the GUI panel
*
* @author Fabio.Formosa
*
*/
public abstract class AbstractLoggingJob implements Job {
private static final Logger log = LoggerFactory.getLogger(AbstractLoggingJob.class);
private static final Logger log = LoggerFactory.getLogger(AbstractLoggingJob.class);
@Autowired
private SimpMessageSendingOperations messagingTemplate;
@Autowired
private SimpMessageSendingOperations messagingTemplate;
@Resource
private ProgressUpdater progressUpdater;
@Resource
private ProgressUpdater progressUpdater;
/**
*
* @param jobExecutionContext
* @return final log
*/
public abstract LogRecord doIt(JobExecutionContext jobExecutionContext);
/**
*
* @param jobExecutionContext
* @return final log
*/
public abstract LogRecord doIt(JobExecutionContext jobExecutionContext);
@Override
public final void execute(JobExecutionContext jobExecutionContext) {
try {
LogRecord logMsg = doIt(jobExecutionContext);
logAndSend(logMsg);
progressUpdater.update();
} catch (SchedulerException e) {
log.error("Error updating progress " + e.getMessage());
}
}
@Override
public final void execute(JobExecutionContext jobExecutionContext) {
try {
LogRecord logMsg = doIt(jobExecutionContext);
logAndSend(logMsg);
progressUpdater.update();
} catch (SchedulerException e) {
log.error("Error updating progress " + e.getMessage());
}
}
public void logAndSend(LogRecord logRecord) {
log.info(logRecord.getMessage());
logRecord.setThreadName(Thread.currentThread().getName());
messagingTemplate.convertAndSend("/topic/logs", logRecord);
}
public void logAndSend(LogRecord logRecord) {
log.info(logRecord.getMessage());
logRecord.setThreadName(Thread.currentThread().getName());
messagingTemplate.convertAndSend("/topic/logs", logRecord);
}
}

View File

@@ -1,26 +0,0 @@
package it.fabioformosa.quartzmanager.jobs;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord.LogType;
public class MisfireTestJob extends AbstractLoggingJob {
private Logger log = LoggerFactory.getLogger(MisfireTestJob.class);
@Override
public LogRecord doIt(JobExecutionContext jobExecutionContext) {
try {
log.info("{} is going to sleep...", Thread.currentThread().getName());
Thread.sleep(10 * 1000);
log.info("{} woke up!", Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
return new LogRecord(LogType.INFO, "Hello!");
}
}

View File

@@ -2,60 +2,66 @@ package it.fabioformosa.quartzmanager.jobs.entities;
import java.util.Date;
/**
* Log record produced by a job at the end of each run
*
* @author Fabio.Formosa
*
*/
public class LogRecord {
public enum LogType {
INFO, WARN, ERROR;
}
public enum LogType {
INFO, WARN, ERROR;
}
private Date date;
private LogType type;
private Date date;
private LogType type;
private String message;
private String threadName;
private String message;
private String threadName;
public LogRecord(LogType type, String msg) {
super();
this.type = type;
message = msg;
date = new Date();
}
public LogRecord(LogType type, String msg) {
super();
this.type = type;
message = msg;
date = new Date();
}
public Date getDate() {
return date;
}
public Date getDate() {
return date;
}
public String getMessage() {
return message;
}
public String getMessage() {
return message;
}
public String getThreadName() {
return threadName;
}
public String getThreadName() {
return threadName;
}
public LogType getType() {
return type;
}
public LogType getType() {
return type;
}
public void setDate(Date date) {
this.date = date;
}
public void setDate(Date date) {
this.date = date;
}
public void setMessage(String msg) {
message = msg;
}
public void setMessage(String msg) {
message = msg;
}
public void setThreadName(String threadName) {
this.threadName = threadName;
}
public void setThreadName(String threadName) {
this.threadName = threadName;
}
public void setType(LogType type) {
this.type = type;
}
public void setType(LogType type) {
this.type = type;
}
@Override
public String toString() {
return "LogRecord [date=" + date + ", type=" + type + ", message=" + message + "]";
}
@Override
public String toString() {
return "LogRecord [date=" + date + ", type=" + type + ", message=" + message + "]";
}
}

View File

@@ -1,7 +1,8 @@
package it.fabioformosa.quartzmanager.jobs;
package it.fabioformosa.quartzmanager.jobs.myjobs;
import org.quartz.JobExecutionContext;
import it.fabioformosa.quartzmanager.jobs.AbstractLoggingJob;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord.LogType;

View File

@@ -0,0 +1,37 @@
package it.fabioformosa.quartzmanager.jobs.tests;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import it.fabioformosa.quartzmanager.jobs.AbstractLoggingJob;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord.LogType;
/**
* This job can be used to test the misfire policy. It pretends to be a long
* processing job (sleeping for a while)
*
* @author Fabio.Formosa
*
*/
public class MisfireTestJob extends AbstractLoggingJob {
private Logger log = LoggerFactory.getLogger(MisfireTestJob.class);
@Override
public LogRecord doIt(JobExecutionContext jobExecutionContext) {
try {
log.info("{} is going to sleep...", Thread.currentThread().getName());
Thread.sleep(10 * 1000);
log.info("{} woke up!", Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
return new LogRecord(LogType.INFO, "Hello!");
}
}

View File

@@ -1,156 +1,161 @@
package it.fabioformosa.quartzmanager.security;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
//@Component
public class TokenHelper {
@Value("${app.name}")
private String APP_NAME;
@Value("${jwt.secret}")
private String SECRET;
@Value("${jwt.expires_in}")
private int EXPIRES_IN;
@Value("${jwt.header}")
private String AUTH_HEADER;
@Value("${jwt.cookie}")
private String AUTH_COOKIE;
@Autowired
UserDetailsService userDetailsService;
private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512;
public Boolean canTokenBeRefreshed(String token) {
try {
final Date expirationDate = getClaimsFromToken(token).getExpiration();
String username = getUsernameFromToken(token);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
return expirationDate.compareTo(generateCurrentDate()) > 0;
} catch (Exception e) {
return false;
}
}
public String generateToken(String username) {
return Jwts.builder()
.setIssuer( APP_NAME )
.setSubject(username)
.setIssuedAt(generateCurrentDate())
.setExpiration(generateExpirationDate())
.signWith( SIGNATURE_ALGORITHM, SECRET )
.compact();
}
/**
* Find a specific HTTP cookie in a request.
*
* @param request
* The HTTP request object.
* @param name
* The cookie name to look for.
* @return The cookie, or <code>null</code> if not found.
*/
public Cookie getCookieValueByName(HttpServletRequest request, String name) {
if (request.getCookies() == null)
return null;
for (int i = 0; i < request.getCookies().length; i++)
if (request.getCookies()[i].getName().equals(name))
return request.getCookies()[i];
return null;
}
public String getToken( HttpServletRequest request ) {
/**
* Getting the token from Cookie store
*/
Cookie authCookie = getCookieValueByName( request, AUTH_COOKIE );
if ( authCookie != null )
return authCookie.getValue();
/**
* Getting the token from Authentication header
* e.g Bearer your_token
*/
String authHeader = request.getHeader(AUTH_HEADER);
if ( authHeader != null && authHeader.startsWith("Bearer "))
return authHeader.substring(7);
return null;
}
public String getUsernameFromToken(String token) {
String username;
try {
final Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
public String refreshToken(String token) {
String refreshedToken;
try {
final Claims claims = getClaimsFromToken(token);
claims.setIssuedAt(generateCurrentDate());
refreshedToken = generateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}
private Date generateCurrentDate() {
return new Date(getCurrentTimeMillis());
}
private Date generateExpirationDate() {
return new Date(getCurrentTimeMillis() + this.EXPIRES_IN * 1000);
}
private Claims getClaimsFromToken(String token) {
Claims claims;
try {
claims = Jwts.parser()
.setSigningKey(this.SECRET)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
private long getCurrentTimeMillis() {
return DateTime.now().getMillis();
}
String generateToken(Map<String, Object> claims) {
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith( SIGNATURE_ALGORITHM, SECRET )
.compact();
}
}
package it.fabioformosa.quartzmanager.security;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetailsService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
* JWT Temporary disabled
*
* @author Fabio.Formosa
*
*/
//@Component
public class TokenHelper {
@Value("${app.name}")
private String APP_NAME;
@Value("${jwt.secret}")
private String SECRET;
@Value("${jwt.expires_in}")
private int EXPIRES_IN;
@Value("${jwt.header}")
private String AUTH_HEADER;
@Value("${jwt.cookie}")
private String AUTH_COOKIE;
@Autowired
UserDetailsService userDetailsService;
private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512;
public Boolean canTokenBeRefreshed(String token) {
try {
final Date expirationDate = getClaimsFromToken(token).getExpiration();
// String username = getUsernameFromToken(token);
// UserDetails userDetails = userDetailsService.loadUserByUsername(username);
return expirationDate.compareTo(generateCurrentDate()) > 0;
} catch (Exception e) {
return false;
}
}
public String generateToken(String username) {
return Jwts.builder()
.setIssuer( APP_NAME )
.setSubject(username)
.setIssuedAt(generateCurrentDate())
.setExpiration(generateExpirationDate())
.signWith( SIGNATURE_ALGORITHM, SECRET )
.compact();
}
/**
* Find a specific HTTP cookie in a request.
*
* @param request
* The HTTP request object.
* @param name
* The cookie name to look for.
* @return The cookie, or <code>null</code> if not found.
*/
public Cookie getCookieValueByName(HttpServletRequest request, String name) {
if (request.getCookies() == null)
return null;
for (int i = 0; i < request.getCookies().length; i++)
if (request.getCookies()[i].getName().equals(name))
return request.getCookies()[i];
return null;
}
public String getToken( HttpServletRequest request ) {
/**
* Getting the token from Cookie store
*/
Cookie authCookie = getCookieValueByName( request, AUTH_COOKIE );
if ( authCookie != null )
return authCookie.getValue();
/**
* Getting the token from Authentication header
* e.g Bearer your_token
*/
String authHeader = request.getHeader(AUTH_HEADER);
if ( authHeader != null && authHeader.startsWith("Bearer "))
return authHeader.substring(7);
return null;
}
public String getUsernameFromToken(String token) {
String username;
try {
final Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
public String refreshToken(String token) {
String refreshedToken;
try {
final Claims claims = getClaimsFromToken(token);
claims.setIssuedAt(generateCurrentDate());
refreshedToken = generateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}
private Date generateCurrentDate() {
return new Date(getCurrentTimeMillis());
}
private Date generateExpirationDate() {
return new Date(getCurrentTimeMillis() + EXPIRES_IN * 1000);
}
private Claims getClaimsFromToken(String token) {
Claims claims;
try {
claims = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
private long getCurrentTimeMillis() {
return DateTime.now().getMillis();
}
String generateToken(Map<String, Object> claims) {
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith( SIGNATURE_ALGORITHM, SECRET )
.compact();
}
}

View File

@@ -1,49 +1,55 @@
package it.fabioformosa.quartzmanager.security.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name="Authority")
public class Authority implements GrantedAuthority {
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Column(name="name")
String name;
@Override
public String getAuthority() {
return name;
}
@JsonIgnore
public Long getId() {
return id;
}
@JsonIgnore
public String getName() {
return name;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
package it.fabioformosa.quartzmanager.security.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* Temporary enabled only inMemoryAuthentication
*
* @author Fabio.Formosa
*
*/
@Entity
@Table(name="Authority")
public class Authority implements GrantedAuthority {
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Column(name="name")
String name;
@Override
public String getAuthority() {
return name;
}
@JsonIgnore
public Long getId() {
return id;
}
@JsonIgnore
public String getName() {
return name;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -1,129 +1,135 @@
package it.fabioformosa.quartzmanager.security.model;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name = "USER")
public class User implements UserDetails, Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "username")
private String username;
@JsonIgnore
@Column(name = "password")
private String password;
@Column(name = "firstname")
private String firstname;
@Column(name = "lastname")
private String lastname;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "user_authority",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id"))
private List<Authority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
public String getFirstname() {
return firstname;
}
public Long getId() {
return id;
}
public String getLastname() {
return lastname;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
// We can add the below fields in the users table.
// For now, they are hardcoded.
@JsonIgnore
@Override
public boolean isAccountNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isAccountNonLocked() {
return true;
}
@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isEnabled() {
return true;
}
public void setAuthorities(List<Authority> authorities) {
this.authorities = authorities;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public void setId(Long id) {
this.id = id;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
}
package it.fabioformosa.quartzmanager.security.model;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* Temporary enabled only inMemoryAuthentication
*
* @author Fabio.Formosa
*
*/
@Entity
@Table(name = "USER")
public class User implements UserDetails, Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "username")
private String username;
@JsonIgnore
@Column(name = "password")
private String password;
@Column(name = "firstname")
private String firstname;
@Column(name = "lastname")
private String lastname;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "user_authority",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id"))
private List<Authority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public String getFirstname() {
return firstname;
}
public Long getId() {
return id;
}
public String getLastname() {
return lastname;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
// We can add the below fields in the users table.
// For now, they are hardcoded.
@JsonIgnore
@Override
public boolean isAccountNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isAccountNonLocked() {
return true;
}
@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isEnabled() {
return true;
}
public void setAuthorities(List<Authority> authorities) {
this.authorities = authorities;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public void setId(Long id) {
this.id = id;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
}

View File

@@ -1,23 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<logger name="it.fabioformosa" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<logger name="org.springframework" level="WARN" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%.7thread] %-5level [%-40.40logger{49}:%-3L] --- %m%n
</Pattern>
</layout>
</appender>
<logger name="it.fabioformosa" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<logger name="org.springframework" level="WARN" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>