diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/QuartManagerApplication.java b/quartz-manager-backend/src/main/java/it/fabioformosa/QuartManagerApplication.java index a754547..4beee27 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/QuartManagerApplication.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/QuartManagerApplication.java @@ -1,12 +1,12 @@ -package it.fabioformosa; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class QuartManagerApplication { - - public static void main(String[] args) { - SpringApplication.run(QuartManagerApplication.class, args); - } -} +package it.fabioformosa; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class QuartManagerApplication { + + public static void main(String[] args) { + SpringApplication.run(QuartManagerApplication.class, args); + } +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/MVCConfig.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/MVCConfig.java deleted file mode 100644 index 8d5c43d..0000000 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/MVCConfig.java +++ /dev/null @@ -1,22 +0,0 @@ -package it.fabioformosa.quartzmanager.configuration; - -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -@Configuration -public class MVCConfig extends WebMvcConfigurerAdapter { - - @Override - public void addViewControllers(ViewControllerRegistry registry) { - registry.addViewController("/login").setViewName("login"); - registry.addViewController("/").setViewName("redirect:/manager"); - - registry.addViewController("/templates/manager/config-form.html").setViewName("manager/config-form"); - registry.addViewController("/templates/manager/progress-panel.html") - .setViewName("manager/progress-panel"); - registry.addViewController("/templates/manager/logs-panel.html").setViewName("manager/logs-panel"); - - } - -} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfig.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfig.java index 853af29..2d72da5 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfig.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfig.java @@ -1,90 +1,75 @@ -package it.fabioformosa.quartzmanager.configuration; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; -import org.springframework.security.web.csrf.CookieCsrfTokenRepository; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; - -import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler; -import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler; -import it.fabioformosa.quartzmanager.security.auth.LogoutSuccess; -import it.fabioformosa.quartzmanager.security.auth.RestAuthenticationEntryPoint; -import it.fabioformosa.quartzmanager.security.auth.TokenAuthenticationFilter; -import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService; - -/** - * Created by fan.jin on 2016-10-19. - */ - -@Configuration -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - - @Value("${jwt.cookie}") - private String TOKEN_COOKIE; - - @Autowired - private CustomUserDetailsService jwtUserDetailsService; - - @Autowired - private RestAuthenticationEntryPoint restAuthenticationEntryPoint; - - @Autowired - private LogoutSuccess logoutSuccess; - - @Autowired - private AuthenticationSuccessHandler authenticationSuccessHandler; - - @Autowired - private AuthenticationFailureHandler authenticationFailureHandler; - - @Bean - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); - } - - @Autowired - public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) - throws Exception { - authenticationManagerBuilder.userDetailsService(jwtUserDetailsService) - .passwordEncoder(passwordEncoder()); - - } - - @Bean - public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception { - return new TokenAuthenticationFilter(); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.csrf().ignoringAntMatchers("/api/login", "/api/signup") - .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and() - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() - .exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint).and() - .addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class) - .authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/api/login") - .successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler) - .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/api/logout")) - .logoutSuccessHandler(logoutSuccess).deleteCookies(TOKEN_COOKIE); - - } - -} +package it.fabioformosa.quartzmanager.configuration; + +import javax.annotation.Resource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import it.fabioformosa.quartzmanager.security.ComboEntryPoint; +import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler; +import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Configuration + @Order(1) + public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable() // + .antMatcher("/notifications").authorizeRequests().anyRequest().hasAnyRole("ADMIN").and() + .httpBasic(); + + // http.antMatcher("/logs/**").authorizeRequests().anyRequest() + // .permitAll(); + } + } + + @Configuration + @Order(2) + public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Resource + private ComboEntryPoint comboEntryPoint; + + @Autowired + private AuthenticationSuccessHandler authenticationSuccessHandler; + + @Autowired + private AuthenticationFailureHandler authenticationFailureHandler; + + @Override + public void configure(WebSecurity web) throws Exception { + web.ignoring().antMatchers("/css/**", "/js/**", "/img/**", "/lib/**"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // http.csrf().ignoringAntMatchers("/api/login", "/api/signup").and() // + http.cors().and().csrf().disable() + .exceptionHandling().authenticationEntryPoint(comboEntryPoint).and()// + .authorizeRequests().anyRequest().authenticated().and()// + .formLogin().loginPage("/api/login").successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler).and().logout() + .logoutRequestMatcher(new AntPathRequestMatcher("/api/logout")) + .logoutSuccessUrl("/manager"); + } + } + + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN"); + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java new file mode 100644 index 0000000..8f6bf0d --- /dev/null +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigJWT.java @@ -0,0 +1,99 @@ +package it.fabioformosa.quartzmanager.configuration; + +import javax.annotation.Resource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import it.fabioformosa.quartzmanager.security.ComboEntryPoint; +import it.fabioformosa.quartzmanager.security.auth.AuthenticationFailureHandler; +import it.fabioformosa.quartzmanager.security.auth.AuthenticationSuccessHandler; +import it.fabioformosa.quartzmanager.security.auth.LogoutSuccess; +import it.fabioformosa.quartzmanager.security.auth.RestAuthenticationEntryPoint; +import it.fabioformosa.quartzmanager.security.auth.TokenAuthenticationFilter; +import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService; + +//@Configuration +//@EnableGlobalMethodSecurity(prePostEnabled = true) +public class WebSecurityConfigJWT extends WebSecurityConfigurerAdapter { + + @Value("${jwt.cookie}") + private String TOKEN_COOKIE; + + @Autowired + private CustomUserDetailsService jwtUserDetailsService; + + @Autowired + private RestAuthenticationEntryPoint restAuthenticationEntryPoint; + @Resource + private ComboEntryPoint comboEntryPoint; + + @Autowired + private LogoutSuccess logoutSuccess; + + @Autowired + private AuthenticationSuccessHandler authenticationSuccessHandler; + + @Autowired + private AuthenticationFailureHandler authenticationFailureHandler; + + @Bean + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) + throws Exception { + authenticationManagerBuilder.userDetailsService(jwtUserDetailsService) + .passwordEncoder(passwordEncoder()); + + } + + @Bean + public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception { + return new TokenAuthenticationFilter(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // http.csrf().ignoringAntMatchers("/api/login", "/api/signup") + // .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and() + http.cors().and().csrf().disable() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + .exceptionHandling().authenticationEntryPoint(comboEntryPoint).and() + .addFilterBefore(jwtAuthenticationTokenFilter(), BasicAuthenticationFilter.class) + .authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/api/login") + .successHandler(authenticationSuccessHandler).failureHandler(authenticationFailureHandler) + .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/api/logout")) + .logoutSuccessHandler(logoutSuccess).deleteCookies(TOKEN_COOKIE); + + } + + @Bean + CorsConfigurationSource corsConfigurationSource() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); + return source; + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigOld.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigOld.java deleted file mode 100644 index f3e0dff..0000000 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebSecurityConfigOld.java +++ /dev/null @@ -1,63 +0,0 @@ -package it.fabioformosa.quartzmanager.configuration; - -import javax.annotation.Resource; - -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; - -import it.fabioformosa.quartzmanager.security.AjaxAuthenticationFilter; -import it.fabioformosa.quartzmanager.security.ComboEntryPoint; - -//@Configuration -//@EnableWebSecurity -public class WebSecurityConfigOld extends WebSecurityConfigurerAdapter { - - // @Configuration - // @Order(1) - public static class ApiWebSecurityConfig extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http.csrf().disable() // - .antMatcher("/notifications").authorizeRequests().anyRequest().hasAnyRole("ADMIN").and() - .httpBasic(); - - // http.antMatcher("/logs/**").authorizeRequests().anyRequest() - // .permitAll(); - } - } - - // @Configuration - // @Order(2) - public static class FormWebSecurityConfig extends WebSecurityConfigurerAdapter { - - @Resource - private ComboEntryPoint comboEntryPoint; - - @Override - public void configure(WebSecurity web) throws Exception { - web.ignoring().antMatchers("/css/**", "/js/**", "/img/**", "/lib/**"); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.csrf().ignoringAntMatchers("/api/login", "/api/signup").and() // - .exceptionHandling().authenticationEntryPoint(comboEntryPoint).and().csrf().disable()// - .authorizeRequests().anyRequest().authenticated().and()// - .addFilterBefore(new AjaxAuthenticationFilter(authenticationManager()), - UsernamePasswordAuthenticationFilter.class)// - .formLogin().loginPage("/api/login").permitAll().and().logout() - .logoutRequestMatcher(new AntPathRequestMatcher("/api/logout")) - .logoutSuccessUrl("/manager"); - } - } - - // @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN"); - } - -} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebsocketConfig.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebsocketConfig.java index 0591af5..22fb094 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebsocketConfig.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/configuration/WebsocketConfig.java @@ -1,25 +1,25 @@ -package it.fabioformosa.quartzmanager.configuration; - -import org.springframework.context.annotation.Configuration; -import org.springframework.messaging.simp.config.MessageBrokerRegistry; -import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; -import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; -import org.springframework.web.socket.config.annotation.StompEndpointRegistry; - -@Configuration -@EnableWebSocketMessageBroker -public class WebsocketConfig extends AbstractWebSocketMessageBrokerConfigurer { - - @Override - public void configureMessageBroker(MessageBrokerRegistry config) { - config.enableSimpleBroker("/topic"); - config.setApplicationDestinationPrefixes("/job"); - } - - @Override - public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/logs").withSockJS(); - registry.addEndpoint("/progress").withSockJS(); - } - -} +package it.fabioformosa.quartzmanager.configuration; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; + +@Configuration +@EnableWebSocketMessageBroker +public class WebsocketConfig extends AbstractWebSocketMessageBrokerConfigurer { + + @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(); + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java index 9f8bdc5..e67162c 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/AuthenticationController.java @@ -1,81 +1,75 @@ -package it.fabioformosa.quartzmanager.controllers; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import it.fabioformosa.quartzmanager.security.TokenHelper; -import it.fabioformosa.quartzmanager.security.model.UserTokenState; -import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService; - -/** - * Created by fan.jin on 2017-05-10. - */ - -@RestController -@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE ) -public class AuthenticationController { - - static class PasswordChanger { - public String oldPassword; - public String newPassword; - } - - @Autowired - private CustomUserDetailsService userDetailsService; - - @Autowired - TokenHelper tokenHelper; - - @Value("${jwt.expires_in}") - private int EXPIRES_IN; - - @Value("${jwt.cookie}") - private String TOKEN_COOKIE; - - @RequestMapping(value = "/changePassword", method = RequestMethod.POST) - @PreAuthorize("hasRole('USER')") - public ResponseEntity changePassword(@RequestBody PasswordChanger passwordChanger) { - userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword); - Map result = new HashMap<>(); - result.put( "result", "success" ); - return ResponseEntity.accepted().body(result); - } - - @RequestMapping(value = "/refresh", method = RequestMethod.GET) - public ResponseEntity refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) { - - String authToken = tokenHelper.getToken( request ); - if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) { - // TODO check user password last update - String refreshedToken = tokenHelper.refreshToken(authToken); - - Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken ); - authCookie.setPath( "/" ); - authCookie.setHttpOnly( true ); - authCookie.setMaxAge( EXPIRES_IN ); - // Add cookie to response - response.addCookie( authCookie ); - - UserTokenState userTokenState = new UserTokenState(refreshedToken, EXPIRES_IN); - return ResponseEntity.ok(userTokenState); - } else { - UserTokenState userTokenState = new UserTokenState(); - return ResponseEntity.accepted().body(userTokenState); - } - } - -} +package it.fabioformosa.quartzmanager.controllers; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import it.fabioformosa.quartzmanager.security.TokenHelper; +import it.fabioformosa.quartzmanager.security.model.UserTokenState; +import it.fabioformosa.quartzmanager.security.service.impl.CustomUserDetailsService; + +//@RestController +//@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE ) +public class AuthenticationController { + + static class PasswordChanger { + public String oldPassword; + public String newPassword; + } + + @Autowired + private CustomUserDetailsService userDetailsService; + + @Autowired + TokenHelper tokenHelper; + + @Value("${jwt.expires_in}") + private int EXPIRES_IN; + + @Value("${jwt.cookie}") + private String TOKEN_COOKIE; + + @RequestMapping(value = "/changePassword", method = RequestMethod.POST) + @PreAuthorize("hasRole('USER')") + public ResponseEntity changePassword(@RequestBody PasswordChanger passwordChanger) { + userDetailsService.changePassword(passwordChanger.oldPassword, passwordChanger.newPassword); + Map result = new HashMap<>(); + result.put( "result", "success" ); + return ResponseEntity.accepted().body(result); + } + + @RequestMapping(value = "/refresh", method = RequestMethod.GET) + public ResponseEntity refreshAuthenticationToken(HttpServletRequest request, HttpServletResponse response) { + + String authToken = tokenHelper.getToken( request ); + if (authToken != null && tokenHelper.canTokenBeRefreshed(authToken)) { + // TODO check user password last update + String refreshedToken = tokenHelper.refreshToken(authToken); + + Cookie authCookie = new Cookie( TOKEN_COOKIE, refreshedToken ); + authCookie.setPath( "/" ); + authCookie.setHttpOnly( true ); + authCookie.setMaxAge( EXPIRES_IN ); + // Add cookie to response + response.addCookie( authCookie ); + + UserTokenState userTokenState = new UserTokenState(refreshedToken, EXPIRES_IN); + return ResponseEntity.ok(userTokenState); + } else { + UserTokenState userTokenState = new UserTokenState(); + return ResponseEntity.accepted().body(userTokenState); + } + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/PublicController.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/PublicController.java deleted file mode 100644 index 57cf88d..0000000 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/PublicController.java +++ /dev/null @@ -1,27 +0,0 @@ -package it.fabioformosa.quartzmanager.controllers; - -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.HashMap; -import java.util.Map; - -import static org.springframework.web.bind.annotation.RequestMethod.GET; - -/** - * Created by fan.jin on 2017-05-08. - */ - -@RestController -@RequestMapping( value = "/api", produces = MediaType.APPLICATION_JSON_VALUE ) -public class PublicController { - - @RequestMapping( method = GET, value= "/foo") - public Map getFoo() { - Map fooObj = new HashMap<>(); - fooObj.put("foo", "bar"); - return fooObj; - } - -} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java index a625ea5..aaecc79 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java @@ -1,133 +1,156 @@ -package it.fabioformosa.quartzmanager.controllers; - -import javax.annotation.Resource; - -import org.quartz.DailyTimeIntervalTrigger; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.SimpleScheduleBuilder; -import org.quartz.SimpleTrigger; -import org.quartz.Trigger; -import org.quartz.TriggerBuilder; -import org.quartz.impl.triggers.SimpleTriggerImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam; -import it.fabioformosa.quartzmanager.dto.TriggerProgress; -import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor; - -@RestController -@RequestMapping("/scheduler") -public class SchedulerController { - - private static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24; - private static final int SEC_IN_A_DAY = 60 * 60 * 24; - - private final Logger log = LoggerFactory.getLogger(SchedulerController.class); - - @Resource - private Scheduler scheduler; - - @Resource - private TriggerMonitor triggerMonitor; - - @SuppressWarnings("unused") - private long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) { - return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills); - } - - private int fromTriggerPerDayToMillSecInterval(long triggerPerDay) { - return (int) Math.ceil(Long.valueOf(MILLS_IN_A_DAY) / triggerPerDay); //with ceil the triggerPerDay is a max value - } - - private int fromTriggerPerDayToSecInterval(long triggerPerDay) { - return (int) Math.ceil(Long.valueOf(SEC_IN_A_DAY) / triggerPerDay); - } - - @RequestMapping(value = "/config", method = RequestMethod.GET) - public SchedulerConfigParam getConfig() { - SchedulerConfigParam config = new SchedulerConfigParam(); - - int maxCount = 0; - long repeatIntervalInMills = 0; - if (triggerMonitor.getTrigger() instanceof SimpleTrigger) { - SimpleTrigger simpleTrigger = (SimpleTrigger) triggerMonitor.getTrigger(); - maxCount = simpleTrigger.getRepeatCount() + 1; - repeatIntervalInMills = fromTriggerPerDayToMillSecInterval(simpleTrigger.getRepeatInterval()); - } else if (triggerMonitor.getTrigger() instanceof DailyTimeIntervalTrigger) { - DailyTimeIntervalTrigger dailyTimeIntervalTrigger = (DailyTimeIntervalTrigger) triggerMonitor - .getTrigger(); - maxCount = dailyTimeIntervalTrigger.getRepeatCount() + 1; - repeatIntervalInMills = fromTriggerPerDayToSecInterval( - dailyTimeIntervalTrigger.getRepeatInterval()); - } - - config.setMaxCount(maxCount); - config.setTriggerPerDay(repeatIntervalInMills); - return config; - } - - @RequestMapping("/progress") - public TriggerProgress getProgressInfo() throws SchedulerException { - - SimpleTriggerImpl jobTrigger = ((SimpleTriggerImpl) scheduler - .getTrigger(triggerMonitor.getTrigger().getKey())); - - TriggerProgress progress = new TriggerProgress(); - if (jobTrigger != null && jobTrigger.getJobKey() != null) { - progress.setJobKey(jobTrigger.getJobKey().getName()); - progress.setJobClass(jobTrigger.getClass().getSimpleName()); - progress.setTimesTriggered(jobTrigger.getTimesTriggered()); - progress.setRepeatCount(jobTrigger.getRepeatCount()); - progress.setFinalFireTime(jobTrigger.getFinalFireTime()); - progress.setNextFireTime(jobTrigger.getNextFireTime()); - progress.setPreviousFireTime(jobTrigger.getPreviousFireTime()); - } - return progress; - } - - @RequestMapping("/pause") - public void pause() throws SchedulerException { - scheduler.standby(); - } - - @RequestMapping(value = "/config", method = RequestMethod.POST) - public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) - throws SchedulerException { - - SimpleTrigger trigger = (SimpleTrigger) triggerMonitor.getTrigger(); - TriggerBuilder triggerBuilder = trigger.getTriggerBuilder(); - - int intervalInSeconds = fromTriggerPerDayToMillSecInterval(config.getTriggerPerDay()); - Trigger newTrigger = triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule() - .withIntervalInMilliseconds(intervalInSeconds).withRepeatCount(config.getMaxCount() - 1)) - .build(); - - scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger); - triggerMonitor.setTrigger(newTrigger); - return config; - } - - @RequestMapping("/resume") - public void resume() throws SchedulerException { - scheduler.start(); - } - - @RequestMapping("/run") - public void run() throws SchedulerException { - log.info("Starting scheduler..."); - scheduler.start(); - } - - @RequestMapping("/stop") - public void stop() throws SchedulerException { - log.info("Stopping scheduler..."); - scheduler.shutdown(true); - } - -} +package it.fabioformosa.quartzmanager.controllers; + +import java.util.Collections; +import java.util.Map; + +import javax.annotation.Resource; + +import org.quartz.DailyTimeIntervalTrigger; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.SimpleScheduleBuilder; +import org.quartz.SimpleTrigger; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; +import org.quartz.impl.triggers.SimpleTriggerImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import it.fabioformosa.quartzmanager.controllers.ManagerController.SchedulerStates; +import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam; +import it.fabioformosa.quartzmanager.dto.TriggerProgress; +import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor; + +@RestController +@RequestMapping("/scheduler") +public class SchedulerController { + + private static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24; + private static final int SEC_IN_A_DAY = 60 * 60 * 24; + + private final Logger log = LoggerFactory.getLogger(SchedulerController.class); + + @Resource + private Scheduler scheduler; + + @Resource + private TriggerMonitor triggerMonitor; + + @RequestMapping(value = "/config", method = RequestMethod.GET) + public SchedulerConfigParam getConfig() { + SchedulerConfigParam config = new SchedulerConfigParam(); + + int maxCount = 0; + long repeatIntervalInMills = 0; + if (triggerMonitor.getTrigger() instanceof SimpleTrigger) { + SimpleTrigger simpleTrigger = (SimpleTrigger) triggerMonitor.getTrigger(); + maxCount = simpleTrigger.getRepeatCount() + 1; + repeatIntervalInMills = fromTriggerPerDayToMillSecInterval(simpleTrigger.getRepeatInterval()); + } else if (triggerMonitor.getTrigger() instanceof DailyTimeIntervalTrigger) { + DailyTimeIntervalTrigger dailyTimeIntervalTrigger = (DailyTimeIntervalTrigger) triggerMonitor + .getTrigger(); + maxCount = dailyTimeIntervalTrigger.getRepeatCount() + 1; + repeatIntervalInMills = fromTriggerPerDayToSecInterval( + dailyTimeIntervalTrigger.getRepeatInterval()); + } + + config.setMaxCount(maxCount); + config.setTriggerPerDay(repeatIntervalInMills); + return config; + } + + @RequestMapping("/progress") + public TriggerProgress getProgressInfo() throws SchedulerException { + + SimpleTriggerImpl jobTrigger = (SimpleTriggerImpl) scheduler + .getTrigger(triggerMonitor.getTrigger().getKey()); + + TriggerProgress progress = new TriggerProgress(); + if (jobTrigger != null && jobTrigger.getJobKey() != null) { + progress.setJobKey(jobTrigger.getJobKey().getName()); + progress.setJobClass(jobTrigger.getClass().getSimpleName()); + progress.setTimesTriggered(jobTrigger.getTimesTriggered()); + progress.setRepeatCount(jobTrigger.getRepeatCount()); + progress.setFinalFireTime(jobTrigger.getFinalFireTime()); + progress.setNextFireTime(jobTrigger.getNextFireTime()); + progress.setPreviousFireTime(jobTrigger.getPreviousFireTime()); + } + return progress; + } + + @GetMapping(produces = "application/json") + public Map getStatus() throws SchedulerException { + String schedulerState = ""; + if (scheduler.isShutdown() || !scheduler.isStarted()) + schedulerState = SchedulerStates.STOPPED.toString(); + else if (scheduler.isStarted() && scheduler.isInStandbyMode()) + schedulerState = SchedulerStates.PAUSED.toString(); + else + schedulerState = SchedulerStates.RUNNING.toString(); + return Collections.singletonMap("data", schedulerState.toLowerCase()); + } + + @RequestMapping("/pause") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void pause() throws SchedulerException { + scheduler.standby(); + } + + @RequestMapping(value = "/config", method = RequestMethod.POST) + public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) + throws SchedulerException { + + SimpleTrigger trigger = (SimpleTrigger) triggerMonitor.getTrigger(); + TriggerBuilder triggerBuilder = trigger.getTriggerBuilder(); + + int intervalInSeconds = fromTriggerPerDayToMillSecInterval(config.getTriggerPerDay()); + Trigger newTrigger = triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule() + .withIntervalInMilliseconds(intervalInSeconds).withRepeatCount(config.getMaxCount() - 1)) + .build(); + + scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger); + triggerMonitor.setTrigger(newTrigger); + return config; + } + + @RequestMapping("/resume") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void resume() throws SchedulerException { + scheduler.start(); + } + + @RequestMapping("/run") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void run() throws SchedulerException { + log.info("Starting scheduler..."); + scheduler.start(); + } + + @ResponseStatus(HttpStatus.NO_CONTENT) + @RequestMapping("/stop") + public void stop() throws SchedulerException { + log.info("Stopping scheduler..."); + scheduler.shutdown(true); + } + + @SuppressWarnings("unused") + private long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) { + return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills); + } + + private int fromTriggerPerDayToMillSecInterval(long triggerPerDay) { + return (int) Math.ceil(Long.valueOf(MILLS_IN_A_DAY) / triggerPerDay); //with ceil the triggerPerDay is a max value + } + + private int fromTriggerPerDayToSecInterval(long triggerPerDay) { + return (int) Math.ceil(Long.valueOf(SEC_IN_A_DAY) / triggerPerDay); + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java index 79754ad..819a76a 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java @@ -1,82 +1,65 @@ -package it.fabioformosa.quartzmanager.controllers; - -import static org.springframework.web.bind.annotation.RequestMethod.GET; -import static org.springframework.web.bind.annotation.RequestMethod.POST; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.util.UriComponentsBuilder; - -import it.fabioformosa.quartzmanager.exceptions.ResourceConflictException; -import it.fabioformosa.quartzmanager.security.model.User; -import it.fabioformosa.quartzmanager.security.model.UserRequest; -import it.fabioformosa.quartzmanager.security.service.UserService; - -/** - * Created by fan.jin on 2016-10-15. - */ - -@RestController -@RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE) -public class UserController { - - @Autowired - private UserService userService; - - - @RequestMapping(method = POST, value = "/signup") - public ResponseEntity addUser(@RequestBody UserRequest userRequest, - UriComponentsBuilder ucBuilder) { - - User existUser = this.userService.findByUsername(userRequest.getUsername()); - if (existUser != null) - throw new ResourceConflictException(userRequest.getId(), "Username already exists"); - User user = this.userService.save(userRequest); - HttpHeaders headers = new HttpHeaders(); - headers.setLocation(ucBuilder.path("/api/user/{userId}").buildAndExpand(user.getId()).toUri()); - return new ResponseEntity<>(user, HttpStatus.CREATED); - } - - @RequestMapping(method = GET, value = "/user/all") - public List 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 resetCredentials() { - this.userService.resetCredentials(); - Map 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(); - } - -} +package it.fabioformosa.quartzmanager.controllers; + +import org.springframework.http.MediaType; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE) +public class UserController { + + // @Autowired + // private UserService userService; + + + // @RequestMapping(method = POST, value = "/signup") + // public ResponseEntity addUser(@RequestBody UserRequest userRequest, + // UriComponentsBuilder ucBuilder) { + // + // User existUser = this.userService.findByUsername(userRequest.getUsername()); + // if (existUser != null) + // throw new ResourceConflictException(userRequest.getId(), "Username already exists"); + // User user = this.userService.save(userRequest); + // HttpHeaders headers = new HttpHeaders(); + // headers.setLocation(ucBuilder.path("/api/user/{userId}").buildAndExpand(user.getId()).toUri()); + // return new ResponseEntity<>(user, HttpStatus.CREATED); + // } + // + // @RequestMapping(method = GET, value = "/user/all") + // public List 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 resetCredentials() { + // this.userService.resetCredentials(); + // Map result = new HashMap<>(); + // result.put("result", "success"); + // return ResponseEntity.accepted().body(result); + // } + + /* + * We are not using userService.findByUsername here(we could), so it is good that we are making + * sure that the user has role "ROLE_USER" to access this endpoint. + */ + // @RequestMapping("/whoami") + // // @PreAuthorize("hasRole('USER')") + // public User user() { + // return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + // } + + @RequestMapping("/whoami") + @PreAuthorize("isAuthenticated()") + public Object user() { + return SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/TokenHelper.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/TokenHelper.java index ab3a02b..0695574 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/TokenHelper.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/TokenHelper.java @@ -1,164 +1,156 @@ -package it.fabioformosa.quartzmanager.security; - -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import org.joda.time.DateTime; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.stereotype.Component; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import java.util.Date; -import java.util.Map; - - -/** - * Created by fan.jin on 2016-10-19. - */ - -@Component -public class TokenHelper { - - @Value("${app.name}") - private String APP_NAME; - - @Value("${jwt.secret}") - private String SECRET; - - @Value("${jwt.expires_in}") - private int EXPIRES_IN; - - @Value("${jwt.header}") - private String AUTH_HEADER; - - @Value("${jwt.cookie}") - private String AUTH_COOKIE; - - @Autowired - UserDetailsService userDetailsService; - - private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512; - - public String getUsernameFromToken(String token) { - String username; - try { - final Claims claims = this.getClaimsFromToken(token); - username = claims.getSubject(); - } catch (Exception e) { - username = null; - } - return username; - } - - public String generateToken(String username) { - return Jwts.builder() - .setIssuer( APP_NAME ) - .setSubject(username) - .setIssuedAt(generateCurrentDate()) - .setExpiration(generateExpirationDate()) - .signWith( SIGNATURE_ALGORITHM, SECRET ) - .compact(); - } - - private Claims getClaimsFromToken(String token) { - Claims claims; - try { - claims = Jwts.parser() - .setSigningKey(this.SECRET) - .parseClaimsJws(token) - .getBody(); - } catch (Exception e) { - claims = null; - } - return claims; - } - - String generateToken(Map claims) { - return Jwts.builder() - .setClaims(claims) - .setExpiration(generateExpirationDate()) - .signWith( SIGNATURE_ALGORITHM, SECRET ) - .compact(); - } - - public Boolean canTokenBeRefreshed(String token) { - try { - final Date expirationDate = getClaimsFromToken(token).getExpiration(); - String username = getUsernameFromToken(token); - UserDetails userDetails = userDetailsService.loadUserByUsername(username); - return expirationDate.compareTo(generateCurrentDate()) > 0; - } catch (Exception e) { - return false; - } - } - - public String refreshToken(String token) { - String refreshedToken; - try { - final Claims claims = getClaimsFromToken(token); - claims.setIssuedAt(generateCurrentDate()); - refreshedToken = generateToken(claims); - } catch (Exception e) { - refreshedToken = null; - } - return refreshedToken; - } - - private long getCurrentTimeMillis() { - return DateTime.now().getMillis(); - } - - private Date generateCurrentDate() { - return new Date(getCurrentTimeMillis()); - } - - private Date generateExpirationDate() { - - return new Date(getCurrentTimeMillis() + this.EXPIRES_IN * 1000); - } - - public String getToken( HttpServletRequest request ) { - /** - * Getting the token from Cookie store - */ - Cookie authCookie = getCookieValueByName( request, AUTH_COOKIE ); - if ( authCookie != null ) { - return authCookie.getValue(); - } - /** - * Getting the token from Authentication header - * e.g Bearer your_token - */ - String authHeader = request.getHeader(AUTH_HEADER); - if ( authHeader != null && authHeader.startsWith("Bearer ")) { - return authHeader.substring(7); - } - - return null; - } - - /** - * Find a specific HTTP cookie in a request. - * - * @param request - * The HTTP request object. - * @param name - * The cookie name to look for. - * @return The cookie, or null if not found. - */ - public Cookie getCookieValueByName(HttpServletRequest request, String name) { - if (request.getCookies() == null) { - return null; - } - for (int i = 0; i < request.getCookies().length; i++) { - if (request.getCookies()[i].getName().equals(name)) { - return request.getCookies()[i]; - } - } - return null; - } -} +package it.fabioformosa.quartzmanager.security; + +import java.util.Date; +import java.util.Map; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; + +import org.joda.time.DateTime; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + + +//@Component +public class TokenHelper { + + @Value("${app.name}") + private String APP_NAME; + + @Value("${jwt.secret}") + private String SECRET; + + @Value("${jwt.expires_in}") + private int EXPIRES_IN; + + @Value("${jwt.header}") + private String AUTH_HEADER; + + @Value("${jwt.cookie}") + private String AUTH_COOKIE; + + @Autowired + UserDetailsService userDetailsService; + + private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512; + + public Boolean canTokenBeRefreshed(String token) { + try { + final Date expirationDate = getClaimsFromToken(token).getExpiration(); + String username = getUsernameFromToken(token); + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + return expirationDate.compareTo(generateCurrentDate()) > 0; + } catch (Exception e) { + return false; + } + } + + public String generateToken(String username) { + return Jwts.builder() + .setIssuer( APP_NAME ) + .setSubject(username) + .setIssuedAt(generateCurrentDate()) + .setExpiration(generateExpirationDate()) + .signWith( SIGNATURE_ALGORITHM, SECRET ) + .compact(); + } + + /** + * Find a specific HTTP cookie in a request. + * + * @param request + * The HTTP request object. + * @param name + * The cookie name to look for. + * @return The cookie, or null if not found. + */ + public Cookie getCookieValueByName(HttpServletRequest request, String name) { + if (request.getCookies() == null) + return null; + for (int i = 0; i < request.getCookies().length; i++) + if (request.getCookies()[i].getName().equals(name)) + return request.getCookies()[i]; + return null; + } + + public String getToken( HttpServletRequest request ) { + /** + * Getting the token from Cookie store + */ + Cookie authCookie = getCookieValueByName( request, AUTH_COOKIE ); + if ( authCookie != null ) + return authCookie.getValue(); + /** + * Getting the token from Authentication header + * e.g Bearer your_token + */ + String authHeader = request.getHeader(AUTH_HEADER); + if ( authHeader != null && authHeader.startsWith("Bearer ")) + return authHeader.substring(7); + + return null; + } + + public String getUsernameFromToken(String token) { + String username; + try { + final Claims claims = getClaimsFromToken(token); + username = claims.getSubject(); + } catch (Exception e) { + username = null; + } + return username; + } + + public String refreshToken(String token) { + String refreshedToken; + try { + final Claims claims = getClaimsFromToken(token); + claims.setIssuedAt(generateCurrentDate()); + refreshedToken = generateToken(claims); + } catch (Exception e) { + refreshedToken = null; + } + return refreshedToken; + } + + private Date generateCurrentDate() { + return new Date(getCurrentTimeMillis()); + } + + private Date generateExpirationDate() { + + return new Date(getCurrentTimeMillis() + this.EXPIRES_IN * 1000); + } + + private Claims getClaimsFromToken(String token) { + Claims claims; + try { + claims = Jwts.parser() + .setSigningKey(this.SECRET) + .parseClaimsJws(token) + .getBody(); + } catch (Exception e) { + claims = null; + } + return claims; + } + + private long getCurrentTimeMillis() { + return DateTime.now().getMillis(); + } + + String generateToken(Map claims) { + return Jwts.builder() + .setClaims(claims) + .setExpiration(generateExpirationDate()) + .signWith( SIGNATURE_ALGORITHM, SECRET ) + .compact(); + } +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AnonAuthentication.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AnonAuthentication.java index 3b368bc..df9fa67 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AnonAuthentication.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AnonAuthentication.java @@ -1,51 +1,44 @@ -package it.fabioformosa.quartzmanager.security.auth; - -import org.springframework.security.authentication.AbstractAuthenticationToken; - -/** - * Created by fan.jin on 2017-04-04. - */ - -public class AnonAuthentication extends AbstractAuthenticationToken { - - public AnonAuthentication() { - super( null ); - } - - @Override - public Object getCredentials() { - return null; - } - - @Override - public Object getPrincipal() { - return null; - } - - @Override - public boolean isAuthenticated() { - return true; - } - - @Override - public int hashCode() { - int hash = 7; - return hash; - } - - @Override - public boolean equals( Object obj ) { - if ( this == obj ) { - return true; - } - if ( obj == null ) { - return false; - } - if ( getClass() != obj.getClass() ) { - return false; - } - return true; - } - - -} +package it.fabioformosa.quartzmanager.security.auth; + +import org.springframework.security.authentication.AbstractAuthenticationToken; + +public class AnonAuthentication extends AbstractAuthenticationToken { + + public AnonAuthentication() { + super( null ); + } + + @Override + public boolean equals( Object obj ) { + if ( this == obj ) + return true; + if ( obj == null ) + return false; + if ( getClass() != obj.getClass() ) + return false; + return true; + } + + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getPrincipal() { + return null; + } + + @Override + public int hashCode() { + int hash = 7; + return hash; + } + + @Override + public boolean isAuthenticated() { + return true; + } + + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationFailureHandler.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationFailureHandler.java index 7585552..a57f6e1 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationFailureHandler.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationFailureHandler.java @@ -1,25 +1,22 @@ -package it.fabioformosa.quartzmanager.security.auth; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * Created by fan.jin on 2016-11-07. - */ - -@Component -public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { - - @Override - public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, - AuthenticationException exception) throws IOException, ServletException { - - super.onAuthenticationFailure(request, response, exception); - } +package it.fabioformosa.quartzmanager.security.auth; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.stereotype.Component; + +@Component +public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException, ServletException { + + super.onAuthenticationFailure(request, response, exception); + } } \ No newline at end of file diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationSuccessHandler.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationSuccessHandler.java index c2b9588..f78fe81 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationSuccessHandler.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/AuthenticationSuccessHandler.java @@ -1,66 +1,65 @@ -package it.fabioformosa.quartzmanager.security.auth; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; -import org.springframework.stereotype.Component; - -/** - * Created by fan.jin on 2016-11-07. - */ -import com.fasterxml.jackson.databind.ObjectMapper; - -import it.fabioformosa.quartzmanager.security.TokenHelper; -import it.fabioformosa.quartzmanager.security.model.User; -import it.fabioformosa.quartzmanager.security.model.UserTokenState; - -@Component -public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { - - @Value("${jwt.expires_in}") - private int EXPIRES_IN; - - @Value("${jwt.cookie}") - private String TOKEN_COOKIE; - - @Autowired - TokenHelper tokenHelper; - - @Autowired - ObjectMapper objectMapper; - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, - Authentication authentication ) throws IOException, ServletException { - clearAuthenticationAttributes(request); - User user = (User)authentication.getPrincipal(); - - String jws = tokenHelper.generateToken( user.getUsername() ); - - // Create token auth Cookie - Cookie authCookie = new Cookie( TOKEN_COOKIE, jws ); - - authCookie.setHttpOnly( true ); - - authCookie.setMaxAge( EXPIRES_IN ); - - authCookie.setPath( "/" ); - // Add cookie to response - response.addCookie( authCookie ); - - // JWT is also in the response - UserTokenState userTokenState = new UserTokenState(jws, EXPIRES_IN); - String jwtResponse = objectMapper.writeValueAsString( userTokenState ); - response.setContentType("application/json"); - response.getWriter().write( jwtResponse ); - - } -} +package it.fabioformosa.quartzmanager.security.auth; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; + +@Component +public class AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { + + // @Value("${jwt.expires_in}") + // private int EXPIRES_IN; + // + // @Value("${jwt.cookie}") + // private String TOKEN_COOKIE; + // + // @Autowired + // TokenHelper tokenHelper; + // + @Autowired + ObjectMapper objectMapper; + // + // @Override + // public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + // Authentication authentication ) throws IOException, ServletException { + // clearAuthenticationAttributes(request); + // User user = (User)authentication.getPrincipal(); + // + // String jws = tokenHelper.generateToken( user.getUsername() ); + // + // // Create token auth Cookie + // Cookie authCookie = new Cookie( TOKEN_COOKIE, jws ); + // + // authCookie.setHttpOnly( true ); + // + // authCookie.setMaxAge( EXPIRES_IN ); + // + // authCookie.setPath( "/" ); + // // Add cookie to response + // response.addCookie( authCookie ); + // + // // JWT is also in the response + // UserTokenState userTokenState = new UserTokenState(jws, EXPIRES_IN); + // String jwtResponse = objectMapper.writeValueAsString( userTokenState ); + // response.setContentType("application/json"); + // response.getWriter().write( jwtResponse ); + // + // } + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication ) throws IOException, ServletException { + // clearAuthenticationAttributes(request); + response.setContentType("application/json"); + response.getWriter().write( objectMapper.writeValueAsString("OK")); + } +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/LogoutSuccess.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/LogoutSuccess.java index 5a757a6..82d2f17 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/LogoutSuccess.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/LogoutSuccess.java @@ -1,36 +1,35 @@ -package it.fabioformosa.quartzmanager.security.auth; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -/** - * Created by fan.jin on 2017-05-06. - */ -@Component -public class LogoutSuccess implements LogoutSuccessHandler { - - @Autowired - ObjectMapper objectMapper; - - @Override - public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication authentication) - throws IOException, ServletException { - Map result = new HashMap<>(); - result.put( "result", "success" ); - response.setContentType("application/json"); - response.getWriter().write( objectMapper.writeValueAsString( result ) ); - response.setStatus(HttpServletResponse.SC_OK); - - } - +package it.fabioformosa.quartzmanager.security.auth; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; + +@Component +public class LogoutSuccess implements LogoutSuccessHandler { + + @Autowired + ObjectMapper objectMapper; + + @Override + public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication authentication) + throws IOException, ServletException { + Map result = new HashMap<>(); + result.put( "result", "success" ); + response.setContentType("application/json"); + response.getWriter().write( objectMapper.writeValueAsString( result ) ); + response.setStatus(HttpServletResponse.SC_OK); + + } + } \ No newline at end of file diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/RestAuthenticationEntryPoint.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/RestAuthenticationEntryPoint.java index 837e4ee..71ad0de 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/RestAuthenticationEntryPoint.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/RestAuthenticationEntryPoint.java @@ -1,30 +1,25 @@ -package it.fabioformosa.quartzmanager.security.auth; - -/** - * Created by fan.jin on 2016-11-12. - */ - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.stereotype.Component; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * Created by fan.jin on 2016-11-07. - */ -@Component -public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { - - @Override - public void commence(HttpServletRequest request, - HttpServletResponse response, - AuthenticationException authException) throws IOException { - // This is invoked when user tries to access a secured REST resource without supplying any credentials - // We should just send a 401 Unauthorized response because there is no 'login page' to redirect to - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); - } -} - +package it.fabioformosa.quartzmanager.security.auth; + + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +@Component +public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, + HttpServletResponse response, + AuthenticationException authException) throws IOException { + // This is invoked when user tries to access a secured REST resource without supplying any credentials + // We should just send a 401 Unauthorized response because there is no 'login page' to redirect to + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); + } +} + diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/TokenAuthenticationFilter.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/TokenAuthenticationFilter.java index e1aaecc..1fae242 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/TokenAuthenticationFilter.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/TokenAuthenticationFilter.java @@ -1,94 +1,91 @@ -package it.fabioformosa.quartzmanager.security.auth; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.OrRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.Assert; -import org.springframework.web.filter.OncePerRequestFilter; - -import it.fabioformosa.quartzmanager.security.TokenHelper; - -/** - * Created by fan.jin on 2016-10-19. - */ -public class TokenAuthenticationFilter extends OncePerRequestFilter { - - /* - * The below paths will get ignored by the filter - */ - public static final String ROOT_MATCHER = "/"; - - public static final String FAVICON_MATCHER = "/favicon.ico"; - - public static final String HTML_MATCHER = "/**/*.html"; - - public static final String CSS_MATCHER = "/**/*.css"; - public static final String JS_MATCHER = "/**/*.js"; - public static final String IMG_MATCHER = "/images/*"; - public static final String LOGIN_MATCHER = "/auth/login"; - public static final String LOGOUT_MATCHER = "/auth/logout"; - private final Log logger = LogFactory.getLog(this.getClass()); - @Autowired - TokenHelper tokenHelper; - @Autowired - UserDetailsService userDetailsService; - - private List pathsToSkip = Arrays.asList( - ROOT_MATCHER, - HTML_MATCHER, - FAVICON_MATCHER, - CSS_MATCHER, - JS_MATCHER, - IMG_MATCHER, - LOGIN_MATCHER, - LOGOUT_MATCHER - ); - - @Override - public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - - - String authToken = tokenHelper.getToken(request); - if (authToken != null && !skipPathRequest(request, pathsToSkip)) - // get username from token - try { - String username = tokenHelper.getUsernameFromToken(authToken); - // get user - UserDetails userDetails = userDetailsService.loadUserByUsername(username); - // create authentication - TokenBasedAuthentication authentication = new TokenBasedAuthentication(userDetails); - authentication.setToken(authToken); - SecurityContextHolder.getContext().setAuthentication(authentication); - } catch (Exception e) { - SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication()); - } - else - SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication()); - - chain.doFilter(request, response); - } - - private boolean skipPathRequest(HttpServletRequest request, List pathsToSkip ) { - Assert.notNull(pathsToSkip, "path cannot be null."); - List m = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList()); - OrRequestMatcher matchers = new OrRequestMatcher(m); - return matchers.matches(request); - } - +package it.fabioformosa.quartzmanager.security.auth; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.OrRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.Assert; +import org.springframework.web.filter.OncePerRequestFilter; + +import it.fabioformosa.quartzmanager.security.TokenHelper; + +public class TokenAuthenticationFilter extends OncePerRequestFilter { + + /* + * The below paths will get ignored by the filter + */ + public static final String ROOT_MATCHER = "/"; + + public static final String FAVICON_MATCHER = "/favicon.ico"; + + public static final String HTML_MATCHER = "/**/*.html"; + + public static final String CSS_MATCHER = "/**/*.css"; + public static final String JS_MATCHER = "/**/*.js"; + public static final String IMG_MATCHER = "/images/*"; + public static final String LOGIN_MATCHER = "/auth/login"; + public static final String LOGOUT_MATCHER = "/auth/logout"; + private final Log logger = LogFactory.getLog(this.getClass()); + @Autowired + TokenHelper tokenHelper; + @Autowired + UserDetailsService userDetailsService; + + private List pathsToSkip = Arrays.asList( + ROOT_MATCHER, + HTML_MATCHER, + FAVICON_MATCHER, + CSS_MATCHER, + JS_MATCHER, + IMG_MATCHER, + LOGIN_MATCHER, + LOGOUT_MATCHER + ); + + @Override + public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + + + String authToken = tokenHelper.getToken(request); + if (authToken != null && !skipPathRequest(request, pathsToSkip)) + // get username from token + try { + String username = tokenHelper.getUsernameFromToken(authToken); + // get user + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + // create authentication + TokenBasedAuthentication authentication = new TokenBasedAuthentication(userDetails); + authentication.setToken(authToken); + SecurityContextHolder.getContext().setAuthentication(authentication); + } catch (Exception e) { + SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication()); + } + else + SecurityContextHolder.getContext().setAuthentication(new AnonAuthentication()); + + chain.doFilter(request, response); + } + + private boolean skipPathRequest(HttpServletRequest request, List pathsToSkip ) { + Assert.notNull(pathsToSkip, "path cannot be null."); + List m = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList()); + OrRequestMatcher matchers = new OrRequestMatcher(m); + return matchers.matches(request); + } + } \ No newline at end of file diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/TokenBasedAuthentication.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/TokenBasedAuthentication.java index 4cd60cf..82462d7 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/TokenBasedAuthentication.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/auth/TokenBasedAuthentication.java @@ -1,43 +1,40 @@ -package it.fabioformosa.quartzmanager.security.auth; - -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.core.userdetails.UserDetails; - - -/** - * Created by fan.jin on 2016-11-11. - */ -public class TokenBasedAuthentication extends AbstractAuthenticationToken { - - private String token; - private final UserDetails principle; - - public TokenBasedAuthentication( UserDetails principle ) { - super( principle.getAuthorities() ); - this.principle = principle; - } - - public String getToken() { - return token; - } - - public void setToken( String token ) { - this.token = token; - } - - @Override - public boolean isAuthenticated() { - return true; - } - - @Override - public Object getCredentials() { - return token; - } - - @Override - public UserDetails getPrincipal() { - return principle; - } - -} +package it.fabioformosa.quartzmanager.security.auth; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.userdetails.UserDetails; + + +public class TokenBasedAuthentication extends AbstractAuthenticationToken { + + private String token; + private final UserDetails principle; + + public TokenBasedAuthentication( UserDetails principle ) { + super( principle.getAuthorities() ); + this.principle = principle; + } + + @Override + public Object getCredentials() { + return token; + } + + @Override + public UserDetails getPrincipal() { + return principle; + } + + public String getToken() { + return token; + } + + @Override + public boolean isAuthenticated() { + return true; + } + + public void setToken( String token ) { + this.token = token; + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java index a9e9b3f..0b37f72 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/Authority.java @@ -1,47 +1,49 @@ -package it.fabioformosa.quartzmanager.security.model; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import org.springframework.security.core.GrantedAuthority; - -import javax.persistence.*; - -/** - * Created by fan.jin on 2016-11-03. - */ - -@Entity -@Table(name="Authority") -public class Authority implements GrantedAuthority { - - @Id - @Column(name="id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - Long id; - - @Column(name="name") - String name; - - @Override - public String getAuthority() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @JsonIgnore - public String getName() { - return name; - } - - @JsonIgnore - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - -} +package it.fabioformosa.quartzmanager.security.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.springframework.security.core.GrantedAuthority; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +@Entity +@Table(name="Authority") +public class Authority implements GrantedAuthority { + + @Id + @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; + + @Column(name="name") + String name; + + @Override + public String getAuthority() { + return name; + } + + @JsonIgnore + public Long getId() { + return id; + } + + @JsonIgnore + public String getName() { + return name; + } + + public void setId(Long id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java index 8226be6..29d7467 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/User.java @@ -1,128 +1,129 @@ -package it.fabioformosa.quartzmanager.security.model; - -import java.io.Serializable; -import java.util.Collection; -import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.Table; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import com.fasterxml.jackson.annotation.JsonIgnore; - -/** - * Created by fan.jin on 2016-10-15. - */ - -@Entity -@Table(name = "USER") -public class User implements UserDetails, Serializable { - @Id - @Column(name = "id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "username") - private String username; - - @JsonIgnore - @Column(name = "password") - private String password; - - @Column(name = "firstname") - private String firstname; - - @Column(name = "lastname") - private String lastname; - - - @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) - @JoinTable(name = "user_authority", - joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), - inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id")) - private List authorities; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getFirstname() { - return firstname; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - public String getLastname() { - return lastname; - } - - public void setLastname(String lastname) { - - this.lastname = lastname; - } - - public void setAuthorities(List authorities) { - this.authorities = authorities; - } - - @Override - public Collection getAuthorities() { - return this.authorities; - } - - // We can add the below fields in the users table. - // For now, they are hardcoded. - @JsonIgnore - @Override - public boolean isAccountNonExpired() { - return true; - } - - @JsonIgnore - @Override - public boolean isAccountNonLocked() { - return true; - } - - @JsonIgnore - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @JsonIgnore - @Override - public boolean isEnabled() { - return true; - } -} +package it.fabioformosa.quartzmanager.security.model; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +@Entity +@Table(name = "USER") +public class User implements UserDetails, Serializable { + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "username") + private String username; + + @JsonIgnore + @Column(name = "password") + private String password; + + @Column(name = "firstname") + private String firstname; + + @Column(name = "lastname") + private String lastname; + + + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinTable(name = "user_authority", + joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), + inverseJoinColumns = @JoinColumn(name = "authority_id", referencedColumnName = "id")) + private List authorities; + + @Override + public Collection getAuthorities() { + return this.authorities; + } + + public String getFirstname() { + return firstname; + } + + public Long getId() { + return id; + } + + public String getLastname() { + return lastname; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getUsername() { + return username; + } + + // We can add the below fields in the users table. + // For now, they are hardcoded. + @JsonIgnore + @Override + public boolean isAccountNonExpired() { + return true; + } + + @JsonIgnore + @Override + public boolean isAccountNonLocked() { + return true; + } + + @JsonIgnore + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @JsonIgnore + @Override + public boolean isEnabled() { + return true; + } + + public void setAuthorities(List authorities) { + this.authorities = authorities; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public void setId(Long id) { + this.id = id; + } + + public void setLastname(String lastname) { + + this.lastname = lastname; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java index 2712742..1e54e9d 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/model/UserTokenState.java @@ -1,35 +1,32 @@ -package it.fabioformosa.quartzmanager.security.model; - -/** - * Created by fan.jin on 2016-10-17. - */ -public class UserTokenState { - private String access_token; - private Long expires_in; - - public UserTokenState() { - this.access_token = null; - this.expires_in = null; - } - - public UserTokenState(String access_token, long expires_in) { - this.access_token = access_token; - this.expires_in = expires_in; - } - - public String getAccess_token() { - return access_token; - } - - public void setAccess_token(String access_token) { - this.access_token = access_token; - } - - public Long getExpires_in() { - return expires_in; - } - - public void setExpires_in(Long expires_in) { - this.expires_in = expires_in; - } -} +package it.fabioformosa.quartzmanager.security.model; + +public class UserTokenState { + private String access_token; + private Long expires_in; + + public UserTokenState() { + this.access_token = null; + this.expires_in = null; + } + + public UserTokenState(String access_token, long expires_in) { + this.access_token = access_token; + this.expires_in = expires_in; + } + + public String getAccess_token() { + return access_token; + } + + public Long getExpires_in() { + return expires_in; + } + + public void setAccess_token(String access_token) { + this.access_token = access_token; + } + + public void setExpires_in(Long expires_in) { + this.expires_in = expires_in; + } +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java index 8783be2..3e147df 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/repository/UserRepository.java @@ -1,13 +1,10 @@ -package it.fabioformosa.quartzmanager.security.repository; - -import org.springframework.data.jpa.repository.JpaRepository; - -import it.fabioformosa.quartzmanager.security.model.User; - -/** - * Created by fan.jin on 2016-10-15. - */ -public interface UserRepository extends JpaRepository { - User findByUsername( String username ); -} - +package it.fabioformosa.quartzmanager.security.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import it.fabioformosa.quartzmanager.security.model.User; + +public interface UserRepository extends JpaRepository { + User findByUsername( String username ); +} + diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java index 64a164e..76dc45c 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/UserService.java @@ -1,21 +1,18 @@ -package it.fabioformosa.quartzmanager.security.service; - -import java.util.List; - -import it.fabioformosa.quartzmanager.security.model.User; -import it.fabioformosa.quartzmanager.security.model.UserRequest; - -/** - * Created by fan.jin on 2016-10-15. - */ -public interface UserService { - List findAll(); - - User findById(Long id); - - User findByUsername(String username); - - void resetCredentials(); - - User save(UserRequest user); -} +package it.fabioformosa.quartzmanager.security.service; + +import java.util.List; + +import it.fabioformosa.quartzmanager.security.model.User; +import it.fabioformosa.quartzmanager.security.model.UserRequest; + +public interface UserService { + List findAll(); + + User findById(Long id); + + User findByUsername(String username); + + void resetCredentials(); + + User save(UserRequest user); +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java index 20c4d92..691704e 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/AuthorityServiceImpl.java @@ -1,38 +1,37 @@ -package it.fabioformosa.quartzmanager.security.service.impl; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import it.fabioformosa.quartzmanager.security.model.Authority; -import it.fabioformosa.quartzmanager.security.repository.AuthorityRepository; -import it.fabioformosa.quartzmanager.security.service.AuthorityService; - -@Service -public class AuthorityServiceImpl implements AuthorityService { - - @Autowired - private AuthorityRepository authorityRepository; - - @Override - public List findById(Long id) { - // TODO Auto-generated method stub - - Authority auth = this.authorityRepository.findOne(id); - List auths = new ArrayList<>(); - auths.add(auth); - return auths; - } - - @Override - public List findByname(String name) { - // TODO Auto-generated method stub - Authority auth = this.authorityRepository.findByName(name); - List auths = new ArrayList<>(); - auths.add(auth); - return auths; - } - -} +package it.fabioformosa.quartzmanager.security.service.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; + +import it.fabioformosa.quartzmanager.security.model.Authority; +import it.fabioformosa.quartzmanager.security.repository.AuthorityRepository; +import it.fabioformosa.quartzmanager.security.service.AuthorityService; + +//@Service +public class AuthorityServiceImpl implements AuthorityService { + + @Autowired + private AuthorityRepository authorityRepository; + + @Override + public List findById(Long id) { + // TODO Auto-generated method stub + + Authority auth = this.authorityRepository.findOne(id); + List auths = new ArrayList<>(); + auths.add(auth); + return auths; + } + + @Override + public List findByname(String name) { + // TODO Auto-generated method stub + Authority auth = this.authorityRepository.findByName(name); + List auths = new ArrayList<>(); + auths.add(auth); + return auths; + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java index 99afb76..57abcf1 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/CustomUserDetailsService.java @@ -1,70 +1,66 @@ -package it.fabioformosa.quartzmanager.security.service.impl; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; - -import it.fabioformosa.quartzmanager.security.model.User; -import it.fabioformosa.quartzmanager.security.repository.UserRepository; - -/** - * Created by fan.jin on 2016-10-31. - */ - -@Service -public class CustomUserDetailsService implements UserDetailsService { - - protected final Log LOGGER = LogFactory.getLog(getClass()); - - @Autowired - private UserRepository userRepository; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Autowired - private AuthenticationManager authenticationManager; - - public void changePassword(String oldPassword, String newPassword) { - - Authentication currentUser = SecurityContextHolder.getContext().getAuthentication(); - String username = currentUser.getName(); - - if (authenticationManager != null) { - LOGGER.debug("Re-authenticating user '"+ username + "' for password change request."); - - authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, oldPassword)); - } else { - LOGGER.debug("No authentication manager set. can't change Password!"); - - return; - } - - LOGGER.debug("Changing password for user '"+ username + "'"); - - User user = (User) loadUserByUsername(username); - - user.setPassword(passwordEncoder.encode(newPassword)); - userRepository.save(user); - - } - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - User user = userRepository.findByUsername(username); - if (user == null) - throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username)); - else - return user; - } - -} +package it.fabioformosa.quartzmanager.security.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; + +import it.fabioformosa.quartzmanager.security.model.User; +import it.fabioformosa.quartzmanager.security.repository.UserRepository; + + +//@Service +public class CustomUserDetailsService implements UserDetailsService { + + protected final Log LOGGER = LogFactory.getLog(getClass()); + + @Autowired + private UserRepository userRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private AuthenticationManager authenticationManager; + + public void changePassword(String oldPassword, String newPassword) { + + Authentication currentUser = SecurityContextHolder.getContext().getAuthentication(); + String username = currentUser.getName(); + + if (authenticationManager != null) { + LOGGER.debug("Re-authenticating user '"+ username + "' for password change request."); + + authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, oldPassword)); + } else { + LOGGER.debug("No authentication manager set. can't change Password!"); + + return; + } + + LOGGER.debug("Changing password for user '"+ username + "'"); + + User user = (User) loadUserByUsername(username); + + user.setPassword(passwordEncoder.encode(newPassword)); + userRepository.save(user); + + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + User user = userRepository.findByUsername(username); + if (user == null) + throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username)); + else + return user; + } + +} diff --git a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java index 3b2e13f..2a8836f 100644 --- a/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java +++ b/quartz-manager-backend/src/main/java/it/fabioformosa/quartzmanager/security/service/impl/UserServiceImpl.java @@ -1,78 +1,73 @@ -package it.fabioformosa.quartzmanager.security.service.impl; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; - -import it.fabioformosa.quartzmanager.security.model.Authority; -import it.fabioformosa.quartzmanager.security.model.User; -import it.fabioformosa.quartzmanager.security.model.UserRequest; -import it.fabioformosa.quartzmanager.security.repository.UserRepository; -import it.fabioformosa.quartzmanager.security.service.AuthorityService; -import it.fabioformosa.quartzmanager.security.service.UserService; - -/** - * Created by fan.jin on 2016-10-15. - */ - -@Service -public class UserServiceImpl implements UserService { - - @Autowired - private UserRepository userRepository; - - @Autowired - private PasswordEncoder passwordEncoder; - - @Autowired - private AuthorityService authService; - - @Override - @PreAuthorize("hasRole('ADMIN')") - public List findAll() throws AccessDeniedException { - List result = userRepository.findAll(); - return result; - } - - @Override - @PreAuthorize("hasRole('ADMIN')") - public User findById(Long id) throws AccessDeniedException { - User u = userRepository.findOne(id); - return u; - } - - @Override - // @PreAuthorize("hasRole('USER')") - public User findByUsername(String username) throws UsernameNotFoundException { - User u = userRepository.findByUsername(username); - return u; - } - - @Override - public void resetCredentials() { - List users = userRepository.findAll(); - for (User user : users) { - user.setPassword(passwordEncoder.encode("123")); - userRepository.save(user); - } - } - - @Override - public User save(UserRequest userRequest) { - User user = new User(); - user.setUsername(userRequest.getUsername()); - user.setPassword(passwordEncoder.encode(userRequest.getPassword())); - user.setFirstname(userRequest.getFirstname()); - user.setLastname(userRequest.getLastname()); - List auth = authService.findByname("ROLE_USER"); - user.setAuthorities(auth); - this.userRepository.save(user); - return user; - } - -} +package it.fabioformosa.quartzmanager.security.service.impl; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; + +import it.fabioformosa.quartzmanager.security.model.Authority; +import it.fabioformosa.quartzmanager.security.model.User; +import it.fabioformosa.quartzmanager.security.model.UserRequest; +import it.fabioformosa.quartzmanager.security.repository.UserRepository; +import it.fabioformosa.quartzmanager.security.service.AuthorityService; +import it.fabioformosa.quartzmanager.security.service.UserService; + +//@Service +public class UserServiceImpl implements UserService { + + @Autowired + private UserRepository userRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private AuthorityService authService; + + @Override + @PreAuthorize("hasRole('ADMIN')") + public List findAll() throws AccessDeniedException { + List result = userRepository.findAll(); + return result; + } + + @Override + @PreAuthorize("hasRole('ADMIN')") + public User findById(Long id) throws AccessDeniedException { + User u = userRepository.findOne(id); + return u; + } + + @Override + // @PreAuthorize("hasRole('USER')") + public User findByUsername(String username) throws UsernameNotFoundException { + User u = userRepository.findByUsername(username); + return u; + } + + @Override + public void resetCredentials() { + List users = userRepository.findAll(); + for (User user : users) { + user.setPassword(passwordEncoder.encode("123")); + userRepository.save(user); + } + } + + @Override + public User save(UserRequest userRequest) { + User user = new User(); + user.setUsername(userRequest.getUsername()); + user.setPassword(passwordEncoder.encode(userRequest.getPassword())); + user.setFirstname(userRequest.getFirstname()); + user.setLastname(userRequest.getLastname()); + List auth = authService.findByname("ROLE_USER"); + user.setAuthorities(auth); + this.userRepository.save(user); + return user; + } + +} diff --git a/quartz-manager-backend/src/main/resources/import.sql b/quartz-manager-backend/src/main/resources/import.sql index 7fd55c0..4120b91 100644 --- a/quartz-manager-backend/src/main/resources/import.sql +++ b/quartz-manager-backend/src/main/resources/import.sql @@ -1,11 +1,11 @@ - --- the password hash is generated by BCrypt Calculator Generator(https://www.dailycred.com/article/bcrypt-calculator) -INSERT INTO user (id, username, password, firstname, lastname) VALUES (1, 'user', '$2a$04$Vbug2lwwJGrvUXTj6z7ff.97IzVBkrJ1XfApfGNl.Z695zqcnPYra', 'Fan', 'Jin'); -INSERT INTO user (id, username, password, firstname, lastname) VALUES (2, 'admin', '$2a$04$Vbug2lwwJGrvUXTj6z7ff.97IzVBkrJ1XfApfGNl.Z695zqcnPYra', 'Jing', 'Xiao'); - -INSERT INTO authority (id, name) VALUES (1, 'ROLE_USER'); -INSERT INTO authority (id, name) VALUES (2, 'ROLE_ADMIN'); - -INSERT INTO user_authority (user_id, authority_id) VALUES (1, 1); -INSERT INTO user_authority (user_id, authority_id) VALUES (2, 1); -INSERT INTO user_authority (user_id, authority_id) VALUES (2, 2); + +-- the password hash is generated by BCrypt Calculator Generator(https://www.dailycred.com/article/bcrypt-calculator) +INSERT INTO user (id, username, password, firstname, lastname) VALUES (1, 'user', '$2a$04$Vbug2lwwJGrvUXTj6z7ff.97IzVBkrJ1XfApfGNl.Z695zqcnPYra', 'John', 'Doe'); +INSERT INTO user (id, username, password, firstname, lastname) VALUES (2, 'admin', '$2a$04$Vbug2lwwJGrvUXTj6z7ff.97IzVBkrJ1XfApfGNl.Z695zqcnPYra', 'Admin', 'Admin'); + +INSERT INTO authority (id, name) VALUES (1, 'ROLE_USER'); +INSERT INTO authority (id, name) VALUES (2, 'ROLE_ADMIN'); + +INSERT INTO user_authority (user_id, authority_id) VALUES (1, 1); +INSERT INTO user_authority (user_id, authority_id) VALUES (2, 1); +INSERT INTO user_authority (user_id, authority_id) VALUES (2, 2); diff --git a/quartz-manager-backend/src/main/resources/logback.xml b/quartz-manager-backend/src/main/resources/logback.xml new file mode 100644 index 0000000..57c6252 --- /dev/null +++ b/quartz-manager-backend/src/main/resources/logback.xml @@ -0,0 +1,23 @@ + + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/css/animate.css b/quartz-manager-backend/src/main/resources/static/css/animate.css deleted file mode 100644 index 7148b57..0000000 --- a/quartz-manager-backend/src/main/resources/static/css/animate.css +++ /dev/null @@ -1,3340 +0,0 @@ -@charset "UTF-8"; - -/*! - * animate.css -http://daneden.me/animate - * Version - 3.5.1 - * Licensed under the MIT license - http://opensource.org/licenses/MIT - * - * Copyright (c) 2016 Daniel Eden - */ - -.animated { - -webkit-animation-duration: 1s; - animation-duration: 1s; - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} - -.animated.infinite { - -webkit-animation-iteration-count: infinite; - animation-iteration-count: infinite; -} - -.animated.hinge { - -webkit-animation-duration: 2s; - animation-duration: 2s; -} - -.animated.flipOutX, -.animated.flipOutY, -.animated.bounceIn, -.animated.bounceOut { - -webkit-animation-duration: .75s; - animation-duration: .75s; -} - -@-webkit-keyframes bounce { - from, 20%, 53%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - -webkit-transform: translate3d(0,0,0); - transform: translate3d(0,0,0); - } - - 40%, 43% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -30px, 0); - transform: translate3d(0, -30px, 0); - } - - 70% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -15px, 0); - transform: translate3d(0, -15px, 0); - } - - 90% { - -webkit-transform: translate3d(0,-4px,0); - transform: translate3d(0,-4px,0); - } -} - -@keyframes bounce { - from, 20%, 53%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - -webkit-transform: translate3d(0,0,0); - transform: translate3d(0,0,0); - } - - 40%, 43% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -30px, 0); - transform: translate3d(0, -30px, 0); - } - - 70% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -15px, 0); - transform: translate3d(0, -15px, 0); - } - - 90% { - -webkit-transform: translate3d(0,-4px,0); - transform: translate3d(0,-4px,0); - } -} - -.bounce { - -webkit-animation-name: bounce; - animation-name: bounce; - -webkit-transform-origin: center bottom; - transform-origin: center bottom; -} - -@-webkit-keyframes flash { - from, 50%, to { - opacity: 1; - } - - 25%, 75% { - opacity: 0; - } -} - -@keyframes flash { - from, 50%, to { - opacity: 1; - } - - 25%, 75% { - opacity: 0; - } -} - -.flash { - -webkit-animation-name: flash; - animation-name: flash; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes pulse { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 50% { - -webkit-transform: scale3d(1.05, 1.05, 1.05); - transform: scale3d(1.05, 1.05, 1.05); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes pulse { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 50% { - -webkit-transform: scale3d(1.05, 1.05, 1.05); - transform: scale3d(1.05, 1.05, 1.05); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.pulse { - -webkit-animation-name: pulse; - animation-name: pulse; -} - -@-webkit-keyframes rubberBand { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 30% { - -webkit-transform: scale3d(1.25, 0.75, 1); - transform: scale3d(1.25, 0.75, 1); - } - - 40% { - -webkit-transform: scale3d(0.75, 1.25, 1); - transform: scale3d(0.75, 1.25, 1); - } - - 50% { - -webkit-transform: scale3d(1.15, 0.85, 1); - transform: scale3d(1.15, 0.85, 1); - } - - 65% { - -webkit-transform: scale3d(.95, 1.05, 1); - transform: scale3d(.95, 1.05, 1); - } - - 75% { - -webkit-transform: scale3d(1.05, .95, 1); - transform: scale3d(1.05, .95, 1); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes rubberBand { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 30% { - -webkit-transform: scale3d(1.25, 0.75, 1); - transform: scale3d(1.25, 0.75, 1); - } - - 40% { - -webkit-transform: scale3d(0.75, 1.25, 1); - transform: scale3d(0.75, 1.25, 1); - } - - 50% { - -webkit-transform: scale3d(1.15, 0.85, 1); - transform: scale3d(1.15, 0.85, 1); - } - - 65% { - -webkit-transform: scale3d(.95, 1.05, 1); - transform: scale3d(.95, 1.05, 1); - } - - 75% { - -webkit-transform: scale3d(1.05, .95, 1); - transform: scale3d(1.05, .95, 1); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.rubberBand { - -webkit-animation-name: rubberBand; - animation-name: rubberBand; -} - -@-webkit-keyframes shake { - from, to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - 10%, 30%, 50%, 70%, 90% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 20%, 40%, 60%, 80% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } -} - -@keyframes shake { - from, to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - 10%, 30%, 50%, 70%, 90% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 20%, 40%, 60%, 80% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } -} - -.shake { - -webkit-animation-name: shake; - animation-name: shake; -} - -@-webkit-keyframes headShake { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 6.5% { - -webkit-transform: translateX(-6px) rotateY(-9deg); - transform: translateX(-6px) rotateY(-9deg); - } - - 18.5% { - -webkit-transform: translateX(5px) rotateY(7deg); - transform: translateX(5px) rotateY(7deg); - } - - 31.5% { - -webkit-transform: translateX(-3px) rotateY(-5deg); - transform: translateX(-3px) rotateY(-5deg); - } - - 43.5% { - -webkit-transform: translateX(2px) rotateY(3deg); - transform: translateX(2px) rotateY(3deg); - } - - 50% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes headShake { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 6.5% { - -webkit-transform: translateX(-6px) rotateY(-9deg); - transform: translateX(-6px) rotateY(-9deg); - } - - 18.5% { - -webkit-transform: translateX(5px) rotateY(7deg); - transform: translateX(5px) rotateY(7deg); - } - - 31.5% { - -webkit-transform: translateX(-3px) rotateY(-5deg); - transform: translateX(-3px) rotateY(-5deg); - } - - 43.5% { - -webkit-transform: translateX(2px) rotateY(3deg); - transform: translateX(2px) rotateY(3deg); - } - - 50% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -.headShake { - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - -webkit-animation-name: headShake; - animation-name: headShake; -} - -@-webkit-keyframes swing { - 20% { - -webkit-transform: rotate3d(0, 0, 1, 15deg); - transform: rotate3d(0, 0, 1, 15deg); - } - - 40% { - -webkit-transform: rotate3d(0, 0, 1, -10deg); - transform: rotate3d(0, 0, 1, -10deg); - } - - 60% { - -webkit-transform: rotate3d(0, 0, 1, 5deg); - transform: rotate3d(0, 0, 1, 5deg); - } - - 80% { - -webkit-transform: rotate3d(0, 0, 1, -5deg); - transform: rotate3d(0, 0, 1, -5deg); - } - - to { - -webkit-transform: rotate3d(0, 0, 1, 0deg); - transform: rotate3d(0, 0, 1, 0deg); - } -} - -@keyframes swing { - 20% { - -webkit-transform: rotate3d(0, 0, 1, 15deg); - transform: rotate3d(0, 0, 1, 15deg); - } - - 40% { - -webkit-transform: rotate3d(0, 0, 1, -10deg); - transform: rotate3d(0, 0, 1, -10deg); - } - - 60% { - -webkit-transform: rotate3d(0, 0, 1, 5deg); - transform: rotate3d(0, 0, 1, 5deg); - } - - 80% { - -webkit-transform: rotate3d(0, 0, 1, -5deg); - transform: rotate3d(0, 0, 1, -5deg); - } - - to { - -webkit-transform: rotate3d(0, 0, 1, 0deg); - transform: rotate3d(0, 0, 1, 0deg); - } -} - -.swing { - -webkit-transform-origin: top center; - transform-origin: top center; - -webkit-animation-name: swing; - animation-name: swing; -} - -@-webkit-keyframes tada { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 10%, 20% { - -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - } - - 30%, 50%, 70%, 90% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - } - - 40%, 60%, 80% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes tada { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 10%, 20% { - -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - } - - 30%, 50%, 70%, 90% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - } - - 40%, 60%, 80% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.tada { - -webkit-animation-name: tada; - animation-name: tada; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes wobble { - from { - -webkit-transform: none; - transform: none; - } - - 15% { - -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - } - - 30% { - -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - } - - 45% { - -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - } - - 60% { - -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - } - - 75% { - -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes wobble { - from { - -webkit-transform: none; - transform: none; - } - - 15% { - -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - } - - 30% { - -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - } - - 45% { - -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - } - - 60% { - -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - } - - 75% { - -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.wobble { - -webkit-animation-name: wobble; - animation-name: wobble; -} - -@-webkit-keyframes jello { - from, 11.1%, to { - -webkit-transform: none; - transform: none; - } - - 22.2% { - -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); - transform: skewX(-12.5deg) skewY(-12.5deg); - } - - 33.3% { - -webkit-transform: skewX(6.25deg) skewY(6.25deg); - transform: skewX(6.25deg) skewY(6.25deg); - } - - 44.4% { - -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); - transform: skewX(-3.125deg) skewY(-3.125deg); - } - - 55.5% { - -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); - transform: skewX(1.5625deg) skewY(1.5625deg); - } - - 66.6% { - -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); - transform: skewX(-0.78125deg) skewY(-0.78125deg); - } - - 77.7% { - -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); - transform: skewX(0.390625deg) skewY(0.390625deg); - } - - 88.8% { - -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - } -} - -@keyframes jello { - from, 11.1%, to { - -webkit-transform: none; - transform: none; - } - - 22.2% { - -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); - transform: skewX(-12.5deg) skewY(-12.5deg); - } - - 33.3% { - -webkit-transform: skewX(6.25deg) skewY(6.25deg); - transform: skewX(6.25deg) skewY(6.25deg); - } - - 44.4% { - -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); - transform: skewX(-3.125deg) skewY(-3.125deg); - } - - 55.5% { - -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); - transform: skewX(1.5625deg) skewY(1.5625deg); - } - - 66.6% { - -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); - transform: skewX(-0.78125deg) skewY(-0.78125deg); - } - - 77.7% { - -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); - transform: skewX(0.390625deg) skewY(0.390625deg); - } - - 88.8% { - -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - } -} - -.jello { - -webkit-animation-name: jello; - animation-name: jello; - -webkit-transform-origin: center; - transform-origin: center; -} - -@-webkit-keyframes bounceIn { - from, 20%, 40%, 60%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 20% { - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - 40% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(1.03, 1.03, 1.03); - transform: scale3d(1.03, 1.03, 1.03); - } - - 80% { - -webkit-transform: scale3d(.97, .97, .97); - transform: scale3d(.97, .97, .97); - } - - to { - opacity: 1; - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes bounceIn { - from, 20%, 40%, 60%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 20% { - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - 40% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(1.03, 1.03, 1.03); - transform: scale3d(1.03, 1.03, 1.03); - } - - 80% { - -webkit-transform: scale3d(.97, .97, .97); - transform: scale3d(.97, .97, .97); - } - - to { - opacity: 1; - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.bounceIn { - -webkit-animation-name: bounceIn; - animation-name: bounceIn; -} - -@-webkit-keyframes bounceInDown { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(0, -3000px, 0); - transform: translate3d(0, -3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, 25px, 0); - transform: translate3d(0, 25px, 0); - } - - 75% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, 5px, 0); - transform: translate3d(0, 5px, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes bounceInDown { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(0, -3000px, 0); - transform: translate3d(0, -3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, 25px, 0); - transform: translate3d(0, 25px, 0); - } - - 75% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, 5px, 0); - transform: translate3d(0, 5px, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.bounceInDown { - -webkit-animation-name: bounceInDown; - animation-name: bounceInDown; -} - -@-webkit-keyframes bounceInLeft { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(-3000px, 0, 0); - transform: translate3d(-3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(25px, 0, 0); - transform: translate3d(25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(5px, 0, 0); - transform: translate3d(5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes bounceInLeft { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(-3000px, 0, 0); - transform: translate3d(-3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(25px, 0, 0); - transform: translate3d(25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(5px, 0, 0); - transform: translate3d(5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.bounceInLeft { - -webkit-animation-name: bounceInLeft; - animation-name: bounceInLeft; -} - -@-webkit-keyframes bounceInRight { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(3000px, 0, 0); - transform: translate3d(3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(-25px, 0, 0); - transform: translate3d(-25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(-5px, 0, 0); - transform: translate3d(-5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes bounceInRight { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(3000px, 0, 0); - transform: translate3d(3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(-25px, 0, 0); - transform: translate3d(-25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(-5px, 0, 0); - transform: translate3d(-5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.bounceInRight { - -webkit-animation-name: bounceInRight; - animation-name: bounceInRight; -} - -@-webkit-keyframes bounceInUp { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(0, 3000px, 0); - transform: translate3d(0, 3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - 75% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, -5px, 0); - transform: translate3d(0, -5px, 0); - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes bounceInUp { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(0, 3000px, 0); - transform: translate3d(0, 3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - 75% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, -5px, 0); - transform: translate3d(0, -5px, 0); - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.bounceInUp { - -webkit-animation-name: bounceInUp; - animation-name: bounceInUp; -} - -@-webkit-keyframes bounceOut { - 20% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 50%, 55% { - opacity: 1; - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } -} - -@keyframes bounceOut { - 20% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 50%, 55% { - opacity: 1; - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } -} - -.bounceOut { - -webkit-animation-name: bounceOut; - animation-name: bounceOut; -} - -@-webkit-keyframes bounceOutDown { - 20% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -@keyframes bounceOutDown { - 20% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -.bounceOutDown { - -webkit-animation-name: bounceOutDown; - animation-name: bounceOutDown; -} - -@-webkit-keyframes bounceOutLeft { - 20% { - opacity: 1; - -webkit-transform: translate3d(20px, 0, 0); - transform: translate3d(20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -@keyframes bounceOutLeft { - 20% { - opacity: 1; - -webkit-transform: translate3d(20px, 0, 0); - transform: translate3d(20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -.bounceOutLeft { - -webkit-animation-name: bounceOutLeft; - animation-name: bounceOutLeft; -} - -@-webkit-keyframes bounceOutRight { - 20% { - opacity: 1; - -webkit-transform: translate3d(-20px, 0, 0); - transform: translate3d(-20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -@keyframes bounceOutRight { - 20% { - opacity: 1; - -webkit-transform: translate3d(-20px, 0, 0); - transform: translate3d(-20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -.bounceOutRight { - -webkit-animation-name: bounceOutRight; - animation-name: bounceOutRight; -} - -@-webkit-keyframes bounceOutUp { - 20% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, 20px, 0); - transform: translate3d(0, 20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -@keyframes bounceOutUp { - 20% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, 20px, 0); - transform: translate3d(0, 20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -.bounceOutUp { - -webkit-animation-name: bounceOutUp; - animation-name: bounceOutUp; -} - -@-webkit-keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -@keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -.fadeIn { - -webkit-animation-name: fadeIn; - animation-name: fadeIn; -} - -@-webkit-keyframes fadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInDown { - -webkit-animation-name: fadeInDown; - animation-name: fadeInDown; -} - -@-webkit-keyframes fadeInDownBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInDownBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInDownBig { - -webkit-animation-name: fadeInDownBig; - animation-name: fadeInDownBig; -} - -@-webkit-keyframes fadeInLeft { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInLeft { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInLeft { - -webkit-animation-name: fadeInLeft; - animation-name: fadeInLeft; -} - -@-webkit-keyframes fadeInLeftBig { - from { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInLeftBig { - from { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInLeftBig { - -webkit-animation-name: fadeInLeftBig; - animation-name: fadeInLeftBig; -} - -@-webkit-keyframes fadeInRight { - from { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInRight { - from { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInRight { - -webkit-animation-name: fadeInRight; - animation-name: fadeInRight; -} - -@-webkit-keyframes fadeInRightBig { - from { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInRightBig { - from { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInRightBig { - -webkit-animation-name: fadeInRightBig; - animation-name: fadeInRightBig; -} - -@-webkit-keyframes fadeInUp { - from { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInUp { - from { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInUp { - -webkit-animation-name: fadeInUp; - animation-name: fadeInUp; -} - -@-webkit-keyframes fadeInUpBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInUpBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInUpBig { - -webkit-animation-name: fadeInUpBig; - animation-name: fadeInUpBig; -} - -@-webkit-keyframes fadeOut { - from { - opacity: 1; - } - - to { - opacity: 0; - } -} - -@keyframes fadeOut { - from { - opacity: 1; - } - - to { - opacity: 0; - } -} - -.fadeOut { - -webkit-animation-name: fadeOut; - animation-name: fadeOut; -} - -@-webkit-keyframes fadeOutDown { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -@keyframes fadeOutDown { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -.fadeOutDown { - -webkit-animation-name: fadeOutDown; - animation-name: fadeOutDown; -} - -@-webkit-keyframes fadeOutDownBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -@keyframes fadeOutDownBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -.fadeOutDownBig { - -webkit-animation-name: fadeOutDownBig; - animation-name: fadeOutDownBig; -} - -@-webkit-keyframes fadeOutLeft { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -@keyframes fadeOutLeft { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -.fadeOutLeft { - -webkit-animation-name: fadeOutLeft; - animation-name: fadeOutLeft; -} - -@-webkit-keyframes fadeOutLeftBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -@keyframes fadeOutLeftBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -.fadeOutLeftBig { - -webkit-animation-name: fadeOutLeftBig; - animation-name: fadeOutLeftBig; -} - -@-webkit-keyframes fadeOutRight { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -@keyframes fadeOutRight { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -.fadeOutRight { - -webkit-animation-name: fadeOutRight; - animation-name: fadeOutRight; -} - -@-webkit-keyframes fadeOutRightBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -@keyframes fadeOutRightBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -.fadeOutRightBig { - -webkit-animation-name: fadeOutRightBig; - animation-name: fadeOutRightBig; -} - -@-webkit-keyframes fadeOutUp { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -@keyframes fadeOutUp { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -.fadeOutUp { - -webkit-animation-name: fadeOutUp; - animation-name: fadeOutUp; -} - -@-webkit-keyframes fadeOutUpBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -@keyframes fadeOutUpBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -.fadeOutUpBig { - -webkit-animation-name: fadeOutUpBig; - animation-name: fadeOutUpBig; -} - -@-webkit-keyframes flip { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 40% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 50% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 80% { - -webkit-transform: perspective(400px) scale3d(.95, .95, .95); - transform: perspective(400px) scale3d(.95, .95, .95); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } -} - -@keyframes flip { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 40% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 50% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 80% { - -webkit-transform: perspective(400px) scale3d(.95, .95, .95); - transform: perspective(400px) scale3d(.95, .95, .95); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } -} - -.animated.flip { - -webkit-backface-visibility: visible; - backface-visibility: visible; - -webkit-animation-name: flip; - animation-name: flip; -} - -@-webkit-keyframes flipInX { - from { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -@keyframes flipInX { - from { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -.flipInX { - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipInX; - animation-name: flipInX; -} - -@-webkit-keyframes flipInY { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -@keyframes flipInY { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -.flipInY { - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipInY; - animation-name: flipInY; -} - -@-webkit-keyframes flipOutX { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - opacity: 0; - } -} - -@keyframes flipOutX { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - opacity: 0; - } -} - -.flipOutX { - -webkit-animation-name: flipOutX; - animation-name: flipOutX; - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; -} - -@-webkit-keyframes flipOutY { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - opacity: 0; - } -} - -@keyframes flipOutY { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - opacity: 0; - } -} - -.flipOutY { - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipOutY; - animation-name: flipOutY; -} - -@-webkit-keyframes lightSpeedIn { - from { - -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); - transform: translate3d(100%, 0, 0) skewX(-30deg); - opacity: 0; - } - - 60% { - -webkit-transform: skewX(20deg); - transform: skewX(20deg); - opacity: 1; - } - - 80% { - -webkit-transform: skewX(-5deg); - transform: skewX(-5deg); - opacity: 1; - } - - to { - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes lightSpeedIn { - from { - -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); - transform: translate3d(100%, 0, 0) skewX(-30deg); - opacity: 0; - } - - 60% { - -webkit-transform: skewX(20deg); - transform: skewX(20deg); - opacity: 1; - } - - 80% { - -webkit-transform: skewX(-5deg); - transform: skewX(-5deg); - opacity: 1; - } - - to { - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.lightSpeedIn { - -webkit-animation-name: lightSpeedIn; - animation-name: lightSpeedIn; - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; -} - -@-webkit-keyframes lightSpeedOut { - from { - opacity: 1; - } - - to { - -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); - transform: translate3d(100%, 0, 0) skewX(30deg); - opacity: 0; - } -} - -@keyframes lightSpeedOut { - from { - opacity: 1; - } - - to { - -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); - transform: translate3d(100%, 0, 0) skewX(30deg); - opacity: 0; - } -} - -.lightSpeedOut { - -webkit-animation-name: lightSpeedOut; - animation-name: lightSpeedOut; - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; -} - -@-webkit-keyframes rotateIn { - from { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, -200deg); - transform: rotate3d(0, 0, 1, -200deg); - opacity: 0; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateIn { - from { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, -200deg); - transform: rotate3d(0, 0, 1, -200deg); - opacity: 0; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateIn { - -webkit-animation-name: rotateIn; - animation-name: rotateIn; -} - -@-webkit-keyframes rotateInDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInDownLeft { - -webkit-animation-name: rotateInDownLeft; - animation-name: rotateInDownLeft; -} - -@-webkit-keyframes rotateInDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInDownRight { - -webkit-animation-name: rotateInDownRight; - animation-name: rotateInDownRight; -} - -@-webkit-keyframes rotateInUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInUpLeft { - -webkit-animation-name: rotateInUpLeft; - animation-name: rotateInUpLeft; -} - -@-webkit-keyframes rotateInUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -90deg); - transform: rotate3d(0, 0, 1, -90deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -90deg); - transform: rotate3d(0, 0, 1, -90deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInUpRight { - -webkit-animation-name: rotateInUpRight; - animation-name: rotateInUpRight; -} - -@-webkit-keyframes rotateOut { - from { - -webkit-transform-origin: center; - transform-origin: center; - opacity: 1; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, 200deg); - transform: rotate3d(0, 0, 1, 200deg); - opacity: 0; - } -} - -@keyframes rotateOut { - from { - -webkit-transform-origin: center; - transform-origin: center; - opacity: 1; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, 200deg); - transform: rotate3d(0, 0, 1, 200deg); - opacity: 0; - } -} - -.rotateOut { - -webkit-animation-name: rotateOut; - animation-name: rotateOut; -} - -@-webkit-keyframes rotateOutDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } -} - -@keyframes rotateOutDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } -} - -.rotateOutDownLeft { - -webkit-animation-name: rotateOutDownLeft; - animation-name: rotateOutDownLeft; -} - -@-webkit-keyframes rotateOutDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -@keyframes rotateOutDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -.rotateOutDownRight { - -webkit-animation-name: rotateOutDownRight; - animation-name: rotateOutDownRight; -} - -@-webkit-keyframes rotateOutUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -@keyframes rotateOutUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -.rotateOutUpLeft { - -webkit-animation-name: rotateOutUpLeft; - animation-name: rotateOutUpLeft; -} - -@-webkit-keyframes rotateOutUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 90deg); - transform: rotate3d(0, 0, 1, 90deg); - opacity: 0; - } -} - -@keyframes rotateOutUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 90deg); - transform: rotate3d(0, 0, 1, 90deg); - opacity: 0; - } -} - -.rotateOutUpRight { - -webkit-animation-name: rotateOutUpRight; - animation-name: rotateOutUpRight; -} - -@-webkit-keyframes hinge { - 0% { - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 20%, 60% { - -webkit-transform: rotate3d(0, 0, 1, 80deg); - transform: rotate3d(0, 0, 1, 80deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 40%, 80% { - -webkit-transform: rotate3d(0, 0, 1, 60deg); - transform: rotate3d(0, 0, 1, 60deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - opacity: 1; - } - - to { - -webkit-transform: translate3d(0, 700px, 0); - transform: translate3d(0, 700px, 0); - opacity: 0; - } -} - -@keyframes hinge { - 0% { - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 20%, 60% { - -webkit-transform: rotate3d(0, 0, 1, 80deg); - transform: rotate3d(0, 0, 1, 80deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 40%, 80% { - -webkit-transform: rotate3d(0, 0, 1, 60deg); - transform: rotate3d(0, 0, 1, 60deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - opacity: 1; - } - - to { - -webkit-transform: translate3d(0, 700px, 0); - transform: translate3d(0, 700px, 0); - opacity: 0; - } -} - -.hinge { - -webkit-animation-name: hinge; - animation-name: hinge; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes rollIn { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes rollIn { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.rollIn { - -webkit-animation-name: rollIn; - animation-name: rollIn; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes rollOut { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - } -} - -@keyframes rollOut { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - } -} - -.rollOut { - -webkit-animation-name: rollOut; - animation-name: rollOut; -} - -@-webkit-keyframes zoomIn { - from { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 50% { - opacity: 1; - } -} - -@keyframes zoomIn { - from { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 50% { - opacity: 1; - } -} - -.zoomIn { - -webkit-animation-name: zoomIn; - animation-name: zoomIn; -} - -@-webkit-keyframes zoomInDown { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInDown { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInDown { - -webkit-animation-name: zoomInDown; - animation-name: zoomInDown; -} - -@-webkit-keyframes zoomInLeft { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInLeft { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInLeft { - -webkit-animation-name: zoomInLeft; - animation-name: zoomInLeft; -} - -@-webkit-keyframes zoomInRight { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInRight { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInRight { - -webkit-animation-name: zoomInRight; - animation-name: zoomInRight; -} - -@-webkit-keyframes zoomInUp { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInUp { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInUp { - -webkit-animation-name: zoomInUp; - animation-name: zoomInUp; -} - -@-webkit-keyframes zoomOut { - from { - opacity: 1; - } - - 50% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - to { - opacity: 0; - } -} - -@keyframes zoomOut { - from { - opacity: 1; - } - - 50% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - to { - opacity: 0; - } -} - -.zoomOut { - -webkit-animation-name: zoomOut; - animation-name: zoomOut; -} - -@-webkit-keyframes zoomOutDown { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomOutDown { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomOutDown { - -webkit-animation-name: zoomOutDown; - animation-name: zoomOutDown; -} - -@-webkit-keyframes zoomOutLeft { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); - transform: scale(.1) translate3d(-2000px, 0, 0); - -webkit-transform-origin: left center; - transform-origin: left center; - } -} - -@keyframes zoomOutLeft { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); - transform: scale(.1) translate3d(-2000px, 0, 0); - -webkit-transform-origin: left center; - transform-origin: left center; - } -} - -.zoomOutLeft { - -webkit-animation-name: zoomOutLeft; - animation-name: zoomOutLeft; -} - -@-webkit-keyframes zoomOutRight { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(2000px, 0, 0); - transform: scale(.1) translate3d(2000px, 0, 0); - -webkit-transform-origin: right center; - transform-origin: right center; - } -} - -@keyframes zoomOutRight { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(2000px, 0, 0); - transform: scale(.1) translate3d(2000px, 0, 0); - -webkit-transform-origin: right center; - transform-origin: right center; - } -} - -.zoomOutRight { - -webkit-animation-name: zoomOutRight; - animation-name: zoomOutRight; -} - -@-webkit-keyframes zoomOutUp { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomOutUp { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomOutUp { - -webkit-animation-name: zoomOutUp; - animation-name: zoomOutUp; -} - -@-webkit-keyframes slideInDown { - from { - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInDown { - from { - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInDown { - -webkit-animation-name: slideInDown; - animation-name: slideInDown; -} - -@-webkit-keyframes slideInLeft { - from { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInLeft { - from { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInLeft { - -webkit-animation-name: slideInLeft; - animation-name: slideInLeft; -} - -@-webkit-keyframes slideInRight { - from { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInRight { - from { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInRight { - -webkit-animation-name: slideInRight; - animation-name: slideInRight; -} - -@-webkit-keyframes slideInUp { - from { - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInUp { - from { - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInUp { - -webkit-animation-name: slideInUp; - animation-name: slideInUp; -} - -@-webkit-keyframes slideOutDown { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -@keyframes slideOutDown { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -.slideOutDown { - -webkit-animation-name: slideOutDown; - animation-name: slideOutDown; -} - -@-webkit-keyframes slideOutLeft { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -@keyframes slideOutLeft { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -.slideOutLeft { - -webkit-animation-name: slideOutLeft; - animation-name: slideOutLeft; -} - -@-webkit-keyframes slideOutRight { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -@keyframes slideOutRight { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -.slideOutRight { - -webkit-animation-name: slideOutRight; - animation-name: slideOutRight; -} - -@-webkit-keyframes slideOutUp { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -@keyframes slideOutUp { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -.slideOutUp { - -webkit-animation-name: slideOutUp; - animation-name: slideOutUp; -} diff --git a/quartz-manager-backend/src/main/resources/static/css/dashboard-bootstrap.css b/quartz-manager-backend/src/main/resources/static/css/dashboard-bootstrap.css deleted file mode 100644 index de31574..0000000 --- a/quartz-manager-backend/src/main/resources/static/css/dashboard-bootstrap.css +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Base structure - */ - -/* Move down content because we have a fixed navbar that is 50px tall */ -body { - padding-top: 50px; -} - - -/* - * Global add-ons - */ - -.sub-header { - padding-bottom: 10px; - border-bottom: 1px solid #eee; -} - -/* - * Top navigation - * Hide default border to remove 1px line. - */ -.navbar-fixed-top { - border: 0; -} - -/* - * Sidebar - */ - -/* Hide for mobile, show later */ -.sidebar { - display: none; -} -@media (min-width: 768px) { - .sidebar { - position: fixed; - top: 51px; - bottom: 0; - left: 0; - z-index: 1000; - display: block; - padding: 20px; - overflow-x: hidden; - overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ - background-color: #f5f5f5; - border-right: 1px solid #eee; - } -} - -/* Sidebar navigation */ -.nav-sidebar { - margin-right: -21px; /* 20px padding + 1px border */ - margin-bottom: 20px; - margin-left: -20px; -} -.nav-sidebar > li > a { - padding-right: 20px; - padding-left: 20px; -} -.nav-sidebar > .active > a, -.nav-sidebar > .active > a:hover, -.nav-sidebar > .active > a:focus { - color: #fff; - background-color: #428bca; -} - - -/* - * Main content - */ - -.main { - padding: 20px; -} -@media (min-width: 768px) { - .main { - padding-right: 40px; - padding-left: 40px; - } -} -.main .page-header { - margin-top: 0; -} - - -/* - * Placeholder dashboard ideas - */ - -.placeholders { - margin-bottom: 30px; - text-align: center; -} -.placeholders h4 { - margin-bottom: 0; -} -.placeholder { - margin-bottom: 20px; -} -.placeholder img { - display: inline-block; - border-radius: 50%; -} \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/css/scheduler.css b/quartz-manager-backend/src/main/resources/static/css/scheduler.css deleted file mode 100644 index 80e8eba..0000000 --- a/quartz-manager-backend/src/main/resources/static/css/scheduler.css +++ /dev/null @@ -1,40 +0,0 @@ -.infoInNavbar{ - color: white; - line-height: 20px; - display: block; - padding: 13px 15px; - font-size: 14px; -} - -.widget-panel{ - padding: 0; -} - -.center{ - text-align: center; -} - -.green{ - color: green; -} - -.red{ - color: red; -} - -.dark-yellow{ - color: #d8dc25; -} - -#schedulerControllerBtn{ - cursor: pointer; -} - -.large-btn{ - width: 200px; -} - -.firstLog{ - -webkit-animation-duration: .25s; - -moz-animation-duration: .25s; -} \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/css/signin.css b/quartz-manager-backend/src/main/resources/static/css/signin.css deleted file mode 100644 index 7c3e522..0000000 --- a/quartz-manager-backend/src/main/resources/static/css/signin.css +++ /dev/null @@ -1,41 +0,0 @@ -body { - padding-top: 40px; - padding-bottom: 40px; - background-color: #eee; -} - -.form-signin { - max-width: 330px; - padding: 15px; - margin: 0 auto; -} - -.form-signin .form-signin-heading, -.form-signin .checkbox { - margin-bottom: 10px; -} -.form-signin .checkbox { - font-weight: normal; -} -.form-signin .form-control { - position: relative; - height: auto; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 10px; - font-size: 16px; -} -.form-signin .form-control:focus { - z-index: 2; -} -.form-signin input[type="email"] { - margin-bottom: -1px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.form-signin input[type="password"] { - margin-bottom: 10px; - border-top-left-radius: 0; - border-top-right-radius: 0; -} diff --git a/quartz-manager-backend/src/main/resources/static/js/app/app.js b/quartz-manager-backend/src/main/resources/static/js/app/app.js deleted file mode 100644 index c1ee36e..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/app.js +++ /dev/null @@ -1 +0,0 @@ -var schedulerApp = angular.module('schedulerApp', ['starter', 'configurator', 'ff-websocket', 'progress', 'http-auth-interceptor', 'authenticationComp']); diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/authentication/authentication.js b/quartz-manager-backend/src/main/resources/static/js/app/components/authentication/authentication.js deleted file mode 100644 index ccef49c..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/authentication/authentication.js +++ /dev/null @@ -1,134 +0,0 @@ -'use strict'; -var authenticationComp = angular.module('authenticationComp', ['http-auth-interceptor']); - - -/**********************************************************************************/ -//SESSION REFRESH -authenticationComp.directive('sessionRefresh', - ['authService','$rootScope', '$http', '$location', - 'LoginService', function(authService, $rootScope, $http, $location, LoginService) { -var openedLoginDialog = false; -return{ - restrict: 'AC', - link: function(scope, elem, attrs) { - - var lastRefreshTimeForAnonymous; - - $rootScope.$on('event:auth-loginRequired', function(e, arg) { - //show login dialog - arg.ajaxLoginError = arg.ajaxLoginError || ""; - - attrs.title = attrs.title || "Session Expired"; - attrs.commonErrorLabel = attrs.commonErrorLabel || "Authenticaion failed:"; - attrs.wrongPasswordMsg = attrs.wrongPasswordMsg || "Wrong Password! Please, re-try."; - attrs.serverConnectionFailedMsg = attrs.serverConnectionFailedMsg || "Server connection failed, please try later"; - - var username = attrs.username || "admin"; - - if(openedLoginDialog) - return; - - openedLoginDialog = true; - bootbox.dialog({ - message: "
" + - "

