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; package it.fabioformosa.quartzmanager.configuration;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import it.fabioformosa.quartzmanager.security.ComboEntryPoint; import it.fabioformosa.quartzmanager.security.ComboEntryPoint;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler; import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler;
import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler; import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler;
import it.fabioformosa.quartzmanager.security.auth.LogoutSuccess; 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.auth.TokenAuthenticationFilter; import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService;
import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService;
/**
//@Configuration * JWT Temporary disabled
//@EnableGlobalMethodSecurity(prePostEnabled = true) *
public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter { * @author Fabio.Formosa
*
@Value("${jwt.cookie}") */
private String TOKEN_COOKIE;
//@Configuration
@Autowired //@EnableGlobalMethodSecurity(prePostEnabled = true)
private CustomUserDetailsService jwtUserDetailsService; public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
@Autowired @Value("${jwt.cookie}")
private RestAuthenticationEntryPoint restAuthenticationEntryPoint; private String TOKEN_COOKIE;
@Resource
private ComboEntryPoint comboEntryPoint; @Autowired
private CustomUserDetailsService jwtUserDetailsService;
@Autowired
private LogoutSuccess logoutSuccess; // @Autowired
// private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Autowired @Resource
private AuthenticationSuccessHandler authenticationSuccessHandler; private ComboEntryPoint comboEntryPoint;
@Autowired @Autowired
private AuthenticationFailureHandler authenticationFailureHandler; private LogoutSuccess logoutSuccess;
@Bean @Autowired
@Override private AuthenticationSuccessHandler authenticationSuccessHandler;
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean(); @Autowired
} private AuthenticationFailureHandler authenticationFailureHandler;
@Autowired @Bean
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) @Override
throws Exception { public AuthenticationManager authenticationManagerBean() throws Exception {
authenticationManagerBuilder.userDetailsService(jwtUserDetailsService) return super.authenticationManagerBean();
.passwordEncoder(passwordEncoder()); }
} @Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)
@Bean throws Exception {
public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception { authenticationManagerBuilder.userDetailsService(jwtUserDetailsService)
return new TokenAuthenticationFilter(); .passwordEncoder(passwordEncoder());
}
}
@Bean
public PasswordEncoder passwordEncoder() { @Bean
return new BCryptPasswordEncoder(); public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
} return new TokenAuthenticationFilter();
}
@Override
protected void configure(HttpSecurity http) throws Exception { @Bean
// http.csrf().ignoringAntMatchers("/api/login", "/api/signup") public PasswordEncoder passwordEncoder() {
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and() return new BCryptPasswordEncoder();
http.cors().and().csrf().disable() }
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.exceptionHandling().authenticationEntryPoint(comboEntryPoint).and() @Override
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class) protected void configure(HttpSecurity http) throws Exception {
.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/api/login") // http.csrf().ignoringAntMatchers("/api/login", "/api/signup")
.successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler) // .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/api/logout")) http.cors().and().csrf().disable()
.logoutSuccessHandler(logoutSuccess).deleteCookies(TOKEN_COOKIE); .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.exceptionHandling().authenticationEntryPoint(comboEntryPoint).and()
} .addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class)
.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/api/login")
@Bean .successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler)
CorsConfigurationSource corsConfigurationSource() { .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/api/logout"))
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); .logoutSuccessHandler(logoutSuccess).deleteCookies(TOKEN_COOKIE);
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source; }
}
@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; package it.fabioformosa.quartzmanager.controllers;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import it.fabioformosa.quartzmanager.security.TokenHelper; import it.fabioformosa.quartzmanager.security.TokenHelper;
import it.fabioformosa.quartzmanager.security.model.UserTokenState; import it.fabioformosa.quartzmanager.security.model.UserTokenState;
import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService; import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService;
//@RestController /**
//@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE ) * JWT Temporary disabled
public class AuthenticationController { *
* @author Fabio.Formosa
static class PasswordChanger { *
public String oldPassword; */
public String newPassword;
} //@RestController
//@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE )
@Autowired public class AuthenticationController {
private CustomUserDetailsService userDetailsService;
static class PasswordChanger {
@Autowired public String oldPassword;
TokenHelper tokenHelper; public String newPassword;
}
@Value("${jwt.expires_in}")
private int EXPIRES_IN; @Autowired
private CustomUserDetailsService userDetailsService;
@Value("${jwt.cookie}")
private String TOKEN_COOKIE; @Autowired
TokenHelper tokenHelper;
@RequestMapping(value = "/changePassword", method = RequestMethod.POST)
@PreAuthorize("hasRole('USER')") @Value("${jwt.expires_in}")
public ResponseEntity<?> changePassword(@RequestBody PasswordChanger passwordChanger) { private int EXPIRES_IN;
userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword);
Map<String, String> result = new HashMap<>(); @Value("${jwt.cookie}")
result.put( "result", "success" ); private String TOKEN_COOKIE;
return ResponseEntity.accepted().body(result);
} @RequestMapping(value = "/changePassword", method = RequestMethod.POST)
@PreAuthorize("hasRole('USER')")
@RequestMapping(value = "/refresh", method = RequestMethod.GET) public ResponseEntity<?> changePassword(@RequestBody PasswordChanger passwordChanger) {
public ResponseEntity<?> refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) { userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword);
Map<String, String> result = new HashMap<>();
String authToken = tokenHelper.getToken( request ); result.put( "result", "success" );
if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) { return ResponseEntity.accepted().body(result);
// TODO check user password last update }
String refreshedToken = tokenHelper.refreshToken(authToken);
@RequestMapping(value = "/refresh", method = RequestMethod.GET)
Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken ); public ResponseEntity<?> refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) {
authCookie.setPath( "/" );
authCookie.setHttpOnly( true ); String authToken = tokenHelper.getToken( request );
authCookie.setMaxAge( EXPIRES_IN ); if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) {
// Add cookie to response // TODO check user password last update
response.addCookie( authCookie ); String refreshedToken = tokenHelper.refreshToken(authToken);
UserTokenState userTokenState = new UserTokenState(refreshedToken, EXPIRES_IN); Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken );
return ResponseEntity.ok(userTokenState); authCookie.setPath( "/" );
} else { authCookie.setHttpOnly( true );
UserTokenState userTokenState = new UserTokenState(); authCookie.setMaxAge( EXPIRES_IN );
return ResponseEntity.accepted().body(userTokenState); // 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; package it.fabioformosa.quartzmanager.controllers;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.quartz.DailyTimeIntervalTrigger; import org.quartz.Scheduler;
import org.quartz.Scheduler; import org.quartz.SchedulerException;
import org.quartz.SchedulerException; import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleScheduleBuilder; import org.quartz.SimpleTrigger;
import org.quartz.SimpleTrigger; import org.quartz.Trigger;
import org.quartz.Trigger; import org.quartz.TriggerBuilder;
import org.quartz.TriggerBuilder; import org.quartz.impl.triggers.SimpleTriggerImpl;
import org.quartz.impl.triggers.SimpleTriggerImpl; import org.slf4j.Logger;
import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestController;
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
import it.fabioformosa.quartzmanager.controllers.ManagerController.SchedulerStates; import it.fabioformosa.quartzmanager.dto.TriggerProgress;
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam; import it.fabioformosa.quartzmanager.enums.SchedulerStates;
import it.fabioformosa.quartzmanager.dto.TriggerProgress; import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor;
import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor;
/**
@RestController * This controller provides scheduler info about config and status. It provides
@RequestMapping("/scheduler") * also methods to set new config and start/stop/resume the scheduler.
public class SchedulerController { *
* @author Fabio.Formosa
private static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24; *
private static final int SEC_IN_A_DAY = 60 * 60 * 24; */
@RestController
private final Logger log = LoggerFactory.getLogger(SchedulerController.class); @RequestMapping("/scheduler")
public class SchedulerController {
@Resource
private Scheduler scheduler; private static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24;
private static final int SEC_IN_A_DAY = 60 * 60 * 24;
@Resource
private TriggerMonitor triggerMonitor; private final Logger log = LoggerFactory.getLogger(SchedulerController.class);
@RequestMapping(value = "/config", method = RequestMethod.GET) @Resource
public SchedulerConfigParam getConfig() { private Scheduler scheduler;
SchedulerConfigParam config = new SchedulerConfigParam();
@Resource
int maxCount = 0; private TriggerMonitor triggerMonitor;
long repeatIntervalInMills = 0;
if (triggerMonitor.getTrigger() instanceof SimpleTrigger) { @RequestMapping(value = "/config", method = RequestMethod.GET)
SimpleTrigger simpleTrigger = (SimpleTrigger) triggerMonitor.getTrigger(); public SchedulerConfigParam getConfig() {
maxCount = simpleTrigger.getRepeatCount() + 1; log.debug("SCHEDULER - GET CONFIG params");
repeatIntervalInMills = fromTriggerPerDayToMillSecInterval(simpleTrigger.getRepeatInterval()); SimpleTrigger simpleTrigger = (SimpleTrigger) triggerMonitor.getTrigger();
} else if (triggerMonitor.getTrigger() instanceof DailyTimeIntervalTrigger) {
DailyTimeIntervalTrigger dailyTimeIntervalTrigger = (DailyTimeIntervalTrigger) triggerMonitor int maxCount = simpleTrigger.getRepeatCount() + 1;
.getTrigger(); long triggersPerDay = fromMillsIntervalToTriggerPerDay(simpleTrigger.getRepeatInterval());
maxCount = dailyTimeIntervalTrigger.getRepeatCount() + 1;
repeatIntervalInMills = fromTriggerPerDayToSecInterval( return new SchedulerConfigParam(triggersPerDay, maxCount);
dailyTimeIntervalTrigger.getRepeatInterval()); }
}
@RequestMapping("/progress")
config.setMaxCount(maxCount); public TriggerProgress getProgressInfo() throws SchedulerException {
config.setTriggerPerDay(repeatIntervalInMills); log.trace("SCHEDULER - GET PROGRESS INFO");
return config; TriggerProgress progress = new TriggerProgress();
}
SimpleTriggerImpl jobTrigger = (SimpleTriggerImpl) scheduler.getTrigger(triggerMonitor.getTrigger().getKey());
@RequestMapping("/progress") if (jobTrigger != null && jobTrigger.getJobKey() != null) {
public TriggerProgress getProgressInfo() throws SchedulerException { progress.setJobKey(jobTrigger.getJobKey().getName());
progress.setJobClass(jobTrigger.getClass().getSimpleName());
SimpleTriggerImpl jobTrigger = (SimpleTriggerImpl) scheduler progress.setTimesTriggered(jobTrigger.getTimesTriggered());
.getTrigger(triggerMonitor.getTrigger().getKey()); progress.setRepeatCount(jobTrigger.getRepeatCount());
progress.setFinalFireTime(jobTrigger.getFinalFireTime());
TriggerProgress progress = new TriggerProgress(); progress.setNextFireTime(jobTrigger.getNextFireTime());
if (jobTrigger != null && jobTrigger.getJobKey() != null) { progress.setPreviousFireTime(jobTrigger.getPreviousFireTime());
progress.setJobKey(jobTrigger.getJobKey().getName()); }
progress.setJobClass(jobTrigger.getClass().getSimpleName());
progress.setTimesTriggered(jobTrigger.getTimesTriggered()); return progress;
progress.setRepeatCount(jobTrigger.getRepeatCount()); }
progress.setFinalFireTime(jobTrigger.getFinalFireTime());
progress.setNextFireTime(jobTrigger.getNextFireTime()); @GetMapping(produces = "application/json")
progress.setPreviousFireTime(jobTrigger.getPreviousFireTime()); public Map<String, String> getStatus() throws SchedulerException {
} log.trace("SCHEDULER - GET STATUS");
return progress; String schedulerState = "";
} if (scheduler.isShutdown() || !scheduler.isStarted())
schedulerState = SchedulerStates.STOPPED.toString();
@GetMapping(produces = "application/json") else if (scheduler.isStarted() && scheduler.isInStandbyMode())
public Map<String, String> getStatus() throws SchedulerException { schedulerState = SchedulerStates.PAUSED.toString();
String schedulerState = ""; else
if (scheduler.isShutdown() || !scheduler.isStarted()) schedulerState = SchedulerStates.RUNNING.toString();
schedulerState = SchedulerStates.STOPPED.toString(); return Collections.singletonMap("data", schedulerState.toLowerCase());
else if (scheduler.isStarted() && scheduler.isInStandbyMode()) }
schedulerState = SchedulerStates.PAUSED.toString();
else @RequestMapping("/pause")
schedulerState = SchedulerStates.RUNNING.toString(); @ResponseStatus(HttpStatus.NO_CONTENT)
return Collections.singletonMap("data", schedulerState.toLowerCase()); public void pause() throws SchedulerException {
} log.info("SCHEDULER - PAUSE COMMAND");
scheduler.standby();
@RequestMapping("/pause") }
@ResponseStatus(HttpStatus.NO_CONTENT)
public void pause() throws SchedulerException { @RequestMapping(value = "/config", method = RequestMethod.POST)
scheduler.standby(); public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) throws SchedulerException {
} log.info("SCHEDULER - NEW CONFIG {}", config);
SimpleTrigger trigger = (SimpleTrigger) triggerMonitor.getTrigger();
@RequestMapping(value = "/config", method = RequestMethod.POST)
public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) TriggerBuilder<SimpleTrigger> triggerBuilder = trigger.getTriggerBuilder();
throws SchedulerException {
int intervalInMills = fromTriggerPerDayToMillsInterval(config.getTriggerPerDay());
SimpleTrigger trigger = (SimpleTrigger) triggerMonitor.getTrigger(); Trigger newTrigger = triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule()
TriggerBuilder<SimpleTrigger> triggerBuilder = trigger.getTriggerBuilder(); .withIntervalInMilliseconds(intervalInMills).withRepeatCount(config.getMaxCount() - 1)).build();
int intervalInSeconds = fromTriggerPerDayToMillSecInterval(config.getTriggerPerDay()); scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger);
Trigger newTrigger = triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule() triggerMonitor.setTrigger(newTrigger);
.withIntervalInMilliseconds(intervalInSeconds).withRepeatCount(config.getMaxCount() - 1)) return config;
.build(); }
scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger); @RequestMapping("/resume")
triggerMonitor.setTrigger(newTrigger); @ResponseStatus(HttpStatus.NO_CONTENT)
return config; public void resume() throws SchedulerException {
} log.info("SCHEDULER - RESUME COMMAND");
scheduler.start();
@RequestMapping("/resume") }
@ResponseStatus(HttpStatus.NO_CONTENT)
public void resume() throws SchedulerException { @RequestMapping("/run")
scheduler.start(); @ResponseStatus(HttpStatus.NO_CONTENT)
} public void run() throws SchedulerException {
log.info("SCHEDULER - START COMMAND");
@RequestMapping("/run") scheduler.start();
@ResponseStatus(HttpStatus.NO_CONTENT) }
public void run() throws SchedulerException {
log.info("Starting scheduler..."); @ResponseStatus(HttpStatus.NO_CONTENT)
scheduler.start(); @RequestMapping("/stop")
} public void stop() throws SchedulerException {
log.info("SCHEDULER - STOP COMMAND");
@ResponseStatus(HttpStatus.NO_CONTENT) scheduler.shutdown(true);
@RequestMapping("/stop") }
public void stop() throws SchedulerException {
log.info("Stopping scheduler..."); private long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) {
scheduler.shutdown(true); return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills);
} }
@SuppressWarnings("unused") private int fromTriggerPerDayToMillsInterval(long triggerPerDay) {
private long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) { return (int) Math.ceil(Long.valueOf(MILLS_IN_A_DAY) / triggerPerDay); // with ceil the triggerPerDay is a max value
return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills); }
}
@SuppressWarnings("unused")
private int fromTriggerPerDayToMillSecInterval(long triggerPerDay) { private int fromTriggerPerDayToSecInterval(long triggerPerDay) {
return (int) Math.ceil(Long.valueOf(MILLS_IN_A_DAY) / triggerPerDay); //with ceil the triggerPerDay is a max value return (int) Math.ceil(Long.valueOf(SEC_IN_A_DAY) / triggerPerDay);
} }
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.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
@Controller @Controller
@RequestMapping("/session") @RequestMapping("/session")
public class SessionController { public class SessionController {
private final Logger log = LoggerFactory.getLogger(SessionController.class); private final Logger log = LoggerFactory.getLogger(SessionController.class);
@RequestMapping("/invalidate") @RequestMapping("/invalidate")
@PreAuthorize("hasAuthority('ADMIN')") @PreAuthorize("hasAuthority('ADMIN')")
public String invalidateSession(HttpSession session) { @ResponseStatus(HttpStatus.NO_CONTENT)
session.invalidate(); public void invalidateSession(HttpSession session) {
log.info("Invalidated current session!"); session.invalidate();
return "redirect:/manager"; log.info("Invalidated current session!");
} }
@RequestMapping("/refresh") @RequestMapping("/refresh")
@PreAuthorize("hasAuthority('ADMIN')") @PreAuthorize("hasAuthority('ADMIN')")
public HttpEntity<Void> refreshSession(HttpSession session) { public HttpEntity<Void> refreshSession(HttpSession session) {
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
} }

View File

@@ -1,65 +1,72 @@
package it.fabioformosa.quartzmanager.controllers; package it.fabioformosa.quartzmanager.controllers;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController { public class UserController {
// @Autowired /**
// private UserService userService; * JWT Temporary disabled
*
* @author Fabio.Formosa
// @RequestMapping(method = POST, value = "/signup") *
// public ResponseEntity<?> addUser(@RequestBody UserRequest userRequest, */
// UriComponentsBuilder ucBuilder) {
// // @Autowired
// User existUser = this.userService.findByUsername(userRequest.getUsername()); // private UserService userService;
// if (existUser != null)
// throw new ResourceConflictException(userRequest.getId(), "Username already exists");
// User user = this.userService.save(userRequest); // @RequestMapping(method = POST, value = "/signup")
// HttpHeaders headers = new HttpHeaders(); // public ResponseEntity<?> addUser(@RequestBody UserRequest userRequest,
// headers.setLocation(ucBuilder.path("/api/user/{userId}").buildAndExpand(user.getId()).toUri()); // UriComponentsBuilder ucBuilder) {
// return new ResponseEntity<>(user, HttpStatus.CREATED); //
// } // User existUser = this.userService.findByUsername(userRequest.getUsername());
// // if (existUser != null)
// @RequestMapping(method = GET, value = "/user/all") // throw new ResourceConflictException(userRequest.getId(), "Username already exists");
// public List<User> loadAll() { // User user = this.userService.save(userRequest);
// return this.userService.findAll(); // 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/{userId}") // }
// public User loadById(@PathVariable Long userId) { //
// return this.userService.findById(userId); // @RequestMapping(method = GET, value = "/user/all")
// } // public List<User> loadAll() {
// // return this.userService.findAll();
// // }
// @RequestMapping(method = GET, value = "/user/reset-credentials") //
// public ResponseEntity<Map> resetCredentials() { // @RequestMapping(method = GET, value = "/user/{userId}")
// this.userService.resetCredentials(); // public User loadById(@PathVariable Long userId) {
// Map<String, String> result = new HashMap<>(); // return this.userService.findById(userId);
// result.put("result", "success"); // }
// return ResponseEntity.accepted().body(result); //
// } //
// @RequestMapping(method = GET, value = "/user/reset-credentials")
/* // public ResponseEntity<Map> resetCredentials() {
* We are not using userService.findByUsername here(we could), so it is good that we are making // this.userService.resetCredentials();
* sure that the user has role "ROLE_USER" to access this endpoint. // Map<String, String> result = new HashMap<>();
*/ // result.put("result", "success");
// @RequestMapping("/whoami") // return ResponseEntity.accepted().body(result);
// // @PreAuthorize("hasRole('USER')") // }
// public User user() {
// return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); /*
// } * 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("isAuthenticated()") // @RequestMapping("/whoami")
public Object user() { // // @PreAuthorize("hasRole('USER')")
return SecurityContextHolder.getContext().getAuthentication().getPrincipal(); // 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 class SchedulerConfigParam {
public long triggerPerDay; public long triggerPerDay;
public int maxCount; public int maxCount;
public int getMaxCount() { public SchedulerConfigParam() {
return maxCount; super();
} }
public long getTriggerPerDay() { public SchedulerConfigParam(long triggerPerDay, int maxCount) {
return triggerPerDay; super();
} this.triggerPerDay = triggerPerDay;
this.maxCount = maxCount;
}
public void setMaxCount(int maxCount) { public int getMaxCount() {
this.maxCount = maxCount; return maxCount;
} }
public void setTriggerPerDay(long triggerPerDay) { public long getTriggerPerDay() {
this.triggerPerDay = triggerPerDay; return triggerPerDay;
} }
@Override public void setMaxCount(int maxCount) {
public String toString() { this.maxCount = maxCount;
return "SchedulerConfigParam [triggerPerDay=" + triggerPerDay }
+ ", 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; package it.fabioformosa.quartzmanager.exceptions;
public class ResourceConflictException extends RuntimeException { public class ResourceConflictException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 1791564636123821405L; private static final long serialVersionUID = 1791564636123821405L;
private Long resourceId; private Long resourceId;
public ResourceConflictException(Long resourceId, String message) { public ResourceConflictException(Long resourceId, String message) {
super(message); super(message);
this.setResourceId(resourceId); setResourceId(resourceId);
} }
public Long getResourceId() { 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.aspects.ProgressUpdater;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord; 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 { 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 @Autowired
private SimpMessageSendingOperations messagingTemplate; private SimpMessageSendingOperations messagingTemplate;
@Resource @Resource
private ProgressUpdater progressUpdater; private ProgressUpdater progressUpdater;
/** /**
* *
* @param jobExecutionContext * @param jobExecutionContext
* @return final log * @return final log
*/ */
public abstract LogRecord doIt(JobExecutionContext jobExecutionContext); public abstract LogRecord doIt(JobExecutionContext jobExecutionContext);
@Override @Override
public final void execute(JobExecutionContext jobExecutionContext) { public final void execute(JobExecutionContext jobExecutionContext) {
try { try {
LogRecord logMsg = doIt(jobExecutionContext); LogRecord logMsg = doIt(jobExecutionContext);
logAndSend(logMsg); logAndSend(logMsg);
progressUpdater.update(); progressUpdater.update();
} catch (SchedulerException e) { } catch (SchedulerException e) {
log.error("Error updating progress " + e.getMessage()); log.error("Error updating progress " + e.getMessage());
} }
} }
public void logAndSend(LogRecord logRecord) { public void logAndSend(LogRecord logRecord) {
log.info(logRecord.getMessage()); log.info(logRecord.getMessage());
logRecord.setThreadName(Thread.currentThread().getName()); logRecord.setThreadName(Thread.currentThread().getName());
messagingTemplate.convertAndSend("/topic/logs", logRecord); 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; import java.util.Date;
/**
* Log record produced by a job at the end of each run
*
* @author Fabio.Formosa
*
*/
public class LogRecord { public class LogRecord {
public enum LogType { public enum LogType {
INFO, WARN, ERROR; INFO, WARN, ERROR;
} }
private Date date; private Date date;
private LogType type; private LogType type;
private String message; private String message;
private String threadName; private String threadName;
public LogRecord(LogType type, String msg) { public LogRecord(LogType type, String msg) {
super(); super();
this.type = type; this.type = type;
message = msg; message = msg;
date = new Date(); date = new Date();
} }
public Date getDate() { public Date getDate() {
return date; return date;
} }
public String getMessage() { public String getMessage() {
return message; return message;
} }
public String getThreadName() { public String getThreadName() {
return threadName; return threadName;
} }
public LogType getType() { public LogType getType() {
return type; return type;
} }
public void setDate(Date date) { public void setDate(Date date) {
this.date = date; this.date = date;
} }
public void setMessage(String msg) { public void setMessage(String msg) {
message = msg; message = msg;
} }
public void setThreadName(String threadName) { public void setThreadName(String threadName) {
this.threadName = threadName; this.threadName = threadName;
} }
public void setType(LogType type) { public void setType(LogType type) {
this.type = type; this.type = type;
} }
@Override @Override
public String toString() { public String toString() {
return "LogRecord [date=" + date + ", type=" + type + ", message=" + message + "]"; 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 org.quartz.JobExecutionContext;
import it.fabioformosa.quartzmanager.jobs.AbstractLoggingJob;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord; import it.fabioformosa.quartzmanager.jobs.entities.LogRecord;
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord.LogType; 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; package it.fabioformosa.quartzmanager.security;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UserDetailsService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureAlgorithm;
/**
* JWT Temporary disabled
//@Component *
public class TokenHelper { * @author Fabio.Formosa
*
@Value("${app.name}") */
private String APP_NAME;
//@Component
@Value("${jwt.secret}") public class TokenHelper {
private String SECRET;
@Value("${app.name}")
@Value("${jwt.expires_in}") private String APP_NAME;
private int EXPIRES_IN;
@Value("${jwt.secret}")
@Value("${jwt.header}") private String SECRET;
private String AUTH_HEADER;
@Value("${jwt.expires_in}")
@Value("${jwt.cookie}") private int EXPIRES_IN;
private String AUTH_COOKIE;
@Value("${jwt.header}")
@Autowired private String AUTH_HEADER;
UserDetailsService userDetailsService;
@Value("${jwt.cookie}")
private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512; private String AUTH_COOKIE;
public Boolean canTokenBeRefreshed(String token) { @Autowired
try { UserDetailsService userDetailsService;
final Date expirationDate = getClaimsFromToken(token).getExpiration();
String username = getUsernameFromToken(token); private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512;
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
return expirationDate.compareTo(generateCurrentDate()) > 0; public Boolean canTokenBeRefreshed(String token) {
} catch (Exception e) { try {
return false; final Date expirationDate = getClaimsFromToken(token).getExpiration();
} // String username = getUsernameFromToken(token);
} // UserDetails userDetails = userDetailsService.loadUserByUsername(username);
return expirationDate.compareTo(generateCurrentDate()) > 0;
public String generateToken(String username) { } catch (Exception e) {
return Jwts.builder() return false;
.setIssuer( APP_NAME ) }
.setSubject(username) }
.setIssuedAt(generateCurrentDate())
.setExpiration(generateExpirationDate()) public String generateToken(String username) {
.signWith( SIGNATURE_ALGORITHM, SECRET ) return Jwts.builder()
.compact(); .setIssuer( APP_NAME )
} .setSubject(username)
.setIssuedAt(generateCurrentDate())
/** .setExpiration(generateExpirationDate())
* Find a specific HTTP cookie in a request. .signWith( SIGNATURE_ALGORITHM, SECRET )
* .compact();
* @param request }
* The HTTP request object.
* @param name /**
* The cookie name to look for. * Find a specific HTTP cookie in a request.
* @return The cookie, or <code>null</code> if not found. *
*/ * @param request
public Cookie getCookieValueByName(HttpServletRequest request, String name) { * The HTTP request object.
if (request.getCookies() == null) * @param name
return null; * The cookie name to look for.
for (int i = 0; i < request.getCookies().length; i++) * @return The cookie, or <code>null</code> if not found.
if (request.getCookies()[i].getName().equals(name)) */
return request.getCookies()[i]; public Cookie getCookieValueByName(HttpServletRequest request, String name) {
return null; if (request.getCookies() == null)
} return null;
for (int i = 0; i < request.getCookies().length; i++)
public String getToken( HttpServletRequest request ) { if (request.getCookies()[i].getName().equals(name))
/** return request.getCookies()[i];
* Getting the token from Cookie store return null;
*/ }
Cookie authCookie = getCookieValueByName( request, AUTH_COOKIE );
if ( authCookie != null ) public String getToken( HttpServletRequest request ) {
return authCookie.getValue(); /**
/** * Getting the token from Cookie store
* Getting the token from Authentication header */
* e.g Bearer your_token Cookie authCookie = getCookieValueByName( request, AUTH_COOKIE );
*/ if ( authCookie != null )
String authHeader = request.getHeader(AUTH_HEADER); return authCookie.getValue();
if ( authHeader != null && authHeader.startsWith("Bearer ")) /**
return authHeader.substring(7); * Getting the token from Authentication header
* e.g Bearer your_token
return null; */
} String authHeader = request.getHeader(AUTH_HEADER);
if ( authHeader != null && authHeader.startsWith("Bearer "))
public String getUsernameFromToken(String token) { return authHeader.substring(7);
String username;
try { return null;
final Claims claims = getClaimsFromToken(token); }
username = claims.getSubject();
} catch (Exception e) { public String getUsernameFromToken(String token) {
username = null; String username;
} try {
return username; final Claims claims = getClaimsFromToken(token);
} username = claims.getSubject();
} catch (Exception e) {
public String refreshToken(String token) { username = null;
String refreshedToken; }
try { return username;
final Claims claims = getClaimsFromToken(token); }
claims.setIssuedAt(generateCurrentDate());
refreshedToken = generateToken(claims); public String refreshToken(String token) {
} catch (Exception e) { String refreshedToken;
refreshedToken = null; try {
} final Claims claims = getClaimsFromToken(token);
return refreshedToken; claims.setIssuedAt(generateCurrentDate());
} refreshedToken = generateToken(claims);
} catch (Exception e) {
private Date generateCurrentDate() { refreshedToken = null;
return new Date(getCurrentTimeMillis()); }
} return refreshedToken;
}
private Date generateExpirationDate() {
private Date generateCurrentDate() {
return new Date(getCurrentTimeMillis() + this.EXPIRES_IN * 1000); return new Date(getCurrentTimeMillis());
} }
private Claims getClaimsFromToken(String token) { private Date generateExpirationDate() {
Claims claims;
try { return new Date(getCurrentTimeMillis() + EXPIRES_IN * 1000);
claims = Jwts.parser() }
.setSigningKey(this.SECRET)
.parseClaimsJws(token) private Claims getClaimsFromToken(String token) {
.getBody(); Claims claims;
} catch (Exception e) { try {
claims = null; claims = Jwts.parser()
} .setSigningKey(SECRET)
return claims; .parseClaimsJws(token)
} .getBody();
} catch (Exception e) {
private long getCurrentTimeMillis() { claims = null;
return DateTime.now().getMillis(); }
} return claims;
}
String generateToken(Map<String, Object> claims) {
return Jwts.builder() private long getCurrentTimeMillis() {
.setClaims(claims) return DateTime.now().getMillis();
.setExpiration(generateExpirationDate()) }
.signWith( SIGNATURE_ALGORITHM, SECRET )
.compact(); 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; package it.fabioformosa.quartzmanager.security.model;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity /**
@Table(name="Authority") * Temporary enabled only inMemoryAuthentication
public class Authority implements GrantedAuthority { *
* @author Fabio.Formosa
@Id *
@Column(name="id") */
@GeneratedValue(strategy = GenerationType.IDENTITY) @Entity
Long id; @Table(name="Authority")
public class Authority implements GrantedAuthority {
@Column(name="name")
String name; @Id
@Column(name="id")
@Override @GeneratedValue(strategy = GenerationType.IDENTITY)
public String getAuthority() { Long id;
return name;
} @Column(name="name")
String name;
@JsonIgnore
public Long getId() { @Override
return id; public String getAuthority() {
} return name;
}
@JsonIgnore
public String getName() { @JsonIgnore
return name; public Long getId() {
} return id;
}
public void setId(Long id) {
this.id = id; @JsonIgnore
} public String getName() {
return name;
public void setName(String name) { }
this.name = 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; package it.fabioformosa.quartzmanager.security.model;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import javax.persistence.CascadeType; import javax.persistence.CascadeType;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.FetchType; import javax.persistence.FetchType;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinTable; import javax.persistence.JoinTable;
import javax.persistence.ManyToMany; import javax.persistence.ManyToMany;
import javax.persistence.Table; import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity /**
@Table(name = "USER") * Temporary enabled only inMemoryAuthentication
public class User implements UserDetails, Serializable { *
@Id * @author Fabio.Formosa
@Column(name = "id") *
@GeneratedValue(strategy = GenerationType.IDENTITY) */
private Long id; @Entity
@Table(name = "USER")
@Column(name = "username") public class User implements UserDetails, Serializable {
private String username; @Id
@Column(name = "id")
@JsonIgnore @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "password") private Long id;
private String password;
@Column(name = "username")
@Column(name = "firstname") private String username;
private String firstname;
@JsonIgnore
@Column(name = "lastname") @Column(name = "password")
private String lastname; private String password;
@Column(name = "firstname")
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private String firstname;
@JoinTable(name = "user_authority",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), @Column(name = "lastname")
inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id")) private String lastname;
private List<Authority> authorities;
@Override @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public Collection<? extends GrantedAuthority> getAuthorities() { @JoinTable(name = "user_authority",
return this.authorities; joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
} inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id"))
private List<Authority> authorities;
public String getFirstname() {
return firstname; @Override
} public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
public Long getId() { }
return id;
} public String getFirstname() {
return firstname;
public String getLastname() { }
return lastname;
} public Long getId() {
return id;
@Override }
public String getPassword() {
return password; public String getLastname() {
} return lastname;
}
@Override
public String getUsername() { @Override
return username; public String getPassword() {
} return password;
}
// We can add the below fields in the users table.
// For now, they are hardcoded. @Override
@JsonIgnore public String getUsername() {
@Override return username;
public boolean isAccountNonExpired() { }
return true;
} // We can add the below fields in the users table.
// For now, they are hardcoded.
@JsonIgnore @JsonIgnore
@Override @Override
public boolean isAccountNonLocked() { public boolean isAccountNonExpired() {
return true; return true;
} }
@JsonIgnore @JsonIgnore
@Override @Override
public boolean isCredentialsNonExpired() { public boolean isAccountNonLocked() {
return true; return true;
} }
@JsonIgnore @JsonIgnore
@Override @Override
public boolean isEnabled() { public boolean isCredentialsNonExpired() {
return true; return true;
} }
public void setAuthorities(List<Authority> authorities) { @JsonIgnore
this.authorities = authorities; @Override
} public boolean isEnabled() {
return true;
public void setFirstname(String firstname) { }
this.firstname = firstname;
} public void setAuthorities(List<Authority> authorities) {
this.authorities = authorities;
public void setId(Long id) { }
this.id = id;
} public void setFirstname(String firstname) {
this.firstname = firstname;
public void setLastname(String lastname) { }
this.lastname = lastname; public void setId(Long id) {
} this.id = id;
}
public void setPassword(String password) {
this.password = password; public void setLastname(String lastname) {
}
this.lastname = lastname;
public void setUsername(String username) { }
this.username = username;
} 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"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout"> <layout class="ch.qos.logback.classic.PatternLayout">
<Pattern> <Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n %d{yyyy-MM-dd HH:mm:ss.SSS} [%.7thread] %-5level [%-40.40logger{49}:%-3L] --- %m%n
</Pattern> </Pattern>
</layout> </layout>
</appender> </appender>
<logger name="it.fabioformosa" level="DEBUG" additivity="false"> <logger name="it.fabioformosa" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</logger> </logger>
<logger name="org.springframework" level="WARN" additivity="false"> <logger name="org.springframework" level="WARN" additivity="false">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</logger> </logger>
<root level="WARN"> <root level="WARN">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>