login-regis

Thanh
Le Phuc 6 months ago
commit 43faab805b
  1. 38
      BE/.gitignore
  2. 8
      BE/.idea/.gitignore
  3. 7
      BE/.idea/encodings.xml
  4. 14
      BE/.idea/misc.xml
  5. 6
      BE/.idea/vcs.xml
  6. 85
      BE/pom.xml
  7. 11
      BE/src/main/java/org/example/Main.java
  8. 69
      BE/src/main/java/org/example/config/SecurityConfig.java
  9. 34
      BE/src/main/java/org/example/controllers/UserController.java
  10. 98
      BE/src/main/java/org/example/models/User.java
  11. 33
      BE/src/main/java/org/example/objects/UserDTO.java
  12. 20
      BE/src/main/java/org/example/queryresults/CourseEnrolmentQueryResult.java
  13. 20
      BE/src/main/java/org/example/repositories/UserRepository.java
  14. 49
      BE/src/main/java/org/example/requests/CreateUserRequest.java
  15. 24
      BE/src/main/java/org/example/services/NeoUserDetailsService.java
  16. 33
      BE/src/main/java/org/example/services/UserService.java
  17. 3
      BE/src/main/resources/application.properties
  18. 1
      FE

38
BE/.gitignore vendored

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>demoNeo4j</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>me.paulschwarz</groupId>
<artifactId>spring-dotenv</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.1.8</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,11 @@
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}

@ -0,0 +1,69 @@
package org.example.config;
import org.example.services.NeoUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
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.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final NeoUserDetailsService neoUserDetailsService;
public SecurityConfig(NeoUserDetailsService neoUserDetailsService) {
this.neoUserDetailsService = neoUserDetailsService;
}
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.csrf(AbstractHttpConfigurer::disable)
.cors(Customizer.withDefaults())
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/api/v1/auth/me"
).authenticated()
.anyRequest().permitAll()
)
.userDetailsService(neoUserDetailsService)
.httpBasic(Customizer.withDefaults())
.build();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
// TODO: make sure that the origin list comes from an environment file.
configuration.setAllowedOrigins(Arrays.asList("http://localhost:3001", "http://127.0.0.1:3000"));
configuration.setAllowedMethods(Arrays.asList("GET","POST","PATCH", "PUT", "DELETE", "OPTIONS", "HEAD"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Requestor-Type", "Content-Type"));
configuration.setExposedHeaders(Arrays.asList("X-Get-Header"));
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}

@ -0,0 +1,34 @@
package org.example.controllers;
import org.example.models.User;
import org.example.objects.UserDTO;
import org.example.requests.CreateUserRequest;
import org.example.services.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
@RestController
@RequestMapping("/api/v1/auth")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/me")
public String loggedInUserDetails(Principal principal) {
return principal.getName();
}
@PostMapping("/register")
public ResponseEntity<UserDTO> signUp(@RequestBody CreateUserRequest request) {
User user = userService.createUser(request);
UserDTO responseUser = new UserDTO(user.getName(), user.getUsername(), user.getRoles());
return new ResponseEntity<>(responseUser, HttpStatus.CREATED);
}
}

@ -0,0 +1,98 @@
package org.example.models;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Arrays;
import java.util.Collection;
@Node
public class User implements UserDetails {
@Id @GeneratedValue
private Long id;
private String name;
private String username;
private String password;
private String roles;
public User() {
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
@Override
public String getUsername() {
return username;
}
@Override
public String getPassword() {
return password;
}
public String getRoles() {
return roles;
}
public void setName(String name) {
this.name = name;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setRoles(String roles) {
this.roles = roles;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.stream(roles.split(","))
.map(SimpleGrantedAuthority::new)
.toList();
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", username='" + username + '\'' +
", roles='" + roles + '\'' +
'}';
}
}

@ -0,0 +1,33 @@
package org.example.objects;
public class UserDTO {
private String name;
private String username;
private String roles;
public UserDTO(String name, String username, String roles) {
this.name = name;
this.username = username;
this.roles = roles;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRoles() {
return roles;
}
public void setRoles(String roles) {
this.roles = roles;
}
}

@ -0,0 +1,20 @@
package org.example.queryresults;
import org.example.models.User;
public class CourseEnrolmentQueryResult {
private User user;
public CourseEnrolmentQueryResult() {
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}

@ -0,0 +1,20 @@
package org.example.repositories;
import org.example.models.User;
import org.example.queryresults.CourseEnrolmentQueryResult;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
import java.util.Optional;
public interface UserRepository extends Neo4jRepository<User, Long> {
Optional<User> findUserByUsername(String username);
@Query("MATCH (user:User), (course:Course) WHERE user.username = $username AND course.identifier = $identifier " +
"RETURN EXISTS((user)-[:ENROLLED_IN]->(course))")
Boolean findEnrolmentStatus(String username, String identifier);
@Query("MATCH (user:User), (course:Course) WHERE user.username = $username AND course.identifier = $identifier " +
"CREATE (user)-[:ENROLLED_IN]->(course) RETURN user, course")
CourseEnrolmentQueryResult createEnrolmentRelationship(String username, String identifier);
}

@ -0,0 +1,49 @@
package org.example.requests;
public class CreateUserRequest {
private String name;
private String username;
private String password;
private String roles;
public CreateUserRequest() {
}
public CreateUserRequest(String name, String username, String password, String roles) {
this.name = name;
this.username = username;
this.password = password;
this.roles = roles;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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 getRoles() {
return roles;
}
public void setRoles(String roles) {
this.roles = roles;
}
}

@ -0,0 +1,24 @@
package org.example.services;
import org.example.repositories.UserRepository;
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;
@Service
public class NeoUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
public NeoUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepository
.findUserByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("Username not found" + username));
}
}

@ -0,0 +1,33 @@
package org.example.services;
import org.example.models.User;
import org.example.repositories.UserRepository;
import org.example.requests.CreateUserRequest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
public User createUser(CreateUserRequest request) {
User user = new User();
user.setName(request.getName());
// TODO: make sure that this username doesn't exist.
user.setUsername(request.getUsername());
user.setRoles(request.getRoles());
user.setPassword(passwordEncoder.encode(request.getPassword()));
userRepository.save(user);
return user;
}
}

@ -0,0 +1,3 @@
spring.neo4j.uri=neo4j://localhost:7687
spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=12345678

1
FE

@ -0,0 +1 @@
Subproject commit 81ad3d154b3b36b98dc5c1179c7e7bfcd7a0b1b0
Loading…
Cancel
Save