Login

"+ - "" + arg.ajaxLoginError + " "+ - "" + - "" + - "" + - "" + - "" + - ""+ - "" + - "
" + - "
", - title: attrs.title, - onEscape: function() { - openedLoginDialog = false; - }, - buttons:{ - main:{ - label: "Ok", - className: "btn-primary", - callback: function() { - openedLoginDialog = false; - var postData = {}; - postData.ajaxUsername = $('#ajaxLoginUsername').val(); - postData.ajaxPassword = $('#ajaxLoginPassword').val(); - - var loginCompleted = LoginService.doLogin(postData.ajaxUsername, postData.ajaxPassword, true); - - loginCompleted - .then(function(){ - authService.loginConfirmed(); - },function(msgError){ - $rootScope.$emit('event:auth-loginRequired', {ajaxLoginError: msgError}); - }); - } - }, - }, - }); - - $('#refreshSessionDialog').closest('.modal').css('z-index', '9001'); - }); - - $rootScope.$on('event:auth-loginConfirmed', function() { - //nothing - }); - - } - }; -}]); - -/**********************************************************************************/ -//LOGIN SERVICE -authenticationComp.service('LoginService', ['$q', '$http', '$window', '$log', function($q, $http, $window, $log){ - - this.doLogin = function(username, password, ignoreAuthModule){ - ignoreAuthModule = ignoreAuthModule || false; - - var ajaxLoginDone = $q.defer(); - - var postData = {}; - postData.ajaxUsername = username; - postData.ajaxPassword = password; - - $http({ - method: 'POST', - url: 'ajaxLogin', - headers: {'Content-Type': 'application/x-www-form-urlencoded'}, - transformRequest: function(obj) { - var str = []; - for(var p in obj) - str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); - return str.join("&"); - }, - data: postData, - ignoreAuthModule : ignoreAuthModule - }) - .then(function (res) { - if(res.status == 200){ - for(var i in res.cookies) - if(res.cookies[i] != null) - document.cookie = res.cookies[i]; - ajaxLoginDone.resolve(res.loggedUser); - } - else - ajaxLoginDone.reject(res.msgError); - }, function(data, status){ - ajaxLoginDone.reject(); - }); - - return ajaxLoginDone.promise; - }; - - -}]); diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/configurator/configurator-directives.js b/quartz-manager-backend/src/main/resources/static/js/app/components/configurator/configurator-directives.js deleted file mode 100644 index 06ec467..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/configurator/configurator-directives.js +++ /dev/null @@ -1,28 +0,0 @@ -angular.module('configurator') -.directive('configForm', function(){ - - var configBackup = {triggerPerDay : '', maxCount : ''}; - - return{ - restrict: 'E', - controller : ['$scope', '$http', function($scope, $http){ - $http.get('scheduler/config').then(function(res){ - $scope.config = res.data; - configBackup = res.data; - }); - - $scope.submitConfig = function (){ - $http.post('scheduler/config', $scope.config) - .then(function(res){ - configBackup = $scope.config; - }, function(error){ - $scope.congif = configBackup; - }); - }; - - }], - templateUrl : 'templates/manager/config-form.html', - link : function($scope){ - } - }; -}); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/configurator/configurator-module.js b/quartz-manager-backend/src/main/resources/static/js/app/components/configurator/configurator-module.js deleted file mode 100644 index 1dd35de..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/configurator/configurator-module.js +++ /dev/null @@ -1 +0,0 @@ -var starterModule = angular.module('configurator', []); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/logs-directive.js b/quartz-manager-backend/src/main/resources/static/js/app/components/progress/logs-directive.js deleted file mode 100644 index 603de69..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/logs-directive.js +++ /dev/null @@ -1,51 +0,0 @@ -angular.module('progress') -.directive('logsPanel', ['LogService', function(LogService){ - - var MAX_LOGS = 10; - - return{ - restrict: 'E', - controller : ['$scope', '$rootScope', '$http', function($scope, $rootScope, $http){ - - $scope.logs = new Array(); - - var _showNewLog = function(logRecord){ - if($scope.logs.length > MAX_LOGS) - $scope.logs.pop(); - - var logItem = {}; - logItem.time = logRecord.date; - logItem.type = logRecord.type; - logItem.msg = logRecord.message; - logItem.threadName = logRecord.threadName; - - $scope.logs.unshift(logItem); - }; - - var _refreshSession = function(){ - $http({ - method : 'GET', - url : 'session/refresh' - }); - }; - - var _handleNewMsgFromLogWebsocket = function(receivedMsg){ - if(receivedMsg.type == 'SUCCESS') - _showNewLo g(receivedMsg.message); - else if(receivedMsg.type == 'ERROR') - _refreshSession(); //if websocket has been closed for session expiration, try to refresh it - }; - - - LogService.receive().then(null, null, function(receivedMsg){ - _handleNewMsgFromLogWebsocket(receivedMsg); - }); - - $rootScope.$on('event:auth-loginConfirmed', function() { - //REST API login succeeded, now open websocket connection again - LogService.reconnectNow(); - }); - }], - templateUrl : 'templates/manager/logs-panel.html' - }; -}]); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/logs-service.js b/quartz-manager-backend/src/main/resources/static/js/app/components/progress/logs-service.js deleted file mode 100644 index 1f71352..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/logs-service.js +++ /dev/null @@ -1,10 +0,0 @@ -angular.module('progress') -.service('LogService',['WebsocketServiceFactory', function(WebsocketServiceFactory){ - - var logServiceParams = { - SOCKET_URL : '/quartz-manager/logs', - TOPIC_NAME : '/topic/logs' - }; - - return WebsocketServiceFactory.create(logServiceParams); -}]); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/progress-directive.js b/quartz-manager-backend/src/main/resources/static/js/app/components/progress/progress-directive.js deleted file mode 100644 index f204aa8..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/progress-directive.js +++ /dev/null @@ -1,25 +0,0 @@ -angular.module('progress') - .directive('progressPanel', [ 'ProgressService', function(ProgressService) { - - return { - restrict : 'E', - controller : [ '$scope', '$rootScope', function($scope, $rootScope) { - - ProgressService.receive().then(null, null, function(receivedMsg) { - if (receivedMsg.type == 'SUCCESS') { - var newStatus = receivedMsg.message; - $scope.progress = newStatus; - $scope.percentageStr = $scope.progress.percentage + '%'; - } - }); - - $rootScope.$on('event:auth-loginConfirmed', function() { - //re-open websocket connection after REST API login - ProgressService.reconnectNow(); - }); - - }], - - templateUrl : 'templates/manager/progress-panel.html' - }; - } ]); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/progress-module.js b/quartz-manager-backend/src/main/resources/static/js/app/components/progress/progress-module.js deleted file mode 100644 index 2083de6..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/progress-module.js +++ /dev/null @@ -1 +0,0 @@ -var starterModule = angular.module('progress', []); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/progress-service.js b/quartz-manager-backend/src/main/resources/static/js/app/components/progress/progress-service.js deleted file mode 100644 index f62772c..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/progress/progress-service.js +++ /dev/null @@ -1,10 +0,0 @@ -angular.module('progress') -.service('ProgressService',['WebsocketServiceFactory', function(WebsocketServiceFactory){ - - var progressServiceParams = { - SOCKET_URL : '/quartz-manager/progress', - TOPIC_NAME : '/topic/progress' - }; - - return WebsocketServiceFactory.create(progressServiceParams); -}]); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/starter/starter-directives.js b/quartz-manager-backend/src/main/resources/static/js/app/components/starter/starter-directives.js deleted file mode 100644 index 09d8e19..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/starter/starter-directives.js +++ /dev/null @@ -1,82 +0,0 @@ -angular.module('starter') -.directive('starterBtn', function(){ - - return{ - restrict: 'EA', - scope : { - schedulerState : '@initState' - }, - controller : ['$scope', '$http', function($scope, $http){ - - var startScheduler = function(){ - var onStartingSuccess = function(res){ - $scope.schedulerState = 'running'; - }; - var onStartingError = function(res){ - console.log(JSON.stringify(res)); - }; - $http.get('scheduler/run').then(onStartingSuccess, onStartingError); - }; - - var stopScheduler = function(){ - var onStoppingSuccess = function(res){ - $scope.schedulerState = 'stopped'; - }; - var onStoppingError = function(res){ - console.log(JSON.stringify(res)); - }; - $http.get('scheduler/stop').then(onStoppingSuccess, onStoppingError); - }; - - var pauseScheduler = function(){ - var onSuccess = function(res){ - $scope.schedulerState = 'paused'; - }; - var onError = function(res){ - console.log(JSON.stringify(res)); - }; - $http.get('scheduler/pause').then(onSuccess, onError); - }; - - var resumeScheduler = function(){ - var onSuccess = function(res){ - $scope.schedulerState = 'running'; - }; - var onError = function(res){ - console.log(JSON.stringify(res)); - }; - $http.get('scheduler/resume').then(onSuccess, onError); - }; - - $scope.stop = function(){ - if($scope.schedulerState != 'stopped') - stopScheduler(); - }; - - $scope.startOrPause = function(){ - switch ($scope.schedulerState) { - case 'running': pauseScheduler(); - break; - case 'paused': resumeScheduler(); - break; - default: - startScheduler(); - break; - } - }; - - }], - template: - '' -// + '' - }; -}); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/starter/starter-module.js b/quartz-manager-backend/src/main/resources/static/js/app/components/starter/starter-module.js deleted file mode 100644 index bfc3f68..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/starter/starter-module.js +++ /dev/null @@ -1 +0,0 @@ -var starterModule = angular.module('starter', []); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/websocket/websocket-factory.js b/quartz-manager-backend/src/main/resources/static/js/app/components/websocket/websocket-factory.js deleted file mode 100644 index eba4749..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/websocket/websocket-factory.js +++ /dev/null @@ -1,101 +0,0 @@ -angular.module('ff-websocket') -.factory('WebsocketServiceFactory',['$q', '$timeout', function($q, $timeout){ - - return{ - create : function(options){ - return new BaseSocketService(options) - } - }; - - function BaseSocketService(options){ - - var that = this; - - var defaultOpt = { - SOCKET_URL : '', - TOPIC_NAME : '', - BROKER_NAME : '', - RECONNECT_TIMEOUT : 30000 - }; - that.options = angular.extend(defaultOpt, options); - - - var _deferred = $q.defer(); - var _messageIds = []; - var _socket = { - client: null, - stomp: null - }; - - var getMessage = function(data) { - var out = {}; - out.type = 'SUCCESS'; - out.message = JSON.parse(data.body); - out.headers = {}; - out.headers.messageId = data.headers["message-id"]; - - if ($.contains(_messageIds, out.headers.messageId)) { - out.self = true; - _messageIds = _.remove(_messageIds, out.headers.messageId); - } - return out; - }; - - that.reconnectionPromise = null; - - that.scheduleReconnection = function() { - that.reconnectionPromise = $timeout(function() { - console.log("Socket reconnecting... (if it fails, next attempt in " + that.options.RECONNECT_TIMEOUT + " msec)"); - _initialize(); - }, that.options.RECONNECT_TIMEOUT); - }; - - that.reconnectNow = function(){ - _socket.stomp.disconnect(); - if(that.reconnectionPromise && that.reconnectionPromise.cancel) - that.reconnectionPromise.cancel(); - _initialize(); - }; - - var _errorCallback = function(errorMsg){ - var out = {}; - out.type = 'ERROR'; - out.message = errorMsg; - _deferred.notify(out); - that.scheduleReconnection(); - }; - - var _startListener = function(frame){ - console.log('Connected: ' + frame); - _socket.stomp.subscribe(that.options.TOPIC_NAME, function(data){ - _deferred.notify(getMessage(data)); - }); - }; - - var _initialize = function(){ - _socket.client = new SockJS(that.options.SOCKET_URL); - _socket.stomp = Stomp.over(_socket.client); - _socket.stomp.connect({}, _startListener, _errorCallback); - _socket.stomp.onclose = that.scheduleReconnection; - }; - - that.receive = function(){ - return _deferred.promise; - }; - - that.send = function(message) { - var id = Math.floor(Math.random() * 1000000); - _socket.stomp.send(that.options.BROKER_NAME, { - priority: 9 - }, JSON.stringify({ - message: message, - id: id - })); - _messageIds.push(id); - }; - - _initialize(); - } - - -}]); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/app/components/websocket/websocket-module.js b/quartz-manager-backend/src/main/resources/static/js/app/components/websocket/websocket-module.js deleted file mode 100644 index 8b7f587..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/app/components/websocket/websocket-module.js +++ /dev/null @@ -1 +0,0 @@ -var socketModule = angular.module('ff-websocket', []); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/lib/bootbox.min.js b/quartz-manager-backend/src/main/resources/static/js/lib/bootbox.min.js deleted file mode 100644 index 0dc0cbd..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/lib/bootbox.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * bootbox.js v4.4.0 - * - * http://bootboxjs.com/license.txt - */ -!function(a,b){"use strict";"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.bootbox=b(a.jQuery)}(this,function a(b,c){"use strict";function d(a){var b=q[o.locale];return b?b[a]:q.en[a]}function e(a,c,d){a.stopPropagation(),a.preventDefault();var e=b.isFunction(d)&&d.call(c,a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a,c){var d=0;b.each(a,function(a,b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},o,a),a.buttons||(a.buttons={}),c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(e.className=2>=d&&f===d-1?"btn-primary":"btn-default")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"",header:"",footer:"",closeButton:"",form:"
",inputs:{text:"",textarea:"",email:"",select:"",checkbox:"
",date:"",time:"",number:"",password:""}},o={locale:"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback.call(this):!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,!1)},a.buttons.confirm.callback=function(){return a.callback.call(this,!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback.call(this,c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!b.isArray(k))throw new Error("Please pass an array of input options");if(!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b("").attr("label",d.group)),e=o[d.group]),e.append("")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var q=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b("
"),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(q,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),a.maxlength&&h.attr("maxlength",a.maxlength),f.append(h),f.on("submit",function(a){a.preventDefault(),a.stopPropagation(),e.find(".btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var d=b(n.dialog),f=d.find(".modal-dialog"),i=d.find(".modal-body"),j=a.buttons,k="",l={onEscape:a.onEscape};if(b.fn.modal===c)throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details.");if(g(j,function(a,b){k+="",l[a]=b.callback}),i.find(".bootbox-body").html(a.message),a.animate===!0&&d.addClass("fade"),a.className&&d.addClass(a.className),"large"===a.size?f.addClass("modal-lg"):"small"===a.size&&f.addClass("modal-sm"),a.title&&i.before(n.header),a.closeButton){var m=b(n.closeButton);a.title?d.find(".modal-header").prepend(m):m.css("margin-top","-10px").prependTo(i)}return a.title&&d.find(".modal-title").html(a.title),k.length&&(i.after(n.footer),d.find(".modal-footer").html(k)),d.on("hidden.bs.modal",function(a){a.target===this&&d.remove()}),d.on("shown.bs.modal",function(){d.find(".btn-primary:first").focus()}),"static"!==a.backdrop&&d.on("click.dismiss.bs.modal",function(a){d.children(".modal-backdrop").length&&(a.currentTarget=d.children(".modal-backdrop").get(0)),a.target===a.currentTarget&&d.trigger("escape.close.bb")}),d.on("escape.close.bb",function(a){l.onEscape&&e(a,d,l.onEscape)}),d.on("click",".modal-footer button",function(a){var c=b(this).data("bb-handler");e(a,d,l[c])}),d.on("click",".bootbox-close-button",function(a){e(a,d,l.onEscape)}),d.on("keyup",function(a){27===a.which&&d.trigger("escape.close.bb")}),b(a.container).append(d),d.modal({backdrop:a.backdrop?"static":!1,keyboard:!1,show:!1}),a.show&&d.modal("show"),d},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){return b(".bootbox").modal("hide"),p};var q={bg_BG:{OK:"Ок",CANCEL:"Отказ",CONFIRM:"Потвърждавам"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},cs:{OK:"OK",CANCEL:"Zrušit",CONFIRM:"Potvrdit"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},el:{OK:"Εντάξει",CANCEL:"Ακύρωση",CONFIRM:"Επιβεβαίωση"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},et:{OK:"OK",CANCEL:"Katkesta",CONFIRM:"OK"},fa:{OK:"قبول",CANCEL:"لغو",CONFIRM:"تایید"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},hu:{OK:"OK",CANCEL:"Mégsem",CONFIRM:"Megerősít"},hr:{OK:"OK",CANCEL:"Odustani",CONFIRM:"Potvrdi"},id:{OK:"OK",CANCEL:"Batal",CONFIRM:"OK"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},ja:{OK:"OK",CANCEL:"キャンセル",CONFIRM:"確認"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},pt:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Confirmar"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sq:{OK:"OK",CANCEL:"Anulo",CONFIRM:"Prano"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},th:{OK:"ตกลง",CANCEL:"ยกเลิก",CONFIRM:"ยืนยัน"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.addLocale=function(a,c){return b.each(["OK","CANCEL","CONFIRM"],function(a,b){if(!c[b])throw new Error("Please supply a translation for '"+b+"'")}),q[a]={OK:c.OK,CANCEL:c.CANCEL,CONFIRM:c.CONFIRM},p},p.removeLocale=function(a){return delete q[a],p},p.setLocale=function(a){return p.setDefaults("locale",a)},p.init=function(c){return a(c||b)},p}); \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/lib/http-auth-interceptor.js b/quartz-manager-backend/src/main/resources/static/js/lib/http-auth-interceptor.js deleted file mode 100644 index 76a3181..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/lib/http-auth-interceptor.js +++ /dev/null @@ -1,141 +0,0 @@ -/*global angular:true, browser:true */ - -/** - * @license HTTP Auth Interceptor Module for AngularJS - * (c) 2012 Witold Szczerba - * License: MIT - */ - -(function () { - 'use strict'; - - angular.module('http-auth-interceptor', ['http-auth-interceptor-buffer']) - - .factory('authService', ['$rootScope','httpBuffer', function($rootScope, httpBuffer) { - return { - /** - * Call this function to indicate that authentication was successful and trigger a - * retry of all deferred requests. - * @param data an optional argument to pass on to $broadcast which may be useful for - * example if you need to pass through details of the user that was logged in - * @param configUpdater an optional transformation function that can modify the - * requests that are retried after having logged in. This can be used for example - * to add an authentication token. It must return the request. - */ - loginConfirmed: function(data, configUpdater) { - var updater = configUpdater || function(config) {return config;}; - $rootScope.$broadcast('event:auth-loginConfirmed', data); - httpBuffer.retryAll(updater); - }, - - /** - * Call this function to indicate that authentication should not proceed. - * All deferred requests will be abandoned or rejected (if reason is provided). - * @param data an optional argument to pass on to $broadcast. - * @param reason if provided, the requests are rejected; abandoned otherwise. - */ - loginCancelled: function(data, reason) { - httpBuffer.rejectAll(reason); - $rootScope.$broadcast('event:auth-loginCancelled', data); - } - }; - }]) - - /** - * $http interceptor. - * On 401 response (without 'ignoreAuthModule' option) stores the request - * and broadcasts 'event:auth-loginRequired'. - * On 403 response (without 'ignoreAuthModule' option) discards the request - * and broadcasts 'event:auth-forbidden'. - */ - .config(['$httpProvider', function($httpProvider) { - $httpProvider.interceptors.push(['$rootScope', '$q', 'httpBuffer', function($rootScope, $q, httpBuffer) { - return { - responseError: function(rejection) { - var config = rejection.config || {}; - if (!config.ignoreAuthModule) { - switch (rejection.status) { - case 401: - var deferred = $q.defer(); - var bufferLength = httpBuffer.append(config, deferred); - if (bufferLength === 1) - $rootScope.$broadcast('event:auth-loginRequired', rejection); - return deferred.promise; - case 403: - $rootScope.$broadcast('event:auth-forbidden', rejection); - break; - } - } - // otherwise, default behaviour - return $q.reject(rejection); - } - }; - }]); - }]); - - /** - * Private module, a utility, required internally by 'http-auth-interceptor'. - */ - angular.module('http-auth-interceptor-buffer', []) - - .factory('httpBuffer', ['$injector', function($injector) { - /** Holds all the requests, so they can be re-requested in future. */ - var buffer = []; - - /** Service initialized later because of circular dependency problem. */ - var $http; - - function retryHttpRequest(config, deferred) { - function successCallback(response) { - deferred.resolve(response); - } - function errorCallback(response) { - deferred.reject(response); - } - $http = $http || $injector.get('$http'); - $http(config).then(successCallback, errorCallback); - } - - return { - /** - * Appends HTTP request configuration object with deferred response attached to buffer. - * @return {Number} The new length of the buffer. - */ - append: function(config, deferred) { - return buffer.push({ - config: config, - deferred: deferred - }); - }, - - /** - * Abandon or reject (if reason provided) all the buffered requests. - */ - rejectAll: function(reason) { - if (reason) { - for (var i = 0; i < buffer.length; ++i) { - buffer[i].deferred.reject(reason); - } - } - buffer = []; - }, - - /** - * Retries all the buffered requests clears the buffer. - */ - retryAll: function(updater) { - for (var i = 0; i < buffer.length; ++i) { - var _cfg = updater(buffer[i].config); - if (_cfg !== false) - retryHttpRequest(_cfg, buffer[i].deferred); - } - buffer = []; - } - }; - }]); -})(); - -/* commonjs package manager support (eg componentjs) */ -if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports){ - module.exports = 'http-auth-interceptor'; -} \ No newline at end of file diff --git a/quartz-manager-backend/src/main/resources/static/js/lib/http-auth-interceptor.min.js b/quartz-manager-backend/src/main/resources/static/js/lib/http-auth-interceptor.min.js deleted file mode 100644 index 167529a..0000000 --- a/quartz-manager-backend/src/main/resources/static/js/lib/http-auth-interceptor.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";angular.module("http-auth-interceptor",["http-auth-interceptor-buffer"]).factory("authService",["$rootScope","httpBuffer",function($rootScope,httpBuffer){return{loginConfirmed:function(data,configUpdater){var updater=configUpdater||function(config){return config};$rootScope.$broadcast("event:auth-loginConfirmed",data),httpBuffer.retryAll(updater)},loginCancelled:function(data,reason){httpBuffer.rejectAll(reason),$rootScope.$broadcast("event:auth-loginCancelled",data)}}}]).config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$rootScope","$q","httpBuffer",function($rootScope,$q,httpBuffer){return{responseError:function(rejection){var config=rejection.config||{};if(!config.ignoreAuthModule)switch(rejection.status){case 401:var deferred=$q.defer(),bufferLength=httpBuffer.append(config,deferred);return 1===bufferLength&&$rootScope.$broadcast("event:auth-loginRequired",rejection),deferred.promise;case 403:$rootScope.$broadcast("event:auth-forbidden",rejection)}return $q.reject(rejection)}}}])}]),angular.module("http-auth-interceptor-buffer",[]).factory("httpBuffer",["$injector",function($injector){function retryHttpRequest(config,deferred){function successCallback(response){deferred.resolve(response)}function errorCallback(response){deferred.reject(response)}$http=$http||$injector.get("$http"),$http(config).then(successCallback,errorCallback)}var $http,buffer=[];return{append:function(config,deferred){return buffer.push({config:config,deferred:deferred})},rejectAll:function(reason){if(reason)for(var i=0;i 1) { - this._listeners[eventType] = arr.slice(0, idx).concat( arr.slice(idx+1) ); - } else { - delete this._listeners[eventType]; - } - return; - } - return; -}; - -REventTarget.prototype.dispatchEvent = function (event) { - var t = event.type; - var args = Array.prototype.slice.call(arguments, 0); - if (this['on'+t]) { - this['on'+t].apply(this, args); - } - if (this._listeners && t in this._listeners) { - for(var i=0; i < this._listeners[t].length; i++) { - this._listeners[t][i].apply(this, args); - } - } -}; -// [*] End of lib/reventtarget.js - - -// [*] Including lib/simpleevent.js -/* - * ***** BEGIN LICENSE BLOCK ***** - * Copyright (c) 2011-2012 VMware, Inc. - * - * For the license see COPYING. - * ***** END LICENSE BLOCK ***** - */ - -var SimpleEvent = function(type, obj) { - this.type = type; - if (typeof obj !== 'undefined') { - for(var k in obj) { - if (!obj.hasOwnProperty(k)) continue; - this[k] = obj[k]; - } - } -}; - -SimpleEvent.prototype.toString = function() { - var r = []; - for(var k in this) { - if (!this.hasOwnProperty(k)) continue; - var v = this[k]; - if (typeof v === 'function') v = '[function]'; - r.push(k + '=' + v); - } - return 'SimpleEvent(' + r.join(', ') + ')'; -}; -// [*] End of lib/simpleevent.js - - -// [*] Including lib/eventemitter.js -/* - * ***** BEGIN LICENSE BLOCK ***** - * Copyright (c) 2011-2012 VMware, Inc. - * - * For the license see COPYING. - * ***** END LICENSE BLOCK ***** - */ - -var EventEmitter = function(events) { - var that = this; - that._events = events || []; - that._listeners = {}; -}; -EventEmitter.prototype.emit = function(type) { - var that = this; - that._verifyType(type); - if (that._nuked) return; - - var args = Array.prototype.slice.call(arguments, 1); - if (that['on'+type]) { - that['on'+type].apply(that, args); - } - if (type in that._listeners) { - for(var i = 0; i < that._listeners[type].length; i++) { - that._listeners[type][i].apply(that, args); - } - } -}; - -EventEmitter.prototype.on = function(type, callback) { - var that = this; - that._verifyType(type); - if (that._nuked) return; - - if (!(type in that._listeners)) { - that._listeners[type] = []; - } - that._listeners[type].push(callback); -}; - -EventEmitter.prototype._verifyType = function(type) { - var that = this; - if (utils.arrIndexOf(that._events, type) === -1) { - utils.log('Event ' + JSON.stringify(type) + - ' not listed ' + JSON.stringify(that._events) + - ' in ' + that); - } -}; - -EventEmitter.prototype.nuke = function() { - var that = this; - that._nuked = true; - for(var i=0; i= 3000 && code <= 4999); -}; - -// See: http://www.erg.abdn.ac.uk/~gerrit/dccp/notes/ccid2/rto_estimator/ -// and RFC 2988. -utils.countRTO = function (rtt) { - var rto; - if (rtt > 100) { - rto = 3 * rtt; // rto > 300msec - } else { - rto = rtt + 200; // 200msec < rto <= 300msec - } - return rto; -} - -utils.log = function() { - if (_window.console && console.log && console.log.apply) { - console.log.apply(console, arguments); - } -}; - -utils.bind = function(fun, that) { - if (fun.bind) { - return fun.bind(that); - } else { - return function() { - return fun.apply(that, arguments); - }; - } -}; - -utils.flatUrl = function(url) { - return url.indexOf('?') === -1 && url.indexOf('#') === -1; -}; - -utils.amendUrl = function(url) { - var dl = _document.location; - if (!url) { - throw new Error('Wrong url for SockJS'); - } - if (!utils.flatUrl(url)) { - throw new Error('Only basic urls are supported in SockJS'); - } - - // '//abc' --> 'http://abc' - if (url.indexOf('//') === 0) { - url = dl.protocol + url; - } - // '/abc' --> 'http://localhost:80/abc' - if (url.indexOf('/') === 0) { - url = dl.protocol + '//' + dl.host + url; - } - // strip trailing slashes - url = url.replace(/[/]+$/,''); - return url; -}; - -// IE doesn't support [].indexOf. -utils.arrIndexOf = function(arr, obj){ - for(var i=0; i < arr.length; i++){ - if(arr[i] === obj){ - return i; - } - } - return -1; -}; - -utils.arrSkip = function(arr, obj) { - var idx = utils.arrIndexOf(arr, obj); - if (idx === -1) { - return arr.slice(); - } else { - var dst = arr.slice(0, idx); - return dst.concat(arr.slice(idx+1)); - } -}; - -// Via: https://gist.github.com/1133122/2121c601c5549155483f50be3da5305e83b8c5df -utils.isArray = Array.isArray || function(value) { - return {}.toString.call(value).indexOf('Array') >= 0 -}; - -utils.delay = function(t, fun) { - if(typeof t === 'function') { - fun = t; - t = 0; - } - return setTimeout(fun, t); -}; - - -// Chars worth escaping, as defined by Douglas Crockford: -// https://github.com/douglascrockford/JSON-js/blob/47a9882cddeb1e8529e07af9736218075372b8ac/json2.js#L196 -var json_escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - json_lookup = { -"\u0000":"\\u0000","\u0001":"\\u0001","\u0002":"\\u0002","\u0003":"\\u0003", -"\u0004":"\\u0004","\u0005":"\\u0005","\u0006":"\\u0006","\u0007":"\\u0007", -"\b":"\\b","\t":"\\t","\n":"\\n","\u000b":"\\u000b","\f":"\\f","\r":"\\r", -"\u000e":"\\u000e","\u000f":"\\u000f","\u0010":"\\u0010","\u0011":"\\u0011", -"\u0012":"\\u0012","\u0013":"\\u0013","\u0014":"\\u0014","\u0015":"\\u0015", -"\u0016":"\\u0016","\u0017":"\\u0017","\u0018":"\\u0018","\u0019":"\\u0019", -"\u001a":"\\u001a","\u001b":"\\u001b","\u001c":"\\u001c","\u001d":"\\u001d", -"\u001e":"\\u001e","\u001f":"\\u001f","\"":"\\\"","\\":"\\\\", -"\u007f":"\\u007f","\u0080":"\\u0080","\u0081":"\\u0081","\u0082":"\\u0082", -"\u0083":"\\u0083","\u0084":"\\u0084","\u0085":"\\u0085","\u0086":"\\u0086", -"\u0087":"\\u0087","\u0088":"\\u0088","\u0089":"\\u0089","\u008a":"\\u008a", -"\u008b":"\\u008b","\u008c":"\\u008c","\u008d":"\\u008d","\u008e":"\\u008e", -"\u008f":"\\u008f","\u0090":"\\u0090","\u0091":"\\u0091","\u0092":"\\u0092", -"\u0093":"\\u0093","\u0094":"\\u0094","\u0095":"\\u0095","\u0096":"\\u0096", -"\u0097":"\\u0097","\u0098":"\\u0098","\u0099":"\\u0099","\u009a":"\\u009a", -"\u009b":"\\u009b","\u009c":"\\u009c","\u009d":"\\u009d","\u009e":"\\u009e", -"\u009f":"\\u009f","\u00ad":"\\u00ad","\u0600":"\\u0600","\u0601":"\\u0601", -"\u0602":"\\u0602","\u0603":"\\u0603","\u0604":"\\u0604","\u070f":"\\u070f", -"\u17b4":"\\u17b4","\u17b5":"\\u17b5","\u200c":"\\u200c","\u200d":"\\u200d", -"\u200e":"\\u200e","\u200f":"\\u200f","\u2028":"\\u2028","\u2029":"\\u2029", -"\u202a":"\\u202a","\u202b":"\\u202b","\u202c":"\\u202c","\u202d":"\\u202d", -"\u202e":"\\u202e","\u202f":"\\u202f","\u2060":"\\u2060","\u2061":"\\u2061", -"\u2062":"\\u2062","\u2063":"\\u2063","\u2064":"\\u2064","\u2065":"\\u2065", -"\u2066":"\\u2066","\u2067":"\\u2067","\u2068":"\\u2068","\u2069":"\\u2069", -"\u206a":"\\u206a","\u206b":"\\u206b","\u206c":"\\u206c","\u206d":"\\u206d", -"\u206e":"\\u206e","\u206f":"\\u206f","\ufeff":"\\ufeff","\ufff0":"\\ufff0", -"\ufff1":"\\ufff1","\ufff2":"\\ufff2","\ufff3":"\\ufff3","\ufff4":"\\ufff4", -"\ufff5":"\\ufff5","\ufff6":"\\ufff6","\ufff7":"\\ufff7","\ufff8":"\\ufff8", -"\ufff9":"\\ufff9","\ufffa":"\\ufffa","\ufffb":"\\ufffb","\ufffc":"\\ufffc", -"\ufffd":"\\ufffd","\ufffe":"\\ufffe","\uffff":"\\uffff"}; - -// Some extra characters that Chrome gets wrong, and substitutes with -// something else on the wire. -var extra_escapable = /[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g, - extra_lookup; - -// JSON Quote string. Use native implementation when possible. -var JSONQuote = (JSON && JSON.stringify) || function(string) { - json_escapable.lastIndex = 0; - if (json_escapable.test(string)) { - string = string.replace(json_escapable, function(a) { - return json_lookup[a]; - }); - } - return '"' + string + '"'; -}; - -// This may be quite slow, so let's delay until user actually uses bad -// characters. -var unroll_lookup = function(escapable) { - var i; - var unrolled = {} - var c = [] - for(i=0; i<65536; i++) { - c.push( String.fromCharCode(i) ); - } - escapable.lastIndex = 0; - c.join('').replace(escapable, function (a) { - unrolled[ a ] = '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - return ''; - }); - escapable.lastIndex = 0; - return unrolled; -}; - -// Quote string, also taking care of unicode characters that browsers -// often break. Especially, take care of unicode surrogates: -// http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates -utils.quote = function(string) { - var quoted = JSONQuote(string); - - // In most cases this should be very fast and good enough. - extra_escapable.lastIndex = 0; - if(!extra_escapable.test(quoted)) { - return quoted; - } - - if(!extra_lookup) extra_lookup = unroll_lookup(extra_escapable); - - return quoted.replace(extra_escapable, function(a) { - return extra_lookup[a]; - }); -} - -var _all_protocols = ['websocket', - 'xdr-streaming', - 'xhr-streaming', - 'iframe-eventsource', - 'iframe-htmlfile', - 'xdr-polling', - 'xhr-polling', - 'iframe-xhr-polling', - 'jsonp-polling']; - -utils.probeProtocols = function() { - var probed = {}; - for(var i=0; i<_all_protocols.length; i++) { - var protocol = _all_protocols[i]; - // User can have a typo in protocol name. - probed[protocol] = SockJS[protocol] && - SockJS[protocol].enabled(); - } - return probed; -}; - -utils.detectProtocols = function(probed, protocols_whitelist, info) { - var pe = {}, - protocols = []; - if (!protocols_whitelist) protocols_whitelist = _all_protocols; - for(var i=0; i 0) { - maybe_push(protos); - } - } - } - - // 1. Websocket - if (info.websocket !== false) { - maybe_push(['websocket']); - } - - // 2. Streaming - if (pe['xhr-streaming'] && !info.null_origin) { - protocols.push('xhr-streaming'); - } else { - if (pe['xdr-streaming'] && !info.cookie_needed && !info.null_origin) { - protocols.push('xdr-streaming'); - } else { - maybe_push(['iframe-eventsource', - 'iframe-htmlfile']); - } - } - - // 3. Polling - if (pe['xhr-polling'] && !info.null_origin) { - protocols.push('xhr-polling'); - } else { - if (pe['xdr-polling'] && !info.cookie_needed && !info.null_origin) { - protocols.push('xdr-polling'); - } else { - maybe_push(['iframe-xhr-polling', - 'jsonp-polling']); - } - } - return protocols; -} -// [*] End of lib/utils.js - - -// [*] Including lib/dom.js -/* - * ***** BEGIN LICENSE BLOCK ***** - * Copyright (c) 2011-2012 VMware, Inc. - * - * For the license see COPYING. - * ***** END LICENSE BLOCK ***** - */ - -// May be used by htmlfile jsonp and transports. -var MPrefix = '_sockjs_global'; -utils.createHook = function() { - var window_id = 'a' + utils.random_string(8); - if (!(MPrefix in _window)) { - var map = {}; - _window[MPrefix] = function(window_id) { - if (!(window_id in map)) { - map[window_id] = { - id: window_id, - del: function() {delete map[window_id];} - }; - } - return map[window_id]; - } - } - return _window[MPrefix](window_id); -}; - - - -utils.attachMessage = function(listener) { - utils.attachEvent('message', listener); -}; -utils.attachEvent = function(event, listener) { - if (typeof _window.addEventListener !== 'undefined') { - _window.addEventListener(event, listener, false); - } else { - // IE quirks. - // According to: http://stevesouders.com/misc/test-postmessage.php - // the message gets delivered only to 'document', not 'window'. - _document.attachEvent("on" + event, listener); - // I get 'window' for ie8. - _window.attachEvent("on" + event, listener); - } -}; - -utils.detachMessage = function(listener) { - utils.detachEvent('message', listener); -}; -utils.detachEvent = function(event, listener) { - if (typeof _window.addEventListener !== 'undefined') { - _window.removeEventListener(event, listener, false); - } else { - _document.detachEvent("on" + event, listener); - _window.detachEvent("on" + event, listener); - } -}; - - -var on_unload = {}; -// Things registered after beforeunload are to be called immediately. -var after_unload = false; - -var trigger_unload_callbacks = function() { - for(var ref in on_unload) { - on_unload[ref](); - delete on_unload[ref]; - }; -}; - -var unload_triggered = function() { - if(after_unload) return; - after_unload = true; - trigger_unload_callbacks(); -}; - -// 'unload' alone is not reliable in opera within an iframe, but we -// can't use `beforeunload` as IE fires it on javascript: links. -utils.attachEvent('unload', unload_triggered); - -utils.unload_add = function(listener) { - var ref = utils.random_string(8); - on_unload[ref] = listener; - if (after_unload) { - utils.delay(trigger_unload_callbacks); - } - return ref; -}; -utils.unload_del = function(ref) { - if (ref in on_unload) - delete on_unload[ref]; -}; - - -utils.createIframe = function (iframe_url, error_callback) { - var iframe = _document.createElement('iframe'); - var tref, unload_ref; - var unattach = function() { - clearTimeout(tref); - // Explorer had problems with that. - try {iframe.onload = null;} catch (x) {} - iframe.onerror = null; - }; - var cleanup = function() { - if (iframe) { - unattach(); - // This timeout makes chrome fire onbeforeunload event - // within iframe. Without the timeout it goes straight to - // onunload. - setTimeout(function() { - if(iframe) { - iframe.parentNode.removeChild(iframe); - } - iframe = null; - }, 0); - utils.unload_del(unload_ref); - } - }; - var onerror = function(r) { - if (iframe) { - cleanup(); - error_callback(r); - } - }; - var post = function(msg, origin) { - try { - // When the iframe is not loaded, IE raises an exception - // on 'contentWindow'. - if (iframe && iframe.contentWindow) { - iframe.contentWindow.postMessage(msg, origin); - } - } catch (x) {}; - }; - - iframe.src = iframe_url; - iframe.style.display = 'none'; - iframe.style.position = 'absolute'; - iframe.onerror = function(){onerror('onerror');}; - iframe.onload = function() { - // `onload` is triggered before scripts on the iframe are - // executed. Give it few seconds to actually load stuff. - clearTimeout(tref); - tref = setTimeout(function(){onerror('onload timeout');}, 2000); - }; - _document.body.appendChild(iframe); - tref = setTimeout(function(){onerror('timeout');}, 15000); - unload_ref = utils.unload_add(cleanup); - return { - post: post, - cleanup: cleanup, - loaded: unattach - }; -}; - -utils.createHtmlfile = function (iframe_url, error_callback) { - var doc = new ActiveXObject('htmlfile'); - var tref, unload_ref; - var iframe; - var unattach = function() { - clearTimeout(tref); - }; - var cleanup = function() { - if (doc) { - unattach(); - utils.unload_del(unload_ref); - iframe.parentNode.removeChild(iframe); - iframe = doc = null; - CollectGarbage(); - } - }; - var onerror = function(r) { - if (doc) { - cleanup(); - error_callback(r); - } - }; - var post = function(msg, origin) { - try { - // When the iframe is not loaded, IE raises an exception - // on 'contentWindow'. - if (iframe && iframe.contentWindow) { - iframe.contentWindow.postMessage(msg, origin); - } - } catch (x) {}; - }; - - doc.open(); - doc.write('' + - 'document.domain="' + document.domain + '";' + - ''); - doc.close(); - doc.parentWindow[WPrefix] = _window[WPrefix]; - var c = doc.createElement('div'); - doc.body.appendChild(c); - iframe = doc.createElement('iframe'); - c.appendChild(iframe); - iframe.src = iframe_url; - tref = setTimeout(function(){onerror('timeout');}, 15000); - unload_ref = utils.unload_add(cleanup); - return { - post: post, - cleanup: cleanup, - loaded: unattach - }; -}; -// [*] End of lib/dom.js - - -// [*] Including lib/dom2.js -/* - * ***** BEGIN LICENSE BLOCK ***** - * Copyright (c) 2011-2012 VMware, Inc. - * - * For the license see COPYING. - * ***** END LICENSE BLOCK ***** - */ - -var AbstractXHRObject = function(){}; -AbstractXHRObject.prototype = new EventEmitter(['chunk', 'finish']); - -AbstractXHRObject.prototype._start = function(method, url, payload, opts) { - var that = this; - - try { - that.xhr = new XMLHttpRequest(); - } catch(x) {}; - - if (!that.xhr) { - try { - that.xhr = new _window.ActiveXObject('Microsoft.XMLHTTP'); - } catch(x) {}; - } - if (_window.ActiveXObject || _window.XDomainRequest) { - // IE8 caches even POSTs - url += ((url.indexOf('?') === -1) ? '?' : '&') + 't='+(+new Date); - } - - // Explorer tends to keep connection open, even after the - // tab gets closed: http://bugs.jquery.com/ticket/5280 - that.unload_ref = utils.unload_add(function(){that._cleanup(true);}); - try { - that.xhr.open(method, url, true); - } catch(e) { - // IE raises an exception on wrong port. - that.emit('finish', 0, ''); - that._cleanup(); - return; - }; - - if (!opts || !opts.no_credentials) { - // Mozilla docs says https://developer.mozilla.org/en/XMLHttpRequest : - // "This never affects same-site requests." - that.xhr.withCredentials = 'true'; - } - if (opts && opts.headers) { - for(var key in opts.headers) { - that.xhr.setRequestHeader(key, opts.headers[key]); - } - } - - that.xhr.onreadystatechange = function() { - if (that.xhr) { - var x = that.xhr; - switch (x.readyState) { - case 3: - // IE doesn't like peeking into responseText or status - // on Microsoft.XMLHTTP and readystate=3 - try { - var status = x.status; - var text = x.responseText; - } catch (x) {}; - // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450 - if (status === 1223) status = 204; - - // IE does return readystate == 3 for 404 answers. - if (text && text.length > 0) { - that.emit('chunk', status, text); - } - break; - case 4: - var status = x.status; - // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450 - if (status === 1223) status = 204; - - that.emit('finish', status, x.responseText); - that._cleanup(false); - break; - } - } - }; - that.xhr.send(payload); -}; - -AbstractXHRObject.prototype._cleanup = function(abort) { - var that = this; - if (!that.xhr) return; - utils.unload_del(that.unload_ref); - - // IE needs this field to be a function - that.xhr.onreadystatechange = function(){}; - - if (abort) { - try { - that.xhr.abort(); - } catch(x) {}; - } - that.unload_ref = that.xhr = null; -}; - -AbstractXHRObject.prototype.close = function() { - var that = this; - that.nuke(); - that._cleanup(true); -}; - -var XHRCorsObject = utils.XHRCorsObject = function() { - var that = this, args = arguments; - utils.delay(function(){that._start.apply(that, args);}); -}; -XHRCorsObject.prototype = new AbstractXHRObject(); - -var XHRLocalObject = utils.XHRLocalObject = function(method, url, payload) { - var that = this; - utils.delay(function(){ - that._start(method, url, payload, { - no_credentials: true - }); - }); -}; -XHRLocalObject.prototype = new AbstractXHRObject(); - - - -// References: -// http://ajaxian.com/archives/100-line-ajax-wrapper -// http://msdn.microsoft.com/en-us/library/cc288060(v=VS.85).aspx -var XDRObject = utils.XDRObject = function(method, url, payload) { - var that = this; - utils.delay(function(){that._start(method, url, payload);}); -}; -XDRObject.prototype = new EventEmitter(['chunk', 'finish']); -XDRObject.prototype._start = function(method, url, payload) { - var that = this; - var xdr = new XDomainRequest(); - // IE caches even POSTs - url += ((url.indexOf('?') === -1) ? '?' : '&') + 't='+(+new Date); - - var onerror = xdr.ontimeout = xdr.onerror = function() { - that.emit('finish', 0, ''); - that._cleanup(false); - }; - xdr.onprogress = function() { - that.emit('chunk', 200, xdr.responseText); - }; - xdr.onload = function() { - that.emit('finish', 200, xdr.responseText); - that._cleanup(false); - }; - that.xdr = xdr; - that.unload_ref = utils.unload_add(function(){that._cleanup(true);}); - try { - // Fails with AccessDenied if port number is bogus - that.xdr.open(method, url); - that.xdr.send(payload); - } catch(x) { - onerror(); - } -}; - -XDRObject.prototype._cleanup = function(abort) { - var that = this; - if (!that.xdr) return; - utils.unload_del(that.unload_ref); - - that.xdr.ontimeout = that.xdr.onerror = that.xdr.onprogress = - that.xdr.onload = null; - if (abort) { - try { - that.xdr.abort(); - } catch(x) {}; - } - that.unload_ref = that.xdr = null; -}; - -XDRObject.prototype.close = function() { - var that = this; - that.nuke(); - that._cleanup(true); -}; - -// 1. Is natively via XHR -// 2. Is natively via XDR -// 3. Nope, but postMessage is there so it should work via the Iframe. -// 4. Nope, sorry. -utils.isXHRCorsCapable = function() { - if (_window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()) { - return 1; - } - // XDomainRequest doesn't work if page is served from file:// - if (_window.XDomainRequest && _document.domain) { - return 2; - } - if (IframeTransport.enabled()) { - return 3; - } - return 4; -}; -// [*] End of lib/dom2.js - - -// [*] Including lib/sockjs.js -/* - * ***** BEGIN LICENSE BLOCK ***** - * Copyright (c) 2011-2012 VMware, Inc. - * - * For the license see COPYING. - * ***** END LICENSE BLOCK ***** - */ - -var SockJS = function(url, dep_protocols_whitelist, options) { - if (this === _window) { - // makes `new` optional - return new SockJS(url, dep_protocols_whitelist, options); - } - - var that = this, protocols_whitelist; - that._options = {devel: false, debug: false, protocols_whitelist: [], - info: undefined, rtt: undefined}; - if (options) { - utils.objectExtend(that._options, options); - } - that._base_url = utils.amendUrl(url); - that._server = that._options.server || utils.random_number_string(1000); - if (that._options.protocols_whitelist && - that._options.protocols_whitelist.length) { - protocols_whitelist = that._options.protocols_whitelist; - } else { - // Deprecated API - if (typeof dep_protocols_whitelist === 'string' && - dep_protocols_whitelist.length > 0) { - protocols_whitelist = [dep_protocols_whitelist]; - } else if (utils.isArray(dep_protocols_whitelist)) { - protocols_whitelist = dep_protocols_whitelist - } else { - protocols_whitelist = null; - } - if (protocols_whitelist) { - that._debug('Deprecated API: Use "protocols_whitelist" option ' + - 'instead of supplying protocol list as a second ' + - 'parameter to SockJS constructor.'); - } - } - that._protocols = []; - that.protocol = null; - that.readyState = SockJS.CONNECTING; - that._ir = createInfoReceiver(that._base_url); - that._ir.onfinish = function(info, rtt) { - that._ir = null; - if (info) { - if (that._options.info) { - // Override if user supplies the option - info = utils.objectExtend(info, that._options.info); - } - if (that._options.rtt) { - rtt = that._options.rtt; - } - that._applyInfo(info, rtt, protocols_whitelist); - that._didClose(); - } else { - that._didClose(1002, 'Can\'t connect to server', true); - } - }; -}; -// Inheritance -SockJS.prototype = new REventTarget(); - -SockJS.version = "0.3.4"; - -SockJS.CONNECTING = 0; -SockJS.OPEN = 1; -SockJS.CLOSING = 2; -SockJS.CLOSED = 3; - -SockJS.prototype._debug = function() { - if (this._options.debug) - utils.log.apply(utils, arguments); -}; - -SockJS.prototype._dispatchOpen = function() { - var that = this; - if (that.readyState === SockJS.CONNECTING) { - if (that._transport_tref) { - clearTimeout(that._transport_tref); - that._transport_tref = null; - } - that.readyState = SockJS.OPEN; - that.dispatchEvent(new SimpleEvent("open")); - } else { - // The server might have been restarted, and lost track of our - // connection. - that._didClose(1006, "Server lost session"); - } -}; - -SockJS.prototype._dispatchMessage = function(data) { - var that = this; - if (that.readyState !== SockJS.OPEN) - return; - that.dispatchEvent(new SimpleEvent("message", {data: data})); -}; - -SockJS.prototype._dispatchHeartbeat = function(data) { - var that = this; - if (that.readyState !== SockJS.OPEN) - return; - that.dispatchEvent(new SimpleEvent('heartbeat', {})); -}; - -SockJS.prototype._didClose = function(code, reason, force) { - var that = this; - if (that.readyState !== SockJS.CONNECTING && - that.readyState !== SockJS.OPEN && - that.readyState !== SockJS.CLOSING) - throw new Error('INVALID_STATE_ERR'); - if (that._ir) { - that._ir.nuke(); - that._ir = null; - } - - if (that._transport) { - that._transport.doCleanup(); - that._transport = null; - } - - var close_event = new SimpleEvent("close", { - code: code, - reason: reason, - wasClean: utils.userSetCode(code)}); - - if (!utils.userSetCode(code) && - that.readyState === SockJS.CONNECTING && !force) { - if (that._try_next_protocol(close_event)) { - return; - } - close_event = new SimpleEvent("close", {code: 2000, - reason: "All transports failed", - wasClean: false, - last_event: close_event}); - } - that.readyState = SockJS.CLOSED; - - utils.delay(function() { - that.dispatchEvent(close_event); - }); -}; - -SockJS.prototype._didMessage = function(data) { - var that = this; - var type = data.slice(0, 1); - switch(type) { - case 'o': - that._dispatchOpen(); - break; - case 'a': - var payload = JSON.parse(data.slice(1) || '[]'); - for(var i=0; i < payload.length; i++){ - that._dispatchMessage(payload[i]); - } - break; - case 'm': - var payload = JSON.parse(data.slice(1) || 'null'); - that._dispatchMessage(payload); - break; - case 'c': - var payload = JSON.parse(data.slice(1) || '[]'); - that._didClose(payload[0], payload[1]); - break; - case 'h': - that._dispatchHeartbeat(); - break; - } -}; - -SockJS.prototype._try_next_protocol = function(close_event) { - var that = this; - if (that.protocol) { - that._debug('Closed transport:', that.protocol, ''+close_event); - that.protocol = null; - } - if (that._transport_tref) { - clearTimeout(that._transport_tref); - that._transport_tref = null; - } - - while(1) { - var protocol = that.protocol = that._protocols.shift(); - if (!protocol) { - return false; - } - // Some protocols require access to `body`, what if were in - // the `head`? - if (SockJS[protocol] && - SockJS[protocol].need_body === true && - (!_document.body || - (typeof _document.readyState !== 'undefined' - && _document.readyState !== 'complete'))) { - that._protocols.unshift(protocol); - that.protocol = 'waiting-for-load'; - utils.attachEvent('load', function(){ - that._try_next_protocol(); - }); - return true; - } - - if (!SockJS[protocol] || - !SockJS[protocol].enabled(that._options)) { - that._debug('Skipping transport:', protocol); - } else { - var roundTrips = SockJS[protocol].roundTrips || 1; - var to = ((that._options.rto || 0) * roundTrips) || 5000; - that._transport_tref = utils.delay(to, function() { - if (that.readyState === SockJS.CONNECTING) { - // I can't understand how it is possible to run - // this timer, when the state is CLOSED, but - // apparently in IE everythin is possible. - that._didClose(2007, "Transport timeouted"); - } - }); - - var connid = utils.random_string(8); - var trans_url = that._base_url + '/' + that._server + '/' + connid; - that._debug('Opening transport:', protocol, ' url:'+trans_url, - ' RTO:'+that._options.rto); - that._transport = new SockJS[protocol](that, trans_url, - that._base_url); - return true; - } - } -}; - -SockJS.prototype.close = function(code, reason) { - var that = this; - if (code && !utils.userSetCode(code)) - throw new Error("INVALID_ACCESS_ERR"); - if(that.readyState !== SockJS.CONNECTING && - that.readyState !== SockJS.OPEN) { - return false; - } - that.readyState = SockJS.CLOSING; - that._didClose(code || 1000, reason || "Normal closure"); - return true; -}; - -SockJS.prototype.send = function(data) { - var that = this; - if (that.readyState === SockJS.CONNECTING) - throw new Error('INVALID_STATE_ERR'); - if (that.readyState === SockJS.OPEN) { - that._transport.doSend(utils.quote('' + data)); - } - return true; -}; - -SockJS.prototype._applyInfo = function(info, rtt, protocols_whitelist) { - var that = this; - that._options.info = info; - that._options.rtt = rtt; - that._options.rto = utils.countRTO(rtt); - that._options.info.null_origin = !_document.domain; - var probed = utils.probeProtocols(); - that._protocols = utils.detectProtocols(probed, protocols_whitelist, info); -}; -// [*] End of lib/sockjs.js - - -// [*] Including lib/trans-websocket.js -/* - * ***** BEGIN LICENSE BLOCK ***** - * Copyright (c) 2011-2012 VMware, Inc. - * - * For the license see COPYING. - * ***** END LICENSE BLOCK ***** - */ - -var WebSocketTransport = SockJS.websocket = function(ri, trans_url) { - var that = this; - var url = trans_url + '/websocket'; - if (url.slice(0, 5) === 'https') { - url = 'wss' + url.slice(5); - } else { - url = 'ws' + url.slice(4); - } - that.ri = ri; - that.url = url; - var Constructor = _window.WebSocket || _window.MozWebSocket; - - that.ws = new Constructor(that.url); - that.ws.onmessage = function(e) { - that.ri._didMessage(e.data); - }; - // Firefox has an interesting bug. If a websocket connection is - // created after onunload, it stays alive even when user - // navigates away from the page. In such situation let's lie - - // let's not open the ws connection at all. See: - // https://github.com/sockjs/sockjs-client/issues/28 - // https://bugzilla.mozilla.org/show_bug.cgi?id=696085 - that.unload_ref = utils.unload_add(function(){that.ws.close()}); - that.ws.onclose = function() { - that.ri._didMessage(utils.closeFrame(1006, "WebSocket connection broken")); - }; -}; - -WebSocketTransport.prototype.doSend = function(data) { - this.ws.send('[' + data + ']'); -}; - -WebSocketTransport.prototype.doCleanup = function() { - var that = this; - var ws = that.ws; - if (ws) { - ws.onmessage = ws.onclose = null; - ws.close(); - utils.unload_del(that.unload_ref); - that.unload_ref = that.ri = that.ws = null; - } -}; - -WebSocketTransport.enabled = function() { - return !!(_window.WebSocket || _window.MozWebSocket); -}; - -// In theory, ws should require 1 round trip. But in chrome, this is -// not very stable over SSL. Most likely a ws connection requires a -// separate SSL connection, in which case 2 round trips are an -// absolute minumum. -WebSocketTransport.roundTrips = 2; -// [*] End of lib/trans-websocket.js - - -// [*] Including lib/trans-sender.js -/* - * ***** BEGIN LICENSE BLOCK ***** - * Copyright (c) 2011-2012 VMware, Inc. - * - * For the license see COPYING. - * ***** END LICENSE BLOCK ***** - */ - -var BufferedSender = function() {}; -BufferedSender.prototype.send_constructor = function(sender) { - var that = this; - that.send_buffer = []; - that.sender = sender; -}; -BufferedSender.prototype.doSend = function(message) { - var that = this; - that.send_buffer.push(message); - if (!that.send_stop) { - that.send_schedule(); - } -}; - -// For polling transports in a situation when in the message callback, -// new message is being send. If the sending connection was started -// before receiving one, it is possible to saturate the network and -// timeout due to the lack of receiving socket. To avoid that we delay -// sending messages by some small time, in order to let receiving -// connection be started beforehand. This is only a halfmeasure and -// does not fix the big problem, but it does make the tests go more -// stable on slow networks. -BufferedSender.prototype.send_schedule_wait = function() { - var that = this; - var tref; - that.send_stop = function() { - that.send_stop = null; - clearTimeout(tref); - }; - tref = utils.delay(25, function() { - that.send_stop = null; - that.send_schedule(); - }); -}; - -BufferedSender.prototype.send_schedule = function() { - var that = this; - if (that.send_buffer.length > 0) { - var payload = '[' + that.send_buffer.join(',') + ']'; - that.send_stop = that.sender(that.trans_url, payload, function(success, abort_reason) { - that.send_stop = null; - if (success === false) { - that.ri._didClose(1006, 'Sending error ' + abort_reason); - } else { - that.send_schedule_wait(); - } - }); - that.send_buffer = []; - } -}; - -BufferedSender.prototype.send_destructor = function() { - var that = this; - if (that._send_stop) { - that._send_stop(); - } - that._send_stop = null; -}; - -var jsonPGenericSender = function(url, payload, callback) { - var that = this; - - if (!('_send_form' in that)) { - var form = that._send_form = _document.createElement('form'); - var area = that._send_area = _document.createElement('textarea'); - area.name = 'd'; - form.style.display = 'none'; - form.style.position = 'absolute'; - form.method = 'POST'; - form.enctype = 'application/x-www-form-urlencoded'; - form.acceptCharset = "UTF-8"; - form.appendChild(area); - _document.body.appendChild(form); - } - var form = that._send_form; - var area = that._send_area; - var id = 'a' + utils.random_string(8); - form.target = id; - form.action = url + '/jsonp_send?i=' + id; - - var iframe; - try { - // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) - iframe = _document.createElement('