mirror of
https://github.com/fabioformosa/quartz-manager.git
synced 2025-12-27 20:53:17 +09:00
@@ -11,7 +11,7 @@
|
||||
</button>
|
||||
<button
|
||||
class="greeting-button"
|
||||
*ngIf="hasSignedIn()"
|
||||
*ngIf="hasSignedIn() && !noAuthenticationRequired()"
|
||||
mat-button mat-ripple
|
||||
[matMenuTriggerFor]="accountMenu">
|
||||
<span>Hi, {{userName()}}</span>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {
|
||||
UserService,
|
||||
AuthService
|
||||
AuthService,
|
||||
NO_AUTH
|
||||
} from '../../services';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@@ -31,6 +32,9 @@ export class HeaderComponent implements OnInit {
|
||||
return !!this.userService.currentUser;
|
||||
}
|
||||
|
||||
noAuthenticationRequired = () => this.hasSignedIn() && this.userService.currentUser === NO_AUTH;
|
||||
|
||||
|
||||
userName() {
|
||||
const user = this.userService.currentUser;
|
||||
return user.username;
|
||||
|
||||
@@ -1,14 +1,55 @@
|
||||
import { TestBed, async, inject } from '@angular/core/testing';
|
||||
import { Router } from '@angular/router';
|
||||
import { UserService } from '../services';
|
||||
import { NO_AUTH, UserService } from '../services';
|
||||
import { AdminGuard } from './admin.guard';
|
||||
import { MockUserService } from '../services/mocks';
|
||||
import {jest} from '@jest/globals'
|
||||
|
||||
export class RouterStub {
|
||||
navigate(commands?: any[], extras?: any) {}
|
||||
}
|
||||
|
||||
describe('AdminGuard', () => {
|
||||
const RouterSpy = jest.spyOn(RouterStub.prototype, 'navigate');
|
||||
|
||||
const MockUserServiceNoAuth = jest.fn(() => ({currentUser: NO_AUTH}));
|
||||
const MockUserService = jest.fn(() => ({
|
||||
currentUser: {
|
||||
authorities: ['ROLE_ADMIN']
|
||||
}
|
||||
}));
|
||||
const MockUserServiceForbidden = jest.fn(() => ({
|
||||
currentUser: {
|
||||
authorities: ['ROLE_GUEST']
|
||||
}
|
||||
}));
|
||||
|
||||
describe('AdminGuard NoAuth', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
AdminGuard,
|
||||
{
|
||||
provide: Router,
|
||||
useClass: RouterStub
|
||||
},
|
||||
{
|
||||
provide: UserService,
|
||||
useClass: MockUserServiceNoAuth
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('should run', inject([AdminGuard], (guard: AdminGuard) => {
|
||||
expect(guard).toBeTruthy();
|
||||
}));
|
||||
|
||||
it('returns true if user is NO_AUTH',inject([AdminGuard], (guard: AdminGuard) => {
|
||||
expect(guard.canActivate(null, null)).toBeTruthy();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('AdminGuard activates the route', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
@@ -25,7 +66,40 @@ describe('AdminGuard', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should ...', inject([AdminGuard], (guard: AdminGuard) => {
|
||||
it('should run', inject([AdminGuard], (guard: AdminGuard) => {
|
||||
expect(guard).toBeTruthy();
|
||||
}));
|
||||
|
||||
it('returns true if user has admin role',inject([AdminGuard], (guard: AdminGuard) => {
|
||||
expect(guard.canActivate(null, null)).toBeTruthy();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('AdminGuard redirects to 403', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
AdminGuard,
|
||||
{
|
||||
provide: Router,
|
||||
useClass: RouterStub
|
||||
},
|
||||
{
|
||||
provide: UserService,
|
||||
useClass: MockUserServiceForbidden
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('should run', inject([AdminGuard], (guard: AdminGuard) => {
|
||||
expect(guard).toBeTruthy();
|
||||
}));
|
||||
|
||||
it('returns false if user is not authorized',inject([AdminGuard], (guard: AdminGuard) => {
|
||||
expect(guard.canActivate(null, null)).toBeFalsy();
|
||||
expect(RouterSpy).toHaveBeenCalledTimes(1);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
@@ -9,6 +9,8 @@ export class AdminGuard implements CanActivate {
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
||||
if (this.userService.currentUser) {
|
||||
if(this.userService.currentUser === 'NO_AUTH')
|
||||
return true;
|
||||
if (JSON.stringify(this.userService.currentUser.authorities).search('ROLE_ADMIN') !== -1)
|
||||
return true;
|
||||
else {
|
||||
|
||||
83
quartz-manager-frontend/src/app/services/api.service.spec.ts
Normal file
83
quartz-manager-frontend/src/app/services/api.service.spec.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { TestBed } from "@angular/core/testing";
|
||||
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||
import { ApiService } from './api.service';
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Router} from '@angular/router';
|
||||
import {jest} from '@jest/globals'
|
||||
|
||||
class Data{
|
||||
name: string
|
||||
}
|
||||
|
||||
class HttpResponseMock {
|
||||
constructor(
|
||||
public body: unknown,
|
||||
public opts?: {
|
||||
headers?:
|
||||
| HttpHeaders
|
||||
| {
|
||||
[name: string]: string | string[];
|
||||
};
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
}
|
||||
) {}
|
||||
}
|
||||
|
||||
const routerSpy = jest.spyOn(Router.prototype, 'navigateByUrl');
|
||||
|
||||
describe('ApiServiceTest', () => {
|
||||
|
||||
let apiService: ApiService;
|
||||
let httpClient: HttpClient;
|
||||
let httpTestingController: HttpTestingController;
|
||||
|
||||
const SAMPLE_URL = '/sample-url';
|
||||
const URL_401 = '/url-response-401';
|
||||
const testData: Data = {name: 'Test Data'};
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule],
|
||||
providers: [ApiService, {provide: Router, useValue: routerSpy}]
|
||||
});
|
||||
apiService = TestBed.inject(ApiService);
|
||||
|
||||
httpClient = TestBed.inject(HttpClient);
|
||||
httpTestingController = TestBed.inject(HttpTestingController);
|
||||
});
|
||||
|
||||
it('should be created', (): void => {
|
||||
expect(apiService).toBeTruthy();
|
||||
});
|
||||
|
||||
it('can test HttpClient.get', (): void => {
|
||||
|
||||
apiService.get(SAMPLE_URL).subscribe((res: Data) => {
|
||||
expect(res).toEqual(testData);
|
||||
});
|
||||
|
||||
const req = httpTestingController.expectOne(SAMPLE_URL)
|
||||
expect(req.request.method).toEqual('GET');
|
||||
req.flush(new HttpResponseMock(testData));
|
||||
httpTestingController.verify();
|
||||
});
|
||||
|
||||
it('doesn\'t do anything if 401 is received', (): void => {
|
||||
|
||||
apiService.get(URL_401).subscribe((res: Data) => {
|
||||
expect(false);
|
||||
}, (error) =>
|
||||
{
|
||||
expect(error.status).toBe(401);
|
||||
expect(routerSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
const req = httpTestingController.expectOne(URL_401)
|
||||
expect(req.request.method).toEqual('GET');
|
||||
req.flush(null, {status: 401, statusText: 'unauthenticated'});
|
||||
httpTestingController.verify();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
import { HttpClient, HttpHeaders, HttpResponse, HttpRequest, HttpEventType, HttpParams } from '@angular/common/http';
|
||||
import { Router} from '@angular/router';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { catchError, map, filter, tap } from 'rxjs/operators'
|
||||
@@ -35,7 +36,7 @@ export class ApiService {
|
||||
|
||||
private jwtToken: string;
|
||||
|
||||
constructor( private http: HttpClient) { }
|
||||
constructor( private http: HttpClient, private router: Router) { }
|
||||
|
||||
setToken(token: string) {
|
||||
this.jwtToken = token;
|
||||
@@ -98,7 +99,7 @@ export class ApiService {
|
||||
// Display error if logged in, otherwise redirect to IDP
|
||||
private checkError(error: any): any {
|
||||
if (error && error.status === 401) {
|
||||
// this.redirectIfUnauth(error);
|
||||
this.router.navigate(['/login']);
|
||||
} else {
|
||||
// this.displayError(error);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@ import { HttpHeaders, HttpResponse } from '@angular/common/http';
|
||||
import { ApiService } from './api.service';
|
||||
import { UserService } from './user.service';
|
||||
import { ConfigService } from './config.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
@Injectable()
|
||||
export class ConfigService {
|
||||
|
||||
@@ -4,6 +4,8 @@ import { ConfigService } from './config.service';
|
||||
|
||||
import { map } from 'rxjs/operators'
|
||||
|
||||
export const NO_AUTH: string = 'NO_AUTH'
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
|
||||
@@ -34,6 +36,7 @@ export class UserService {
|
||||
this.currentUser = user;
|
||||
}, err => {
|
||||
//not logged
|
||||
console.log(`error retrieving current user due to ` + err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -25,52 +25,52 @@ import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor;
|
||||
@Component
|
||||
public class WebSocketProgressNotifier implements ProgressNotifier {
|
||||
|
||||
@Autowired
|
||||
private SimpMessageSendingOperations messagingTemplate;
|
||||
@Autowired
|
||||
private SimpMessageSendingOperations messagingTemplate;
|
||||
|
||||
@Resource
|
||||
private Scheduler scheduler;
|
||||
@Resource
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Resource
|
||||
private TriggerMonitor triggerMonitor;
|
||||
@Resource
|
||||
private TriggerMonitor triggerMonitor;
|
||||
|
||||
//@AfterReturning("execution(* logAndSend(..))")
|
||||
// @Override
|
||||
// public void updateProgress(JoinPoint joinPoint) {
|
||||
// log.info("PROGRESS UPDATE!!!");
|
||||
// }
|
||||
//@AfterReturning("execution(* logAndSend(..))")
|
||||
// @Override
|
||||
// public void updateProgress(JoinPoint joinPoint) {
|
||||
// log.info("PROGRESS UPDATE!!!");
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void send() throws SchedulerException {
|
||||
TriggerStatus currTriggerStatus = new TriggerStatus();
|
||||
@Override
|
||||
public void send() throws SchedulerException {
|
||||
TriggerStatus currTriggerStatus = new TriggerStatus();
|
||||
|
||||
Trigger trigger = scheduler.getTrigger(triggerMonitor.getTrigger().getKey());
|
||||
currTriggerStatus.setFinalFireTime(trigger.getFinalFireTime());
|
||||
currTriggerStatus.setNextFireTime(trigger.getNextFireTime());
|
||||
currTriggerStatus.setPreviousFireTime(trigger.getPreviousFireTime());
|
||||
Trigger trigger = scheduler.getTrigger(triggerMonitor.getTrigger().getKey());
|
||||
currTriggerStatus.setFinalFireTime(trigger.getFinalFireTime());
|
||||
currTriggerStatus.setNextFireTime(trigger.getNextFireTime());
|
||||
currTriggerStatus.setPreviousFireTime(trigger.getPreviousFireTime());
|
||||
|
||||
int timesTriggered = 0;
|
||||
int repeatCount = 0;
|
||||
int timesTriggered = 0;
|
||||
int repeatCount = 0;
|
||||
|
||||
if (trigger instanceof SimpleTrigger) {
|
||||
SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
|
||||
timesTriggered = simpleTrigger.getTimesTriggered();
|
||||
repeatCount = simpleTrigger.getRepeatCount();
|
||||
} else if (trigger instanceof DailyTimeIntervalTrigger) {
|
||||
DailyTimeIntervalTrigger dailyTrigger = (DailyTimeIntervalTrigger) trigger;
|
||||
timesTriggered = dailyTrigger.getTimesTriggered();
|
||||
repeatCount = dailyTrigger.getRepeatCount();
|
||||
}
|
||||
if (trigger instanceof SimpleTrigger) {
|
||||
SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
|
||||
timesTriggered = simpleTrigger.getTimesTriggered();
|
||||
repeatCount = simpleTrigger.getRepeatCount();
|
||||
} else if (trigger instanceof DailyTimeIntervalTrigger) {
|
||||
DailyTimeIntervalTrigger dailyTrigger = (DailyTimeIntervalTrigger) trigger;
|
||||
timesTriggered = dailyTrigger.getTimesTriggered();
|
||||
repeatCount = dailyTrigger.getRepeatCount();
|
||||
}
|
||||
|
||||
Trigger jobTrigger = triggerMonitor.getTrigger();
|
||||
if (jobTrigger != null && jobTrigger.getJobKey() != null) {
|
||||
currTriggerStatus.setJobKey(jobTrigger.getJobKey().getName());
|
||||
currTriggerStatus.setJobClass(jobTrigger.getClass().getSimpleName());
|
||||
currTriggerStatus.setTimesTriggered(timesTriggered);
|
||||
currTriggerStatus.setRepeatCount(repeatCount + 1);
|
||||
}
|
||||
Trigger jobTrigger = triggerMonitor.getTrigger();
|
||||
if (jobTrigger != null && jobTrigger.getJobKey() != null) {
|
||||
currTriggerStatus.setJobKey(jobTrigger.getJobKey().getName());
|
||||
currTriggerStatus.setJobClass(jobTrigger.getClass().getSimpleName());
|
||||
currTriggerStatus.setTimesTriggered(timesTriggered);
|
||||
currTriggerStatus.setRepeatCount(repeatCount + 1);
|
||||
}
|
||||
|
||||
messagingTemplate.convertAndSend("/topic/progress", currTriggerStatus);
|
||||
}
|
||||
messagingTemplate.convertAndSend("/topic/progress", currTriggerStatus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.springframework.beans.factory.config.PropertiesFactoryBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
|
||||
@@ -24,75 +25,76 @@ import it.fabioformosa.quartzmanager.scheduler.AutowiringSpringBeanJobFactory;
|
||||
import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor;
|
||||
import it.fabioformosa.quartzmanager.scheduler.TriggerMonitorImpl;
|
||||
|
||||
@ComponentScan(basePackages = {"it.fabioformosa.quartzmanager.controllers"})
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "quartz.enabled")
|
||||
public class SchedulerConfig {
|
||||
|
||||
private static JobDetailFactoryBean createJobDetail(Class<? extends Job> jobClass) {
|
||||
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
|
||||
factoryBean.setJobClass(jobClass);
|
||||
factoryBean.setDurability(false);
|
||||
return factoryBean;
|
||||
}
|
||||
private static JobDetailFactoryBean createJobDetail(Class<? extends Job> jobClass) {
|
||||
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
|
||||
factoryBean.setJobClass(jobClass);
|
||||
factoryBean.setDurability(false);
|
||||
return factoryBean;
|
||||
}
|
||||
|
||||
private static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs,
|
||||
int repeatCount) {
|
||||
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
|
||||
factoryBean.setJobDetail(jobDetail);
|
||||
factoryBean.setStartDelay(3000L);
|
||||
factoryBean.setRepeatInterval(pollFrequencyMs);
|
||||
factoryBean.setRepeatCount(repeatCount);
|
||||
factoryBean
|
||||
.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT);// in case of misfire, ignore all missed triggers and continue
|
||||
return factoryBean;
|
||||
}
|
||||
private static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs,
|
||||
int repeatCount) {
|
||||
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
|
||||
factoryBean.setJobDetail(jobDetail);
|
||||
factoryBean.setStartDelay(3000L);
|
||||
factoryBean.setRepeatInterval(pollFrequencyMs);
|
||||
factoryBean.setRepeatCount(repeatCount);
|
||||
factoryBean
|
||||
.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT);// in case of misfire, ignore all missed triggers and continue
|
||||
return factoryBean;
|
||||
}
|
||||
|
||||
@Value("${quartz-manager.jobClass}")
|
||||
private String jobClassname;
|
||||
@Value("${quartz-manager.jobClass}")
|
||||
private String jobClassname;
|
||||
|
||||
@Bean(name = "triggerMonitor")
|
||||
public TriggerMonitor createTriggerMonitor(@Qualifier("jobTrigger") Trigger trigger) {
|
||||
TriggerMonitor triggerMonitor = new TriggerMonitorImpl();
|
||||
triggerMonitor.setTrigger(trigger);
|
||||
return triggerMonitor;
|
||||
}
|
||||
@Bean(name = "triggerMonitor")
|
||||
public TriggerMonitor createTriggerMonitor(@Qualifier("jobTrigger") Trigger trigger) {
|
||||
TriggerMonitor triggerMonitor = new TriggerMonitorImpl();
|
||||
triggerMonitor.setTrigger(trigger);
|
||||
return triggerMonitor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unchecked")
|
||||
public JobDetailFactoryBean jobDetail() throws ClassNotFoundException {
|
||||
Class<? extends Job> JobClass = (Class<? extends Job>) Class.forName(jobClassname);
|
||||
return createJobDetail(JobClass);
|
||||
}
|
||||
@Bean
|
||||
@SuppressWarnings("unchecked")
|
||||
public JobDetailFactoryBean jobDetail() throws ClassNotFoundException {
|
||||
Class<? extends Job> JobClass = (Class<? extends Job>) Class.forName(jobClassname);
|
||||
return createJobDetail(JobClass);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JobFactory jobFactory(ApplicationContext applicationContext) {
|
||||
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
|
||||
jobFactory.setApplicationContext(applicationContext);
|
||||
return jobFactory;
|
||||
}
|
||||
@Bean
|
||||
public JobFactory jobFactory(ApplicationContext applicationContext) {
|
||||
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
|
||||
jobFactory.setApplicationContext(applicationContext);
|
||||
return jobFactory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Properties quartzProperties() throws IOException {
|
||||
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
|
||||
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
|
||||
propertiesFactoryBean.afterPropertiesSet();
|
||||
return propertiesFactoryBean.getObject();
|
||||
}
|
||||
@Bean
|
||||
public Properties quartzProperties() throws IOException {
|
||||
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
|
||||
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
|
||||
propertiesFactoryBean.afterPropertiesSet();
|
||||
return propertiesFactoryBean.getObject();
|
||||
}
|
||||
|
||||
@Bean(name = "jobTrigger")
|
||||
public SimpleTriggerFactoryBean sampleJobTrigger(@Qualifier("jobDetail") JobDetail jobDetail,
|
||||
@Value("${job.frequency}") long frequency, @Value("${job.repeatCount}") int repeatCount) {
|
||||
return createTrigger(jobDetail, frequency, repeatCount);
|
||||
}
|
||||
@Bean(name = "jobTrigger")
|
||||
public SimpleTriggerFactoryBean sampleJobTrigger(@Qualifier("jobDetail") JobDetail jobDetail,
|
||||
@Value("${job.frequency}") long frequency, @Value("${job.repeatCount}") int repeatCount) {
|
||||
return createTrigger(jobDetail, frequency, repeatCount);
|
||||
}
|
||||
|
||||
@Bean(name = "scheduler")
|
||||
public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory,
|
||||
@Qualifier("jobTrigger") Trigger sampleJobTrigger) throws IOException {
|
||||
SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
factory.setJobFactory(jobFactory);
|
||||
factory.setQuartzProperties(quartzProperties());
|
||||
factory.setTriggers(sampleJobTrigger);
|
||||
factory.setAutoStartup(false);
|
||||
return factory;
|
||||
}
|
||||
@Bean(name = "scheduler")
|
||||
public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory,
|
||||
@Qualifier("jobTrigger") Trigger sampleJobTrigger) throws IOException {
|
||||
SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
factory.setJobFactory(jobFactory);
|
||||
factory.setQuartzProperties(quartzProperties());
|
||||
factory.setTriggers(sampleJobTrigger);
|
||||
factory.setAutoStartup(false);
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package it.fabioformosa.quartzmanager.configuration;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
|
||||
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
|
||||
@@ -7,19 +8,20 @@ import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBr
|
||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = {"it.fabioformosa.quartzmanager.aspects"})
|
||||
@EnableWebSocketMessageBroker
|
||||
public class WebsocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry config) {
|
||||
config.enableSimpleBroker("/topic");
|
||||
config.setApplicationDestinationPrefixes("/job");
|
||||
}
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry config) {
|
||||
config.enableSimpleBroker("/topic");
|
||||
config.setApplicationDestinationPrefixes("/job");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
registry.addEndpoint("/logs").setAllowedOrigins("/**").withSockJS();
|
||||
registry.addEndpoint("/progress").setAllowedOrigins("/**").withSockJS();
|
||||
}
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
registry.addEndpoint("/quartz-manager/logs").setAllowedOrigins("/**").withSockJS();
|
||||
registry.addEndpoint("/quartz-manager/progress").setAllowedOrigins("/**").withSockJS();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,119 +36,119 @@ import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor;
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/scheduler")
|
||||
@RequestMapping("/quartz-manager/scheduler")
|
||||
@Api(value = "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 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);
|
||||
private final Logger log = LoggerFactory.getLogger(SchedulerController.class);
|
||||
|
||||
@Resource
|
||||
private Scheduler scheduler;
|
||||
@Resource
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Resource
|
||||
private TriggerMonitor triggerMonitor;
|
||||
@Resource
|
||||
private TriggerMonitor triggerMonitor;
|
||||
|
||||
@GetMapping("/config")
|
||||
public SchedulerConfigParam getConfig() {
|
||||
log.debug("SCHEDULER - GET CONFIG params");
|
||||
SimpleTrigger simpleTrigger = (SimpleTrigger) triggerMonitor.getTrigger();
|
||||
private long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) {
|
||||
return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills);
|
||||
}
|
||||
|
||||
int maxCount = simpleTrigger.getRepeatCount() + 1;
|
||||
long triggersPerDay = fromMillsIntervalToTriggerPerDay(simpleTrigger.getRepeatInterval());
|
||||
private int fromTriggerPerDayToMillsInterval(long triggerPerDay) {
|
||||
return (int) Math.ceil(Long.valueOf(MILLS_IN_A_DAY) / triggerPerDay); // with ceil the triggerPerDay is a max value
|
||||
}
|
||||
|
||||
return new SchedulerConfigParam(triggersPerDay, maxCount);
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
private int fromTriggerPerDayToSecInterval(long triggerPerDay) {
|
||||
return (int) Math.ceil(Long.valueOf(SEC_IN_A_DAY) / triggerPerDay);
|
||||
}
|
||||
|
||||
@GetMapping("/progress")
|
||||
public TriggerStatus getProgressInfo() throws SchedulerException {
|
||||
log.trace("SCHEDULER - GET PROGRESS INFO");
|
||||
TriggerStatus progress = new TriggerStatus();
|
||||
@GetMapping("/config")
|
||||
public SchedulerConfigParam getConfig() {
|
||||
log.debug("SCHEDULER - GET CONFIG params");
|
||||
SimpleTrigger simpleTrigger = (SimpleTrigger) triggerMonitor.getTrigger();
|
||||
|
||||
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());
|
||||
}
|
||||
int maxCount = simpleTrigger.getRepeatCount() + 1;
|
||||
long triggersPerDay = fromMillsIntervalToTriggerPerDay(simpleTrigger.getRepeatInterval());
|
||||
|
||||
return progress;
|
||||
}
|
||||
return new SchedulerConfigParam(triggersPerDay, maxCount);
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
@GetMapping("/progress")
|
||||
public TriggerStatus getProgressInfo() throws SchedulerException {
|
||||
log.trace("SCHEDULER - GET PROGRESS INFO");
|
||||
TriggerStatus progress = new TriggerStatus();
|
||||
|
||||
@GetMapping("/pause")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public void pause() throws SchedulerException {
|
||||
log.info("SCHEDULER - PAUSE COMMAND");
|
||||
scheduler.standby();
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
@PostMapping("/config")
|
||||
public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) throws SchedulerException {
|
||||
log.info("SCHEDULER - NEW CONFIG {}", config);
|
||||
SimpleTrigger trigger = (SimpleTrigger) triggerMonitor.getTrigger();
|
||||
return progress;
|
||||
}
|
||||
|
||||
TriggerBuilder<SimpleTrigger> triggerBuilder = trigger.getTriggerBuilder();
|
||||
@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());
|
||||
}
|
||||
|
||||
int intervalInMills = fromTriggerPerDayToMillsInterval(config.getTriggerPerDay());
|
||||
Trigger newTrigger = triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule()
|
||||
.withIntervalInMilliseconds(intervalInMills).withRepeatCount(config.getMaxCount() - 1)).build();
|
||||
@GetMapping("/pause")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public void pause() throws SchedulerException {
|
||||
log.info("SCHEDULER - PAUSE COMMAND");
|
||||
scheduler.standby();
|
||||
}
|
||||
|
||||
scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger);
|
||||
triggerMonitor.setTrigger(newTrigger);
|
||||
return config;
|
||||
}
|
||||
@PostMapping("/config")
|
||||
public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) throws SchedulerException {
|
||||
log.info("SCHEDULER - NEW CONFIG {}", config);
|
||||
SimpleTrigger trigger = (SimpleTrigger) triggerMonitor.getTrigger();
|
||||
|
||||
@GetMapping("/resume")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public void resume() throws SchedulerException {
|
||||
log.info("SCHEDULER - RESUME COMMAND");
|
||||
scheduler.start();
|
||||
}
|
||||
TriggerBuilder<SimpleTrigger> triggerBuilder = trigger.getTriggerBuilder();
|
||||
|
||||
@GetMapping("/run")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public void run() throws SchedulerException {
|
||||
log.info("SCHEDULER - START COMMAND");
|
||||
scheduler.start();
|
||||
}
|
||||
int intervalInMills = fromTriggerPerDayToMillsInterval(config.getTriggerPerDay());
|
||||
Trigger newTrigger = triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule()
|
||||
.withIntervalInMilliseconds(intervalInMills).withRepeatCount(config.getMaxCount() - 1)).build();
|
||||
|
||||
@GetMapping("/stop")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public void stop() throws SchedulerException {
|
||||
log.info("SCHEDULER - STOP COMMAND");
|
||||
scheduler.shutdown(true);
|
||||
}
|
||||
scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger);
|
||||
triggerMonitor.setTrigger(newTrigger);
|
||||
return config;
|
||||
}
|
||||
|
||||
private long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) {
|
||||
return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills);
|
||||
}
|
||||
@GetMapping("/resume")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public void resume() throws SchedulerException {
|
||||
log.info("SCHEDULER - RESUME COMMAND");
|
||||
scheduler.start();
|
||||
}
|
||||
|
||||
private int fromTriggerPerDayToMillsInterval(long triggerPerDay) {
|
||||
return (int) Math.ceil(Long.valueOf(MILLS_IN_A_DAY) / triggerPerDay); // with ceil the triggerPerDay is a max value
|
||||
}
|
||||
@GetMapping("/run")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public void run() throws SchedulerException {
|
||||
log.info("SCHEDULER - START COMMAND");
|
||||
scheduler.start();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private int fromTriggerPerDayToSecInterval(long triggerPerDay) {
|
||||
return (int) Math.ceil(Long.valueOf(SEC_IN_A_DAY) / triggerPerDay);
|
||||
}
|
||||
@GetMapping("/stop")
|
||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||
public void stop() throws SchedulerException {
|
||||
log.info("SCHEDULER - STOP COMMAND");
|
||||
scheduler.shutdown(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import org.springframework.stereotype.Controller;
|
||||
@Controller
|
||||
public class WebsocketController {
|
||||
|
||||
@MessageMapping({ "/logs", "/progress" })
|
||||
@SendTo("/topic/logs")
|
||||
public String subscribe() throws Exception {
|
||||
return "subscribed";
|
||||
}
|
||||
@MessageMapping({ "/quartz-manager/logs", "/quartz-manager/progress" })
|
||||
@SendTo("/topic/logs")
|
||||
public String subscribe() throws Exception {
|
||||
return "subscribed";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
it.fabioformosa.quartzmanager.configuration.SchedulerConfig,\
|
||||
it.fabioformosa.quartzmanager.configuration.SwaggerConfig,\
|
||||
it.fabioformosa.quartzmanager.configuration.WebsocketConfig
|
||||
@@ -37,9 +37,9 @@ import it.fabioformosa.quartzmanager.security.helpers.impl.JwtAuthenticationSucc
|
||||
import it.fabioformosa.quartzmanager.security.helpers.impl.JwtAuthenticationSuccessHandlerImpl;
|
||||
import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenAuthenticationFilter;
|
||||
import it.fabioformosa.quartzmanager.security.helpers.impl.JwtTokenHelper;
|
||||
import it.fabioformosa.quartzmanager.security.helpers.impl.QuartzManagerHttpSecurity;
|
||||
import it.fabioformosa.quartzmanager.security.helpers.impl.JwtUsernamePasswordFiterLoginConfig;
|
||||
import it.fabioformosa.quartzmanager.security.helpers.impl.LogoutSuccess;
|
||||
import it.fabioformosa.quartzmanager.security.helpers.impl.QuartzManagerHttpSecurity;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -51,142 +51,142 @@ import it.fabioformosa.quartzmanager.security.helpers.impl.LogoutSuccess;
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private static final String[] PATTERNS_SWAGGER_UI = {"/swagger-ui.html", "/v2/api-docs", "/swagger-resources/**", "/webjars/**"};
|
||||
private static final String[] PATTERNS_SWAGGER_UI = {"/swagger-ui.html", "/v2/api-docs", "/swagger-resources/**", "/webjars/**"};
|
||||
|
||||
private static final String LOGIN_PATH = "/api/login";
|
||||
private static final String LOGOUT_PATH = "/api/logout";
|
||||
private static final String LOGIN_PATH = "/quartz-manager/api/login";
|
||||
private static final String LOGOUT_PATH = "/quartz-manager/api/logout";
|
||||
|
||||
@Value("${server.servlet.context-path}")
|
||||
private String contextPath;
|
||||
@Value("${server.servlet.context-path}")
|
||||
private String contextPath;
|
||||
|
||||
@Value("${app.name}")
|
||||
private String APP_NAME;
|
||||
@Value("${app.name}")
|
||||
private String APP_NAME;
|
||||
|
||||
@Value("${quartz-manager.security.login-model.form-login-enabled}")
|
||||
private Boolean formLoginEnabled;
|
||||
@Value("${quartz-manager.security.login-model.userpwd-filter-enabled}")
|
||||
private Boolean userpwdFilterEnabled;
|
||||
@Value("${quartz-manager.security.login-model.form-login-enabled}")
|
||||
private Boolean formLoginEnabled;
|
||||
@Value("${quartz-manager.security.login-model.userpwd-filter-enabled}")
|
||||
private Boolean userpwdFilterEnabled;
|
||||
|
||||
@Autowired
|
||||
private JwtSecurityProperties jwtSecurityProps;
|
||||
@Autowired
|
||||
private JwtSecurityProperties jwtSecurityProps;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
@Autowired
|
||||
private InMemoryAccountProperties inMemoryAccountProps;
|
||||
@Autowired
|
||||
private InMemoryAccountProperties inMemoryAccountProps;
|
||||
|
||||
|
||||
@Override
|
||||
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder)throws Exception {
|
||||
configureInMemoryAuthentication(authenticationManagerBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.csrf().disable() //
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() //
|
||||
.exceptionHandling().authenticationEntryPoint(restAuthEntryPoint()).and() //
|
||||
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class) //
|
||||
.authorizeRequests().anyRequest().authenticated();
|
||||
|
||||
QuartzManagerHttpSecurity.from(http).withLoginConfigurer(loginConfigurer(), logoutConfigurer()) //
|
||||
.login(LOGIN_PATH, authenticationManager()).logout(LOGOUT_PATH);
|
||||
|
||||
// temporary disabled csfr
|
||||
// http.csrf().ignoringAntMatchers("/api/login", "/api/signup") //
|
||||
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) //
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(WebSecurity web) throws Exception {
|
||||
web.ignoring()//
|
||||
.antMatchers(HttpMethod.GET, PATTERNS_SWAGGER_UI) //
|
||||
.antMatchers(HttpMethod.GET,"/css/**", "/js/**", "/img/**", "/lib/**");
|
||||
}
|
||||
|
||||
private void configureInMemoryAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
|
||||
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||
if(inMemoryAccountProps.isEnabled() && inMemoryAccountProps.getUsers() != null && !inMemoryAccountProps.getUsers().isEmpty()) {
|
||||
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuth = authenticationManagerBuilder.inMemoryAuthentication();
|
||||
inMemoryAccountProps.getUsers()
|
||||
.forEach(u -> inMemoryAuth
|
||||
.withUser(u.getName())
|
||||
.password(encoder.encode(u.getPassword()))
|
||||
.roles(u.getRoles().toArray(new String[0])));
|
||||
@Override
|
||||
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder)throws Exception {
|
||||
configureInMemoryAuthentication(authenticationManagerBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
CorsConfigurationSource corsConfigurationSource() {
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
|
||||
return source;
|
||||
}
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.csrf().disable() //
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() //
|
||||
.exceptionHandling().authenticationEntryPoint(restAuthEntryPoint()).and() //
|
||||
.addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class) //
|
||||
.authorizeRequests().anyRequest().authenticated();
|
||||
|
||||
@Bean
|
||||
public LoginConfigurer formLoginConfigurer() {
|
||||
JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler();
|
||||
AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler(jwtAuthenticationSuccessHandler);
|
||||
AuthenticationFailureHandler authenticationFailureHandler = new AuthenticationFailureHandler();
|
||||
LoginConfigurer loginConfigurer = new FormLoginConfig(authenticationSuccessHandler, authenticationFailureHandler);
|
||||
return loginConfigurer;
|
||||
}
|
||||
QuartzManagerHttpSecurity.from(http).withLoginConfigurer(loginConfigurer(), logoutConfigurer()) //
|
||||
.login(LOGIN_PATH, authenticationManager()).logout(LOGOUT_PATH);
|
||||
|
||||
@Bean
|
||||
public JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler() {
|
||||
JwtTokenHelper jwtTokenHelper = jwtTokenHelper();
|
||||
JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = new JwtAuthenticationSuccessHandlerImpl(contextPath, jwtSecurityProps, jwtTokenHelper, objectMapper);
|
||||
return jwtAuthenticationSuccessHandler;
|
||||
}
|
||||
// temporary disabled csfr
|
||||
// http.csrf().ignoringAntMatchers("/api/login", "/api/signup") //
|
||||
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) //
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtTokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
|
||||
return new JwtTokenAuthenticationFilter(jwtTokenHelper(), userDetailsService);
|
||||
}
|
||||
@Override
|
||||
public void configure(WebSecurity web) throws Exception {
|
||||
web.ignoring()//
|
||||
.antMatchers(HttpMethod.GET, PATTERNS_SWAGGER_UI) //
|
||||
.antMatchers(HttpMethod.GET,"/css/**", "/js/**", "/img/**", "/lib/**");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtTokenHelper jwtTokenHelper() {
|
||||
return new JwtTokenHelper(APP_NAME, jwtSecurityProps);
|
||||
}
|
||||
private void configureInMemoryAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
|
||||
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||
if(inMemoryAccountProps.isEnabled() && inMemoryAccountProps.getUsers() != null && !inMemoryAccountProps.getUsers().isEmpty()) {
|
||||
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuth = authenticationManagerBuilder.inMemoryAuthentication();
|
||||
inMemoryAccountProps.getUsers()
|
||||
.forEach(u -> inMemoryAuth
|
||||
.withUser(u.getName())
|
||||
.password(encoder.encode(u.getPassword()))
|
||||
.roles(u.getRoles().toArray(new String[0])));
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoginConfigurer loginConfigurer() {
|
||||
if(BooleanUtils.isTrue(userpwdFilterEnabled))
|
||||
return userpwdFilterLoginConfigurer();
|
||||
if(BooleanUtils.isNotFalse(formLoginEnabled))
|
||||
return formLoginConfigurer();
|
||||
throw new RuntimeException("No login configurer enabled!");
|
||||
}
|
||||
@Bean
|
||||
CorsConfigurationSource corsConfigurationSource() {
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
|
||||
return source;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LogoutSuccess logoutConfigurer() {
|
||||
return new LogoutSuccess(objectMapper);
|
||||
}
|
||||
@Bean
|
||||
public LoginConfigurer formLoginConfigurer() {
|
||||
JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = jwtAuthenticationSuccessHandler();
|
||||
AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler(jwtAuthenticationSuccessHandler);
|
||||
AuthenticationFailureHandler authenticationFailureHandler = new AuthenticationFailureHandler();
|
||||
LoginConfigurer loginConfigurer = new FormLoginConfig(authenticationSuccessHandler, authenticationFailureHandler);
|
||||
return loginConfigurer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationEntryPoint restAuthEntryPoint() {
|
||||
return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
@Bean
|
||||
public JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler() {
|
||||
JwtTokenHelper jwtTokenHelper = jwtTokenHelper();
|
||||
JwtAuthenticationSuccessHandler jwtAuthenticationSuccessHandler = new JwtAuthenticationSuccessHandlerImpl(contextPath, jwtSecurityProps, jwtTokenHelper, objectMapper);
|
||||
return jwtAuthenticationSuccessHandler;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public UserDetailsService userDetailsServiceBean() throws Exception {
|
||||
return super.userDetailsServiceBean();
|
||||
}
|
||||
@Bean
|
||||
public JwtTokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
|
||||
return new JwtTokenAuthenticationFilter(jwtTokenHelper(), userDetailsService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoginConfigurer userpwdFilterLoginConfigurer() {
|
||||
LoginConfigurer loginConfigurer = new JwtUsernamePasswordFiterLoginConfig(jwtAuthenticationSuccessHandler());
|
||||
return loginConfigurer;
|
||||
}
|
||||
@Bean
|
||||
public JwtTokenHelper jwtTokenHelper() {
|
||||
return new JwtTokenHelper(APP_NAME, jwtSecurityProps);
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public PasswordEncoder passwordEncoder() {
|
||||
// return new BCryptPasswordEncoder();
|
||||
// }
|
||||
@Bean
|
||||
public LoginConfigurer loginConfigurer() {
|
||||
if(BooleanUtils.isTrue(userpwdFilterEnabled))
|
||||
return userpwdFilterLoginConfigurer();
|
||||
if(BooleanUtils.isNotFalse(formLoginEnabled))
|
||||
return formLoginConfigurer();
|
||||
throw new RuntimeException("No login configurer enabled!");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LogoutSuccess logoutConfigurer() {
|
||||
return new LogoutSuccess(objectMapper);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationEntryPoint restAuthEntryPoint() {
|
||||
return new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public UserDetailsService userDetailsServiceBean() throws Exception {
|
||||
return super.userDetailsServiceBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LoginConfigurer userpwdFilterLoginConfigurer() {
|
||||
LoginConfigurer loginConfigurer = new JwtUsernamePasswordFiterLoginConfig(jwtAuthenticationSuccessHandler());
|
||||
return loginConfigurer;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public PasswordEncoder passwordEncoder() {
|
||||
// return new BCryptPasswordEncoder();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -8,66 +8,66 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequestMapping(value = "/quartz-manager/api", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public class UserController {
|
||||
|
||||
/**
|
||||
* JWT Temporary disabled
|
||||
*
|
||||
* @author Fabio.Formosa
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* JWT Temporary disabled
|
||||
*
|
||||
* @author Fabio.Formosa
|
||||
*
|
||||
*/
|
||||
|
||||
// @Autowired
|
||||
// private UserService userService;
|
||||
// @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);
|
||||
// }
|
||||
// @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();
|
||||
// }
|
||||
/*
|
||||
* 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();
|
||||
// }
|
||||
|
||||
@GetMapping("/whoami")
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
public Object user() {
|
||||
return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
}
|
||||
@GetMapping("/whoami")
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
public Object user() {
|
||||
return SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
server:
|
||||
servlet:
|
||||
context-path: /quartz-manager
|
||||
context-path: /
|
||||
session.timeout : 28800
|
||||
port: 8080
|
||||
|
||||
|
||||
Reference in New Issue
Block a user