Skip to content

Commit bffcd22

Browse files
committed
Initial commit
0 parents  commit bffcd22

File tree

84 files changed

+4913
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+4913
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.idea/
2+
target/

pom.xml

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns="http://maven.apache.org/POM/4.0.0"
5+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
6+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
7+
<modelVersion>4.0.0</modelVersion>
8+
9+
<groupId>com.github.danilkozyrev</groupId>
10+
<artifactId>file-storage-api</artifactId>
11+
<version>1.0</version>
12+
<packaging>jar</packaging>
13+
14+
<parent>
15+
<groupId>org.springframework.boot</groupId>
16+
<artifactId>spring-boot-starter-parent</artifactId>
17+
<version>2.1.6.RELEASE</version>
18+
</parent>
19+
20+
<properties>
21+
<java.version>11</java.version>
22+
<lombok.version>1.18.8</lombok.version>
23+
<mapstruct.version>1.3.0.Final</mapstruct.version>
24+
<springfox.version>2.9.2</springfox.version>
25+
<jaxb.version>2.3.2</jaxb.version>
26+
</properties>
27+
28+
<dependencies>
29+
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
30+
<dependency>
31+
<groupId>org.springframework.boot</groupId>
32+
<artifactId>spring-boot-starter-web</artifactId>
33+
</dependency>
34+
35+
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator -->
36+
<dependency>
37+
<groupId>org.springframework.boot</groupId>
38+
<artifactId>spring-boot-starter-actuator</artifactId>
39+
</dependency>
40+
41+
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
42+
<dependency>
43+
<groupId>org.springframework.boot</groupId>
44+
<artifactId>spring-boot-starter-data-jpa</artifactId>
45+
</dependency>
46+
47+
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation -->
48+
<dependency>
49+
<groupId>org.springframework.boot</groupId>
50+
<artifactId>spring-boot-starter-validation</artifactId>
51+
</dependency>
52+
53+
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
54+
<dependency>
55+
<groupId>org.springframework.boot</groupId>
56+
<artifactId>spring-boot-starter-security</artifactId>
57+
</dependency>
58+
59+
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
60+
<dependency>
61+
<groupId>org.springframework.boot</groupId>
62+
<artifactId>spring-boot-starter-test</artifactId>
63+
<scope>test</scope>
64+
</dependency>
65+
66+
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-configuration-processor -->
67+
<dependency>
68+
<groupId>org.springframework.boot</groupId>
69+
<artifactId>spring-boot-configuration-processor</artifactId>
70+
</dependency>
71+
72+
<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 -->
73+
<dependency>
74+
<groupId>org.springframework.security.oauth</groupId>
75+
<artifactId>spring-security-oauth2</artifactId>
76+
<version>2.3.6.RELEASE</version>
77+
</dependency>
78+
79+
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
80+
<dependency>
81+
<groupId>org.projectlombok</groupId>
82+
<artifactId>lombok</artifactId>
83+
<version>${lombok.version}</version>
84+
<scope>provided</scope>
85+
</dependency>
86+
87+
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
88+
<dependency>
89+
<groupId>org.postgresql</groupId>
90+
<artifactId>postgresql</artifactId>
91+
<scope>runtime</scope>
92+
</dependency>
93+
94+
<!-- https://mvnrepository.com/artifact/org.passay/passay -->
95+
<dependency>
96+
<groupId>org.passay</groupId>
97+
<artifactId>passay</artifactId>
98+
<version>1.5.0</version>
99+
</dependency>
100+
101+
<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-core -->
102+
<dependency>
103+
<groupId>org.apache.tika</groupId>
104+
<artifactId>tika-core</artifactId>
105+
<version>1.21</version>
106+
</dependency>
107+
108+
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
109+
<dependency>
110+
<groupId>com.auth0</groupId>
111+
<artifactId>java-jwt</artifactId>
112+
<version>3.8.1</version>
113+
</dependency>
114+
115+
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
116+
<dependency>
117+
<groupId>org.mapstruct</groupId>
118+
<artifactId>mapstruct</artifactId>
119+
<version>${mapstruct.version}</version>
120+
</dependency>
121+
122+
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
123+
<dependency>
124+
<groupId>org.mapstruct</groupId>
125+
<artifactId>mapstruct-processor</artifactId>
126+
<version>${mapstruct.version}</version>
127+
<scope>provided</scope>
128+
</dependency>
129+
130+
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
131+
<dependency>
132+
<groupId>io.springfox</groupId>
133+
<artifactId>springfox-swagger2</artifactId>
134+
<version>${springfox.version}</version>
135+
</dependency>
136+
137+
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
138+
<dependency>
139+
<groupId>io.springfox</groupId>
140+
<artifactId>springfox-swagger-ui</artifactId>
141+
<version>${springfox.version}</version>
142+
</dependency>
143+
144+
<!-- https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api -->
145+
<dependency>
146+
<groupId>jakarta.xml.bind</groupId>
147+
<artifactId>jakarta.xml.bind-api</artifactId>
148+
<version>${jaxb.version}</version>
149+
</dependency>
150+
151+
<!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
152+
<dependency>
153+
<groupId>org.glassfish.jaxb</groupId>
154+
<artifactId>jaxb-runtime</artifactId>
155+
<version>${jaxb.version}</version>
156+
</dependency>
157+
</dependencies>
158+
159+
<build>
160+
<plugins>
161+
<plugin>
162+
<groupId>org.springframework.boot</groupId>
163+
<artifactId>spring-boot-maven-plugin</artifactId>
164+
</plugin>
165+
<plugin>
166+
<groupId>org.apache.maven.plugins</groupId>
167+
<artifactId>maven-compiler-plugin</artifactId>
168+
<version>3.8.0</version>
169+
<configuration>
170+
<annotationProcessorPaths>
171+
<path>
172+
<groupId>org.mapstruct</groupId>
173+
<artifactId>mapstruct-processor</artifactId>
174+
<version>${mapstruct.version}</version>
175+
</path>
176+
<path>
177+
<groupId>org.projectlombok</groupId>
178+
<artifactId>lombok</artifactId>
179+
<version>${lombok.version}</version>
180+
</path>
181+
</annotationProcessorPaths>
182+
<compilerArgs>
183+
<compilerArg>
184+
-Amapstruct.defaultComponentModel=spring
185+
</compilerArg>
186+
</compilerArgs>
187+
</configuration>
188+
</plugin>
189+
</plugins>
190+
</build>
191+
</project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.github.danilkozyrev.filestorageapi;
2+
3+
import com.github.danilkozyrev.filestorageapi.config.ApplicationProperties;
4+
import org.springframework.boot.SpringApplication;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
7+
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
8+
import org.springframework.transaction.annotation.EnableTransactionManagement;
9+
10+
@SpringBootApplication
11+
@EnableConfigurationProperties(ApplicationProperties.class)
12+
@EnableTransactionManagement(order = 1000)
13+
@EnableJpaRepositories(enableDefaultTransactions = false)
14+
public class Application {
15+
16+
public static void main(String[] args) {
17+
SpringApplication.run(Application.class, args);
18+
}
19+
20+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.github.danilkozyrev.filestorageapi.config;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
import org.springframework.boot.context.properties.ConfigurationProperties;
6+
7+
/**
8+
* Application-specific configuration properties.
9+
*/
10+
@ConfigurationProperties("application")
11+
@Getter
12+
@Setter
13+
public class ApplicationProperties {
14+
15+
/**
16+
* Base folder for uploaded files.
17+
*/
18+
private String baseFolder;
19+
20+
/**
21+
* Base storage limit in bytes.
22+
*/
23+
private Long baseLimit;
24+
25+
/**
26+
* Encryption key for signing file tokens.
27+
*/
28+
private String fileTokenSecret;
29+
30+
/**
31+
* File token validity time in seconds.
32+
*/
33+
private Long fileTokenValidity;
34+
35+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.github.danilkozyrev.filestorageapi.config;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.springframework.context.ApplicationContext;
5+
import org.springframework.security.access.PermissionEvaluator;
6+
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
7+
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
8+
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
9+
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
10+
11+
// Executed after @Transactional advice, so requests in permission evaluator are cached.
12+
@EnableGlobalMethodSecurity(prePostEnabled = true, order = 2000)
13+
@RequiredArgsConstructor
14+
public class GlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
15+
16+
private final ApplicationContext applicationContext;
17+
private final PermissionEvaluator permissionEvaluator;
18+
19+
@Override
20+
protected MethodSecurityExpressionHandler createExpressionHandler() {
21+
OAuth2MethodSecurityExpressionHandler expressionHandler = new OAuth2MethodSecurityExpressionHandler();
22+
expressionHandler.setApplicationContext(applicationContext);
23+
expressionHandler.setPermissionEvaluator(permissionEvaluator);
24+
return expressionHandler;
25+
}
26+
27+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.github.danilkozyrev.filestorageapi.config;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.springframework.context.annotation.Bean;
5+
import org.springframework.context.annotation.Configuration;
6+
import org.springframework.security.authentication.AuthenticationManager;
7+
import org.springframework.security.core.userdetails.UserDetailsService;
8+
import org.springframework.security.crypto.password.PasswordEncoder;
9+
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
10+
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
11+
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
12+
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
13+
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
14+
import org.springframework.security.oauth2.provider.token.TokenStore;
15+
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
16+
17+
@Configuration
18+
@EnableAuthorizationServer
19+
@RequiredArgsConstructor
20+
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
21+
22+
private final AuthenticationManager authenticationManager;
23+
private final PasswordEncoder passwordEncoder;
24+
private final UserDetailsService userDetailsService;
25+
26+
@Bean
27+
public TokenStore tokenStore() {
28+
return new InMemoryTokenStore();
29+
}
30+
31+
@Override
32+
public void configure(AuthorizationServerSecurityConfigurer security) {
33+
security
34+
.tokenKeyAccess("permitAll()")
35+
.checkTokenAccess("isAuthenticated()")
36+
.passwordEncoder(passwordEncoder);
37+
}
38+
39+
@Override
40+
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
41+
clients
42+
.inMemory()
43+
44+
// Sample confidential client where client secret can be kept safe.
45+
.withClient("confidential")
46+
.secret(passwordEncoder.encode("confidential"))
47+
.authorizedGrantTypes("authorization_code", "refresh_token")
48+
.scopes("read", "write", "full")
49+
.redirectUris("https://localhost:8443/confidential")
50+
.accessTokenValiditySeconds(3600)
51+
.refreshTokenValiditySeconds(7 * 24 * 3600)
52+
53+
.and()
54+
55+
// Sample public client where client secret is vulnerable.
56+
.withClient("public")
57+
.authorizedGrantTypes("implicit")
58+
.scopes("read", "write", "full")
59+
.redirectUris("https://localhost:8443/public")
60+
.accessTokenValiditySeconds(3600)
61+
62+
.and()
63+
64+
// Swagger client.
65+
.withClient("swagger")
66+
.authorizedGrantTypes("implicit")
67+
.scopes("read", "write", "full")
68+
.redirectUris("https://localhost:8443/webjars/springfox-swagger-ui/oauth2-redirect.html")
69+
.accessTokenValiditySeconds(3600)
70+
.autoApprove(true);
71+
}
72+
73+
@Override
74+
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
75+
endpoints
76+
.tokenStore(tokenStore())
77+
.authenticationManager(authenticationManager)
78+
.userDetailsService(userDetailsService);
79+
}
80+
81+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.github.danilkozyrev.filestorageapi.config;
2+
3+
import org.springframework.context.annotation.Configuration;
4+
import org.springframework.http.HttpMethod;
5+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
6+
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
7+
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
8+
9+
@Configuration
10+
@EnableResourceServer
11+
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
12+
13+
@Override
14+
public void configure(HttpSecurity http) throws Exception {
15+
http
16+
.requestMatchers()
17+
.antMatchers("/api/**")
18+
.and()
19+
.authorizeRequests()
20+
.antMatchers(HttpMethod.GET, "/api/users/**")
21+
.access("#oauth2.hasAnyScope('read', 'full')")
22+
.antMatchers("/api/users/**")
23+
.access("#oauth2.hasScope('full')")
24+
.antMatchers(HttpMethod.GET)
25+
.access("#oauth2.hasAnyScope('read', 'full')")
26+
.anyRequest()
27+
.access("#oauth2.hasAnyScope('write', 'full')");
28+
}
29+
30+
}

0 commit comments

Comments
 (0)