Add settings page with 'allow/disallow registration' option for admin. Allowed for first run.
This commit is contained in:
parent
52dd7f509a
commit
583682106d
13 changed files with 176 additions and 11 deletions
|
@ -1,10 +1,8 @@
|
||||||
package ru.redrise.marinesco;
|
package ru.redrise.marinesco;
|
||||||
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
//@PreAuthorize("hasRole('USER')")
|
|
||||||
@Controller
|
@Controller
|
||||||
public class RootController {
|
public class RootController {
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,19 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import ru.redrise.marinesco.data.RolesRepository;
|
import ru.redrise.marinesco.data.RolesRepository;
|
||||||
import ru.redrise.marinesco.data.UserRepository;
|
import ru.redrise.marinesco.data.UserRepository;
|
||||||
import ru.redrise.marinesco.security.UserRole;
|
import ru.redrise.marinesco.security.UserRole;
|
||||||
|
import ru.redrise.marinesco.settings.ApplicationSettings;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
public class ShinyApplicationRunner {
|
public class ShinyApplicationRunner {
|
||||||
private UserRepository users;
|
private UserRepository users;
|
||||||
private RolesRepository roles;
|
private RolesRepository roles;
|
||||||
|
private ApplicationSettings settings;
|
||||||
public ShinyApplicationRunner(UserRepository users, RolesRepository roles) {
|
|
||||||
|
public ShinyApplicationRunner(UserRepository users, RolesRepository roles, ApplicationSettings settings) {
|
||||||
this.users = users;
|
this.users = users;
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
|
this.settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -32,6 +35,7 @@ public class ShinyApplicationRunner {
|
||||||
log.info("Application first run");
|
log.info("Application first run");
|
||||||
setRoles();
|
setRoles();
|
||||||
setAdmin(args, encoder);
|
setAdmin(args, encoder);
|
||||||
|
settings.setAllowRegistraion(true);
|
||||||
} else
|
} else
|
||||||
log.info("Regular run");
|
log.info("Regular run");
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.redrise.marinesco;
|
package ru.redrise.marinesco.security;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import jakarta.validation.constraints.NotEmpty;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import ru.redrise.marinesco.security.UserRole;
|
import ru.redrise.marinesco.User;
|
||||||
|
|
||||||
//TODO: refactor along with RegistrationForm.java
|
//TODO: refactor along with RegistrationForm.java
|
||||||
@Data
|
@Data
|
|
@ -16,7 +16,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import ru.redrise.marinesco.AdministatorAddUserForm;
|
|
||||||
import ru.redrise.marinesco.User;
|
import ru.redrise.marinesco.User;
|
||||||
import ru.redrise.marinesco.UserGenerified;
|
import ru.redrise.marinesco.UserGenerified;
|
||||||
import ru.redrise.marinesco.data.RolesRepository;
|
import ru.redrise.marinesco.data.RolesRepository;
|
||||||
|
|
|
@ -15,6 +15,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import ru.redrise.marinesco.User;
|
import ru.redrise.marinesco.User;
|
||||||
import ru.redrise.marinesco.data.RolesRepository;
|
import ru.redrise.marinesco.data.RolesRepository;
|
||||||
import ru.redrise.marinesco.data.UserRepository;
|
import ru.redrise.marinesco.data.UserRepository;
|
||||||
|
import ru.redrise.marinesco.settings.ApplicationSettings;
|
||||||
|
import ru.redrise.marinesco.settings.KeyValueRepository;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Controller
|
@Controller
|
||||||
|
@ -25,14 +27,18 @@ public class RegistrationController {
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
private HttpServletRequest request;
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
private ApplicationSettings applicationSettings;
|
||||||
|
|
||||||
public RegistrationController(UserRepository userRepo,
|
public RegistrationController(UserRepository userRepo,
|
||||||
RolesRepository rolesRepo,
|
RolesRepository rolesRepo,
|
||||||
PasswordEncoder passwordEncoder,
|
PasswordEncoder passwordEncoder,
|
||||||
HttpServletRequest request) {
|
HttpServletRequest request,
|
||||||
|
ApplicationSettings applicationSettings) {
|
||||||
this.userRepo = userRepo;
|
this.userRepo = userRepo;
|
||||||
this.rolesRepo = rolesRepo;
|
this.rolesRepo = rolesRepo;
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder = passwordEncoder;
|
||||||
this.request = request;
|
this.request = request;
|
||||||
|
this.applicationSettings = applicationSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModelAttribute(name = "registrationForm")
|
@ModelAttribute(name = "registrationForm")
|
||||||
|
@ -42,11 +48,15 @@ public class RegistrationController {
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public String registerForm() {
|
public String registerForm() {
|
||||||
return "registration";
|
if (applicationSettings.isRegistrationAllowed())
|
||||||
|
return "registration";
|
||||||
|
return "registration_forbidden";
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public String postMethodName(@Valid RegistrationForm form, Errors errors, Model model) {
|
public String postMethodName(@Valid RegistrationForm form, Errors errors, Model model) {
|
||||||
|
if (!applicationSettings.isRegistrationAllowed())
|
||||||
|
return "redirect:/";
|
||||||
if (form.isPasswordsNotEqual()) {
|
if (form.isPasswordsNotEqual()) {
|
||||||
model.addAttribute("passwordsMismatch", "Passwords must be the same.");
|
model.addAttribute("passwordsMismatch", "Passwords must be the same.");
|
||||||
return "registration";
|
return "registration";
|
||||||
|
|
|
@ -54,8 +54,8 @@ public class SecurityConfig {
|
||||||
.requestMatchers(mvc.pattern("/login")).anonymous()
|
.requestMatchers(mvc.pattern("/login")).anonymous()
|
||||||
.requestMatchers(mvc.pattern("/error")).permitAll()
|
.requestMatchers(mvc.pattern("/error")).permitAll()
|
||||||
.requestMatchers(PathRequest.toH2Console()).permitAll()
|
.requestMatchers(PathRequest.toH2Console()).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/")).hasAnyRole("ADMIN", "USER")
|
.requestMatchers(mvc.pattern("/")).authenticated()
|
||||||
.requestMatchers(mvc.pattern("/profile/**")).hasAnyRole("ADMIN", "USER")
|
.requestMatchers(mvc.pattern("/profile/**")).authenticated()//.hasAnyRole("ADMIN", "USER")
|
||||||
//.requestMatchers(mvc.pattern("/design/**")).hasRole("USER")
|
//.requestMatchers(mvc.pattern("/design/**")).hasRole("USER")
|
||||||
.anyRequest().authenticated())
|
.anyRequest().authenticated())
|
||||||
//.anyRequest().permitAll())
|
//.anyRequest().permitAll())
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package ru.redrise.marinesco.settings;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ApplicationSettings {
|
||||||
|
private static final String ALLOW_REGISTRATION = "allow_registration";
|
||||||
|
|
||||||
|
private KeyValueRepository keyValueRepository;
|
||||||
|
|
||||||
|
private boolean registrationAllowed;
|
||||||
|
|
||||||
|
public ApplicationSettings(KeyValueRepository keyValueRepository) {
|
||||||
|
this.keyValueRepository = keyValueRepository;
|
||||||
|
initAllowRegistraionValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initAllowRegistraionValue() {
|
||||||
|
try{
|
||||||
|
this.registrationAllowed = keyValueRepository.findById(ApplicationSettings.ALLOW_REGISTRATION).get().getM_value();
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
// Application first run, thus no data on the DB
|
||||||
|
registrationAllowed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setAllowRegistraion(boolean value) {
|
||||||
|
keyValueRepository.save(new KeyValue(ApplicationSettings.ALLOW_REGISTRATION, value));
|
||||||
|
this.registrationAllowed = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isRegistrationAllowed() {
|
||||||
|
return registrationAllowed;
|
||||||
|
}
|
||||||
|
}
|
19
src/main/java/ru/redrise/marinesco/settings/KeyValue.java
Normal file
19
src/main/java/ru/redrise/marinesco/settings/KeyValue.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package ru.redrise.marinesco.settings;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
|
||||||
|
public class KeyValue {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String m_key;
|
||||||
|
private Boolean m_value;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ru.redrise.marinesco.settings;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface KeyValueRepository extends CrudRepository<KeyValue, String>{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package ru.redrise.marinesco.settings;
|
||||||
|
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
//@Slf4j
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/settings")
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
public class SettingsController {
|
||||||
|
private KeyValueRepository keyValueRepository;
|
||||||
|
private ApplicationSettings applicationSettings;
|
||||||
|
|
||||||
|
public SettingsController(KeyValueRepository keyValueRepository, ApplicationSettings applicationSettings){
|
||||||
|
this.keyValueRepository = keyValueRepository;
|
||||||
|
this.applicationSettings = applicationSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String getPage() {
|
||||||
|
|
||||||
|
return "settings";
|
||||||
|
}
|
||||||
|
@ModelAttribute(name = "allowRegistration")
|
||||||
|
public Boolean setRegistrationSetting(){
|
||||||
|
return applicationSettings.isRegistrationAllowed();
|
||||||
|
//return keyValueRepository.findById(ApplicationSettings.ALLOW_REGISTRATION).get().getM_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/allow_registration/{sw}")
|
||||||
|
public String switchRegistration(@PathVariable("sw") Boolean sw){
|
||||||
|
//log.info("{}", sw);
|
||||||
|
//keyValueRepository.save(new KeyValue(ApplicationSettings.ALLOW_REGISTRATION, sw));
|
||||||
|
applicationSettings.setAllowRegistraion(sw);
|
||||||
|
|
||||||
|
return "redirect:/settings";
|
||||||
|
}
|
||||||
|
}
|
22
src/main/resources/templates/registration_forbidden.html
Normal file
22
src/main/resources/templates/registration_forbidden.html
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Marinesco - registration form</title>
|
||||||
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||||
|
<link rel="alternate icon" href="/favicon.png" type="image/png">
|
||||||
|
<link rel="stylesheet" th:href="@{/styles/styles.css}" />
|
||||||
|
<script src="/jquery.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="page">
|
||||||
|
<div th:replace="~{fragments/header :: 'header'}"></div>
|
||||||
|
<div class="container base">
|
||||||
|
<h1>Currently we're close to new registrations</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:replace="~{fragments/footer :: 'footer'}"></div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -15,6 +15,7 @@
|
||||||
<br /><a href="/login">Login</a>
|
<br /><a href="/login">Login</a>
|
||||||
<br /><a href="/profile">/profile</a>
|
<br /><a href="/profile">/profile</a>
|
||||||
<br /><a href="/manage_users">/manage_users</a>
|
<br /><a href="/manage_users">/manage_users</a>
|
||||||
|
<br /><a href="/settings">/settings</a>
|
||||||
<br /><a href="/h2">H2</a>
|
<br /><a href="/h2">H2</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
22
src/main/resources/templates/settings.html
Normal file
22
src/main/resources/templates/settings.html
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Marinesco - Application settings</title>
|
||||||
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||||
|
<link rel="alternate icon" href="/favicon.png" type="image/png">
|
||||||
|
<link rel="stylesheet" th:href="@{/styles/styles.css}" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="page">
|
||||||
|
<div th:replace="~{fragments/header :: 'header'}"></div>
|
||||||
|
<div class="container base">
|
||||||
|
<span th:text="${'New users registration is now ' + (allowRegistration ? 'enabled. ' : 'disabled. ' )}"></span>
|
||||||
|
<a th:href="${'/settings/allow_registration/' + !allowRegistration }" th:text="${'Click here to ' + (allowRegistration ? 'disable' : 'enable' )}"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:replace="~{fragments/footer :: 'footer'}"></div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in a new issue