Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cadastral/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

</dependencies>
<dependencyManagement>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.unipampa.crud.config.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableMethodSecurity
public class SecurityConfig {

private static final String HOST = "HOST";
private static final String ADMIN = "ADMINISTRATOR";
private static final String GUEST = "GUEST";
@Autowired
private UserDetailsServiceImpl userDetailsService;

private static final String[] PUBLIC_MATCHERS = {
"/users/**"
};

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.POST, PUBLIC_MATCHERS).permitAll()
.requestMatchers(HttpMethod.POST, "/accommodations/**").hasAnyRole(HOST, ADMIN)
.requestMatchers(HttpMethod.GET, "/accommodations/**").hasAnyRole(HOST, GUEST, ADMIN)
.requestMatchers(HttpMethod.GET, "/accommodations/{id}").hasAnyRole(HOST, GUEST, ADMIN)
.requestMatchers(HttpMethod.PUT, "/accommodations/{id}").hasAnyRole(HOST, ADMIN)
.requestMatchers(HttpMethod.DELETE, "/accommodations/{id}").hasAnyRole(HOST, ADMIN)

.requestMatchers(HttpMethod.GET, "/users").hasRole(ADMIN)
.requestMatchers(HttpMethod.GET, "/users/email/**").hasAnyRole(ADMIN, HOST, GUEST)
.requestMatchers(HttpMethod.GET, "/users/{id}").hasAnyRole(ADMIN, HOST, GUEST)
.requestMatchers(HttpMethod.PUT, "/users/{id}").hasAnyRole(ADMIN, HOST, GUEST)
.requestMatchers(HttpMethod.DELETE, "/users/{id}").hasAnyRole(ADMIN, HOST, GUEST)

.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults())
.csrf(AbstractHttpConfigurer::disable);
return http.build();
}

@Bean
public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder builder = http.getSharedObject(AuthenticationManagerBuilder.class);
builder.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
return builder.build();
}


@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.unipampa.crud.config.security;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;

public class SecurityUtil {

public static String getAuthenticatedUserId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication != null && authentication.getPrincipal() instanceof UserDatailsImpl userDetails) {
return userDetails.getUserId();
}

throw new RuntimeException("Usuário não autenticado!");
}

public static boolean isAuthenticatedAdmin() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication != null && authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMINISTRATOR"))) {
return true;
}
return false;
}

public static boolean isOwnerOrAdmin(String resourceUserId) {
String authenticatedUserId = getAuthenticatedUserId();
return isAuthenticatedAdmin() || authenticatedUserId.equals(resourceUserId);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.unipampa.crud.config.security;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.unipampa.crud.entities.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.io.Serial;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@Data
@AllArgsConstructor
public class UserDatailsImpl implements UserDetails {

@Serial
private static final long serialVersionUID = 4735505087197006457L;
private String userId;
private String fullName;
private String username;
@JsonIgnore
private String password;
private String email;
private Collection<? extends GrantedAuthority> authorities;

public static UserDatailsImpl build(User user) {
List<GrantedAuthority> authorities = user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority(role.getAuthority()))
.collect(Collectors.toList());

return new UserDatailsImpl (
user.getId(),
user.getName(),
user.getUserName(),
user.getPassword(),
user.getEmail(),
authorities);
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}

@Override
public String getPassword() {
return this.password;
}

@Override
public String getUsername() {
return this.username;
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.unipampa.crud.config.security;

import com.unipampa.crud.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
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 UserDetailsServiceImpl implements UserDetailsService {

public static final String USER_NOT_FOUND = "Usuário não encontrado para o nome de usuário: ";

@Autowired
private UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
var user = userRepository.findByUserName(username)
.orElseThrow(() -> new UsernameNotFoundException(USER_NOT_FOUND + username));
return UserDatailsImpl.build(user);
} catch (Exception e) {
throw new UsernameNotFoundException("Erro de conectividade ou ao carregar os dados do usuário: " + username, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,8 @@ public record AccommodationRequestDTO(
Integer maxOccupancy,

@Schema(example = "[\"https://img.com/1.jpg\", \"https://img.com/2.jpg\"]")
List<String> imagesUrls
List<String> imagesUrls,

@NotBlank
String hostId
) {}
7 changes: 4 additions & 3 deletions cadastral/src/main/java/com/unipampa/crud/dto/UserDTO.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.unipampa.crud.dto;

import com.unipampa.crud.enums.UserType;
import lombok.Data;

import com.unipampa.crud.enums.UserType;
import jakarta.validation.constraints.NotBlank;

public record UserDTO(
Expand All @@ -12,5 +11,7 @@ public record UserDTO(
@NotBlank String cpf,
@NotBlank String phone,
@NotBlank String address,
UserType type
@NotBlank String password,
@NotBlank String role,
@NotBlank UserType type
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
import com.unipampa.crud.enums.AccommodationType;
import lombok.Builder;
import lombok.Data;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;

import org.springframework.data.annotation.Id;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Builder
@Document
Expand Down Expand Up @@ -35,5 +38,6 @@ public class Accommodation {
private String state;
private int imageCount;
private int maxOccupancy;
private String hostId;

}
31 changes: 31 additions & 0 deletions cadastral/src/main/java/com/unipampa/crud/entities/Role.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.unipampa.crud.entities;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.unipampa.crud.enums.UserType;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.security.core.GrantedAuthority;

import java.io.Serializable;

@Document
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role implements GrantedAuthority, Serializable {
private static final long serialVersionUID = 1L;

@Id
private String id;

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private UserType roleName;

@Override
public String getAuthority() {
return this.roleName.toString();
}
}
11 changes: 11 additions & 0 deletions cadastral/src/main/java/com/unipampa/crud/entities/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@

import com.fasterxml.jackson.annotation.JsonFormat;
import com.unipampa.crud.enums.UserType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

@Builder
@Document
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {

private static final long serialVersionUID = 4477471521765649872L;
Expand All @@ -27,6 +34,10 @@ public class User implements Serializable {
private String name;
private UserType type;

@DBRef
private Set<Role> roles = new HashSet<>();


@Field
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
private LocalDateTime creationDate;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.unipampa.crud.enums;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;

public enum AccommodationType {
Expand All @@ -11,9 +9,4 @@ public enum AccommodationType {

@Schema(description = "Casa")
HOUSE;

// @JsonCreator
// public static AccommodationType fromString(String value) {
// return AccommodationType.valueOf(value.toUpperCase());
// }
}
14 changes: 3 additions & 11 deletions cadastral/src/main/java/com/unipampa/crud/enums/UserType.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
package com.unipampa.crud.enums;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public enum UserType {

HOST,

GUEST,
ROLE_HOST,

ADMINITSTRATOR;
ROLE_GUEST,

// @JsonCreator
// public static UserType fromString(String value) {
// return UserType.valueOf(value.toUpperCase());
// }
ROLE_ADMINISTRATOR;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.unipampa.crud.repository;

import com.unipampa.crud.entities.Role;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.Optional;


public interface RoleRepository extends MongoRepository<Role, String> {

Optional<Role> findRoleByRoleName(String name);

}
Loading