diff --git a/src/main/java/com/alterdekim/game/ThymeleafConfig.java b/src/main/java/com/alterdekim/game/ThymeleafConfig.java new file mode 100644 index 0000000..3f10b1b --- /dev/null +++ b/src/main/java/com/alterdekim/game/ThymeleafConfig.java @@ -0,0 +1,14 @@ +package com.alterdekim.game; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.thymeleaf.extras.springsecurity6.dialect.SpringSecurityDialect; + +@Configuration +public class ThymeleafConfig { + + @Bean + public SpringSecurityDialect springSecurityDialect(){ + return new SpringSecurityDialect(); + } +} \ No newline at end of file diff --git a/src/main/java/com/alterdekim/game/controller/AuthController.java b/src/main/java/com/alterdekim/game/controller/AuthController.java index fe002f0..be5e029 100644 --- a/src/main/java/com/alterdekim/game/controller/AuthController.java +++ b/src/main/java/com/alterdekim/game/controller/AuthController.java @@ -33,12 +33,27 @@ public class AuthController { return "game"; } + @GetMapping("/rules") + public String rulesPage(Model model) { + return "rules"; + } + @GetMapping("/login") public String loginPage(Model model) { model.addAttribute("title", "Login" + base_title); return "login"; } + @GetMapping("/games") + public String gamesPage(Model model) { + return "games"; + } + + @GetMapping("/") + public String homePage(Model model) { + return "index"; + } + @GetMapping("/access-denied") public String accessDenied(Model model) { model.addAttribute("title", "Access denied"); @@ -63,17 +78,22 @@ public class AuthController { if(existingUser != null && existingUser.getUsername() != null && !existingUser.getUsername().isEmpty() ){ result.rejectValue("username", null, "There is already an account registered with the same username"); - return "redirect:/signup?error=1"; + return "redirect:/signup?error=already_exists"; } if(!existingInvite.getInvite_code().equals(userDto.getInvite_code())) { result.rejectValue("invite_code", null, "Incorrect invite code."); - return "redirect:/signup?error=1"; + return "redirect:/signup?error=bad_invite"; + } + + if(!userDto.getTerms_and_conditions_accept()) { + result.rejectValue("terms_and_conditions_accept", null, "You must accept terms and conditions"); + return "redirect:/signup?error=terms_and_conditions"; } if(result.hasErrors()) { model.addAttribute("user", new UserDTO()); - return "redirect:/signup?error=1"; + return "redirect:/signup?error=other"; } userService.saveUser(userDto); diff --git a/src/main/java/com/alterdekim/game/dto/UserDTO.java b/src/main/java/com/alterdekim/game/dto/UserDTO.java index 849723e..e8a5b27 100644 --- a/src/main/java/com/alterdekim/game/dto/UserDTO.java +++ b/src/main/java/com/alterdekim/game/dto/UserDTO.java @@ -1,5 +1,6 @@ package com.alterdekim.game.dto; +import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.NotEmpty; import lombok.AllArgsConstructor; import lombok.Getter; @@ -18,6 +19,7 @@ public class UserDTO { private String password; @NotEmpty(message = "Invite code should not be empty") private String invite_code; + private Boolean terms_and_conditions_accept; private String lang; } diff --git a/src/main/java/com/alterdekim/game/security/SpringSecurity.java b/src/main/java/com/alterdekim/game/security/SpringSecurity.java index 09c6d50..7ff4c49 100644 --- a/src/main/java/com/alterdekim/game/security/SpringSecurity.java +++ b/src/main/java/com/alterdekim/game/security/SpringSecurity.java @@ -29,11 +29,12 @@ public class SpringSecurity { http.csrf().disable() .authorizeHttpRequests((authorize) -> authorize - .requestMatchers("/game").permitAll() - .requestMatchers("/games").permitAll() + .requestMatchers("/game").hasAnyAuthority("ROLE_ADMIN") + .requestMatchers("/games").hasAnyAuthority("ROLE_ADMIN") .requestMatchers("/static/**").permitAll() .requestMatchers("/access-denied").permitAll() .requestMatchers("/signup").permitAll() + .requestMatchers("/rules").permitAll() .requestMatchers("/favicon.ico").permitAll() .requestMatchers("/signup/**").permitAll() .requestMatchers("/").permitAll() @@ -42,7 +43,7 @@ public class SpringSecurity { .loginPage("/login") .loginProcessingUrl("/login") .failureForwardUrl("/") - .defaultSuccessUrl("/game") + .defaultSuccessUrl("/games") .permitAll() ) .logout( diff --git a/src/main/java/com/alterdekim/game/service/CustomUserDetailsService.java b/src/main/java/com/alterdekim/game/service/CustomUserDetailsService.java new file mode 100644 index 0000000..7af527b --- /dev/null +++ b/src/main/java/com/alterdekim/game/service/CustomUserDetailsService.java @@ -0,0 +1,43 @@ +package com.alterdekim.game.service; + +import com.alterdekim.game.entities.Role; +import com.alterdekim.game.entities.User; +import com.alterdekim.game.repository.UserRepository; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.stream.Collectors; + +@Service +public class CustomUserDetailsService implements UserDetailsService { + + private final UserRepository userRepository; + + public CustomUserDetailsService(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + User user = userRepository.findByUsername(email); + + if (user != null) { + return new org.springframework.security.core.userdetails.User(user.getUsername(), + user.getPassword(), + mapRolesToAuthorities(user.getRoles())); + }else{ + throw new UsernameNotFoundException("Invalid username or password."); + } + } + + private Collection< ? extends GrantedAuthority> mapRolesToAuthorities(Collection roles) { + return roles.stream() + .map(role -> new SimpleGrantedAuthority(role.getName())) + .collect(Collectors.toList()); + } +} diff --git a/src/main/resources/templates/access-denied.html b/src/main/resources/templates/access-denied.html new file mode 100644 index 0000000..f321271 --- /dev/null +++ b/src/main/resources/templates/access-denied.html @@ -0,0 +1,16 @@ + + + + + + + + +
+

Access denied

+
+ + + + + \ No newline at end of file diff --git a/src/main/resources/templates/fragments/essentials.html b/src/main/resources/templates/fragments/essentials.html index f7d9dfc..08c6b86 100644 --- a/src/main/resources/templates/fragments/essentials.html +++ b/src/main/resources/templates/fragments/essentials.html @@ -1,6 +1,7 @@ + - + + + \ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html index fd2a3f5..ffd51a0 100644 --- a/src/main/resources/templates/login.html +++ b/src/main/resources/templates/login.html @@ -1,5 +1,5 @@ - + @@ -8,11 +8,11 @@

Login

- - + + - +
diff --git a/src/main/resources/templates/rules.html b/src/main/resources/templates/rules.html new file mode 100644 index 0000000..4c8e5f3 --- /dev/null +++ b/src/main/resources/templates/rules.html @@ -0,0 +1,56 @@ + + + + + + + + +
+

Terms of service

+

Last updated: 02/14/2024

+
1. Introduction:
+ +

Welcome to Nosedive! This document outlines the terms and conditions (the "Terms") governing your use of the game and its components. Please read these Terms carefully before playing. By playing the game, you agree to be bound by these Terms.

+ +
2. Ownership and Intellectual Property:
+ +

Nosedive is owned and operated by alterdekim. All intellectual property rights, including copyrights, trademarks, and patents, associated with the game belong to alterdekim.

+ +
3. Use of the Game:
+ +

This game is intended for private, non-commercial use only. You may not sell, reproduce, distribute, or modify the game or its components without our prior written consent.

+ +
4. Disclaimer of Warranties:
+ +

The game is provided "as is" and without any warranties, express or implied. We do not guarantee that the game will be free of errors or bugs.

+ +
5. Limitation of Liability:
+ +

We shall not be liable for any damages arising from your use of the game, including but not limited to, direct, indirect, incidental, consequential, or punitive damages.

+ +
6. Age Restriction:
+ +

This game is intended for players aged 18 and above. Parental supervision is recommended for younger players.

+ +
7. Changes to the Terms:
+ +

We reserve the right to modify these Terms at any time. Your continued use of the game following any changes constitutes your acceptance of the revised Terms.

+ +
8. Governing Law:
+ +

These Terms shall be governed by and construed in accordance with the laws of the United States of America.

+ +
9. Dispute Resolution:
+ +

Any dispute arising out of or relating to these Terms shall be submitted to binding arbitration in accordance with the rules of the American Arbitration Association. The arbitration shall be held in Texas, and the decision of the arbitrator shall be final and binding.

+ +
10. Contact Us:
+ +

If you have any questions about these Terms, please contact us at alterwain@protonmail.com

+
+ + + + + \ No newline at end of file diff --git a/src/main/resources/templates/signup.html b/src/main/resources/templates/signup.html index 1103390..5fcac9d 100644 --- a/src/main/resources/templates/signup.html +++ b/src/main/resources/templates/signup.html @@ -1,5 +1,5 @@ - + @@ -8,11 +8,14 @@

Sign up

- - + + + + + - +
@@ -20,7 +23,7 @@
- +
@@ -29,13 +32,15 @@
- -
- +
+ +

Already have an account? Login