Skip to content

Commit

Permalink
Merge pull request #1 from AndreaDev001/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
AndreaDev001 committed Nov 11, 2023
2 parents 9639cb1 + b962522 commit 280732b
Show file tree
Hide file tree
Showing 237 changed files with 12,948 additions and 6 deletions.
60 changes: 58 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
Expand All @@ -17,29 +18,80 @@
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
<artifactId>spring-boot-starter-hateoas</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.vladimir-bukhtoyarov</groupId>
<artifactId>bucket4j-core</artifactId>
<version>7.6.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.4.4</version>
</dependency>
</dependencies>

<build>
Expand All @@ -56,6 +108,10 @@
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.enterpriseapplications.progettoentepriseapplicationsspringboot;
package com.enterpriseapplications.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class EnterpriseApplicationsSpringBootApplication {

public static void main(String[] args) {
SpringApplication.run(EnterpriseApplicationsSpringBootApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.enterpriseapplications.springboot.config;


import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Configuration
@EnableCaching
@EnableScheduling
@Slf4j
public class CacheConfig
{
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH::mm:ss");
public static final String CACHE_SEARCH_PRODUCTS = "SEARCH_PRODUCTS";
public static final String CACHE_SEARCH_USERS = "SEARCH_USERS";
public static final String CACHE_SEARCH_REPORTS = "SEARCH_REPORTS";
public static final String CACHE_SEARCH_BANS = "SEARCH_BANS";
public static final String CACHE_ALL_PRODUCTS = "ALL_PRODUCTS";
public static final String CACHE_ALL_USERS = "ALL_USERS";
public static final String CACHE_ALL_REPORTS = "ALL_REPORTS";
public static final String CACHE_ALL_BANS = "ALL_PRODUCTS";
public static final String CACHE_BANNED_USERS = "BANNED_USERS";


@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager(CACHE_BANNED_USERS,CACHE_ALL_PRODUCTS,CACHE_ALL_USERS,CACHE_ALL_REPORTS,CACHE_ALL_BANS,CACHE_SEARCH_PRODUCTS,CACHE_SEARCH_USERS,CACHE_SEARCH_REPORTS,CACHE_SEARCH_BANS);
}

@CacheEvict(allEntries = true,value = {CACHE_SEARCH_PRODUCTS})
@Scheduled(fixedDelay = 5 * 60 * 1000, initialDelay = 1000)
public void productSearchCacheEvict() {
log.info(String.format("Cache [%s] has been flushed at [%s]",CACHE_SEARCH_PRODUCTS,dateTimeFormatter.format(LocalDateTime.now())));
}

@CacheEvict(allEntries = true,value = {CACHE_SEARCH_USERS})
@Scheduled(fixedDelay = 5 * 60 * 1000,initialDelay = 1000)
public void userSearchCacheEvict() {
log.info(String.format("Cache [%s] has been flushed at [%s]",CACHE_SEARCH_USERS,dateTimeFormatter.format(LocalDateTime.now())));
}

@CacheEvict(allEntries = true,value = {CACHE_SEARCH_REPORTS})
@Scheduled(fixedDelay = 5 * 60 * 1000,initialDelay = 1000)
public void reportsSearchCacheEvict() {
log.info(String.format("Cache [%s] has been flushed at [%s]",CACHE_SEARCH_REPORTS,dateTimeFormatter.format(LocalDateTime.now())));
}

@CacheEvict(allEntries = true,value = {CACHE_SEARCH_BANS})
@Scheduled(fixedDelay = 5 * 60 * 1000,initialDelay = 1000)
public void banSearchCacheEvict() {
log.info(String.format("Cache [%s] has been flushed at [%s]",CACHE_SEARCH_BANS,dateTimeFormatter.format(LocalDateTime.now())));
}

@CacheEvict(allEntries = true,value = {CACHE_ALL_PRODUCTS})
@Scheduled(fixedDelay = 5 * 60 * 1000,initialDelay = 1000)
public void allReportsCacheEvict() {
log.info(String.format("Cache [%s] has been flushed at [%s]",CACHE_ALL_REPORTS,dateTimeFormatter.format(LocalDateTime.now())));
}
@CacheEvict(allEntries = true,value = {CACHE_ALL_PRODUCTS})
@Scheduled(fixedDelay = 5 * 60 * 1000,initialDelay = 1000)
public void allBansCacheEvict() {
log.info(String.format("Cache [%s] has been flushed at [%s]",CACHE_ALL_BANS,dateTimeFormatter.format(LocalDateTime.now())));
}
@CacheEvict(allEntries = true,value = {CACHE_ALL_PRODUCTS})
@Scheduled(fixedDelay = 5 * 60 * 1000,initialDelay = 1000)
public void allUsersCacheEvict() {
log.info(String.format("Cache [%s] has been flushed at [%s]",CACHE_ALL_USERS,dateTimeFormatter.format(LocalDateTime.now())));
}
@CacheEvict(allEntries = true,value = {CACHE_ALL_BANS})
@Scheduled(fixedDelay = 24 * 60 * 60 * 1000,initialDelay = 1000)
public void bannedUserCacheEvict() {
log.info(String.format("Cache [%s] has been flushed at [%s]",CACHE_ALL_USERS,dateTimeFormatter.format(LocalDateTime.now())));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.enterpriseapplications.springboot.config;


import com.enterpriseapplications.springboot.data.dto.output.ConversationDto;
import com.enterpriseapplications.springboot.data.dto.output.GenericOutput;
import com.enterpriseapplications.springboot.data.dto.output.ProductDto;
import com.enterpriseapplications.springboot.data.dto.output.UserDetailsDto;
import com.enterpriseapplications.springboot.data.dto.output.refs.*;
import com.enterpriseapplications.springboot.data.entities.*;
import org.modelmapper.*;
import org.modelmapper.spi.MappingContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ui.ModelMap;

import java.util.UUID;

@Configuration
public class ModelMapperConfig
{

public static Converter<Product,ProductDto> productConverter = new Converter<Product, ProductDto>() {
@Override
public ProductDto convert(MappingContext<Product, ProductDto> mappingContext) {
mappingContext.getDestination().setAmountOfLikes(mappingContext.getSource().getReceivedLikes().size());
return mappingContext.getDestination();
}
};
public static Converter<User,UserDetailsDto> userConverter = new Converter<User, UserDetailsDto>() {
@Override
public UserDetailsDto convert(MappingContext<User, UserDetailsDto> mappingContext) {
User source = mappingContext.getSource();
UserDetailsDto destination = mappingContext.getDestination();
destination.setAmountOfFollowers(source.getFollowers().size());
destination.setAmountOfFollowed(source.getFollows().size());
destination.setAmountOfProducts(source.getProducts().size());
destination.setAmountOfLikes(source.getCreatedLikes().size());
destination.setAmountOfWrittenReviews(source.getWrittenReviews().size());
destination.setAmountOfReceivedReviews(source.getReceivedReviews().size());
destination.setAmountOfReplies(source.getWrittenReplies().size());
destination.setAmountOfReceivedBans(source.getCreatedBans().size());
return destination;
}
};

public static Converter<User,UserRef> userRefConverter = new AbstractConverter<User, UserRef>() {
@Override
protected UserRef convert(User user) {
return new UserRef(user);
}
};
public static Converter<Product, ProductRef> productRefConverter = new AbstractConverter<Product, ProductRef>() {
@Override
protected ProductRef convert(Product product) {
return new ProductRef(product);
}
};
public static Converter<Address, AddressRef> addressRefConverter = new AbstractConverter<Address, AddressRef>() {
@Override
protected AddressRef convert(Address address) {
return new AddressRef(address);
}
};
public static Converter<PaymentMethod,PaymentMethodRef> paymentMethodRefConverter = new AbstractConverter<PaymentMethod, PaymentMethodRef>() {
@Override
protected PaymentMethodRef convert(PaymentMethod paymentMethod) {
return new PaymentMethodRef(paymentMethod);
}
};
public static Converter<Conversation,ConversationRef> conversationRefConverter = new AbstractConverter<Conversation,ConversationRef>() {
@Override
protected ConversationRef convert(Conversation conversation) {
return new ConversationRef(conversation);
}
};

public static ModelMapper generateModelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setSkipNullEnabled(true);
modelMapper.getConfiguration().setAmbiguityIgnored(true);
modelMapper.getConfiguration().setFieldMatchingEnabled(true).setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE);
modelMapper.addConverter(userRefConverter);
modelMapper.addConverter(productRefConverter);
modelMapper.addConverter(addressRefConverter);
modelMapper.addConverter(paymentMethodRefConverter);
modelMapper.addConverter(conversationRefConverter);
modelMapper.createTypeMap(Product.class,ProductDto.class).setPostConverter(productConverter);
modelMapper.createTypeMap(User.class,UserDetailsDto.class).setPostConverter(userConverter);
return modelMapper;
}

@Bean
public ModelMapper modelMapper() {
return generateModelMapper();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.enterpriseapplications.springboot.config;


import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.security.SecurityScheme;

@OpenAPIDefinition(info =
@Info(title = "Documentazione Progetto Enterprise Applications",description = "API REST Enterprise Applications",version = "1.00"))
@SecurityScheme(name = "Authorization",type = SecuritySchemeType.HTTP,in = SecuritySchemeIn.HEADER,scheme = "bearer",bearerFormat = "JWT")
public class OpenApiConfig
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.enterpriseapplications.springboot.config;


import com.enterpriseapplications.springboot.data.entities.interfaces.MultiOwnableEntity;
import com.enterpriseapplications.springboot.data.entities.interfaces.OwnableEntity;
import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.UUID;

@Component
@RequiredArgsConstructor
public class PermissionHandler
{
public boolean hasRole(String requiredRole) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null) {
if(authentication instanceof JwtAuthenticationToken jwtAuthenticationToken) {
List<String> roles = (List<String>)jwtAuthenticationToken.getTokenAttributes().get("roles");
for(String role : roles)
if(role.equals(requiredRole))
return true;
}
}
return false;
}
public boolean isProvider(String requiredProvider) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null) {
if(authentication instanceof JwtAuthenticationToken jwtAuthenticationToken) {
String provider = (String)jwtAuthenticationToken.getTokenAttributes().get("provider");
return provider.equals(requiredProvider);
}
}
return false;
}

public boolean hasAccess(JpaRepository<OwnableEntity,UUID> repository, UUID resourceID) {
if(hasRole("ROLE_ADMIN"))
return true;
UUID userID = this.readUserID();
OwnableEntity ownableEntity = repository.findById(resourceID).orElseThrow();
return ownableEntity.getOwnerID().equals(userID);
}

public boolean hasAccessMulti(JpaRepository<MultiOwnableEntity,UUID> repository,UUID resourceID) {
if(hasRole("ROLE_ADMIN"))
return true;
UUID userID = this.readUserID();
MultiOwnableEntity multiOwnableEntity = repository.findById(resourceID).orElseThrow();
return multiOwnableEntity.getOwners().contains(userID);
}

private UUID readUserID() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication instanceof JwtAuthenticationToken jwtAuthenticationToken) {
String sub = (String)jwtAuthenticationToken.getTokenAttributes().get("sub");
UUID userID = UUID.fromString(sub);
return userID;
}
return null;
}
public boolean hasAccess(UUID userID) {
if(hasRole("ROLE_ADMIN"))
return true;
UUID requiredID = this.readUserID();
return requiredID.equals(userID);
}
}
Loading

0 comments on commit 280732b

Please sign in to comment.