Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.

Commit 7a401d8

Browse files
FF-330 - ViewFolderContents updated to new sharing concept (#91)
* ViewFolderContents updated to new sharing concept * Implemented Refactorings from FF-296 * start with delete FeatureFile * Rewrote part of the logic, Implemented Ownerids, renamed to lastupdated. * adapt feature files to refactoring * minor changes. * Fixed failing request. Happy Easter btw lol * minor fix of feature files * Implemented getFolderContents with feature file. * Rewrote Deletion Endpoint. * Implemented recursive updating of timestamps * Updated Tests, fixed cov. * fix some preperation steps for delte, add check for last modified * dirty hack, have a better idea ? * bad things happen when you forget about that one little change you made ages ago * Finished UnitTests. Changed logger level to debug. * add return values to delte feature file * FF-331 rewrote deletion endpoint logic for the 12398th time. * Fixed tests. * Added missing coverage. Co-authored-by: open-schnick <[email protected]>
1 parent 61f88e4 commit 7a401d8

33 files changed

+1540
-1014
lines changed

.run/RestApplication-debug.run.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="RestApplication[DEBUG]" type="SpringBootApplicationConfigurationType"
3+
factoryName="Spring Boot">
4+
<module name="RestApi"/>
5+
<option name="SPRING_BOOT_MAIN_CLASS" value="de.filefighter.rest.RestApplication"/>
6+
<option name="ACTIVE_PROFILES" value="debug"/>
7+
<option name="ALTERNATIVE_JRE_PATH"/>
8+
<method v="2">
9+
<option name="Maven.BeforeRunTask" enabled="true" file="$PROJECT_DIR$/pom.xml" goal="clean compile"/>
10+
<option name="Make" enabled="true"/>
11+
</method>
12+
</configuration>
13+
</component>

src/main/java/de/filefighter/rest/configuration/CorsConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public CorsConfig() {
2525
}
2626

2727
@Bean
28-
@Profile({"dev","stage"})
28+
@Profile({"dev", "stage", "debug"})
2929
public CorsFilter corsFilterDev() {
3030
final CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues();
3131
ArrayList<String> allowedOrigins = new ArrayList<>();
@@ -39,7 +39,7 @@ public CorsFilter corsFilterDev() {
3939
}
4040

4141
@Bean
42-
@Profile({"prod","test"})
42+
@Profile({"prod"})
4343
public CorsFilter corsFilterProd() {
4444
final CorsConfiguration config = new CorsConfiguration();
4545
config.setAllowedMethods(allowedMethods);

src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public class PrepareDataBase {
4545
String date;
4646

4747
@Bean
48-
@Profile({"dev", "prod, stage"})
48+
@Profile({"dev", "prod, stage", "debug"})
4949
@Autowired
5050
CommandLineRunner veryImportantFileFighterStartScript(Environment environment) {
5151
return args -> {
@@ -70,12 +70,6 @@ CommandLineRunner veryImportantFileFighterStartScript(Environment environment) {
7070
System.out.println();
7171
System.out.println("-------------------------------< REST API >-------------------------------");
7272
System.out.println();
73-
74-
/*
75-
System.out.println("╭---╮")
76-
System.out.println("| |")
77-
System.out.println("╰---╯")
78-
*/
7973
};
8074
}
8175

@@ -91,26 +85,28 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo
9185
addDefaultAdminAndRuntimeUser(userRepository);
9286
log.info("Inserting Home directories and default structure: {} {}.", fileSystemRepository.save(FileSystemEntity
9387
.builder()
94-
.createdByUserId(RUNTIME_USER_ID)
88+
.lastUpdatedBy(RUNTIME_USER_ID)
89+
.lastUpdated(Instant.now().getEpochSecond())
90+
.ownerId(1)
9591
.fileSystemId(0)
9692
.isFile(false)
9793
.path("/")
9894
.itemIds(new long[0])
99-
.lastUpdated(Instant.now().getEpochSecond())
100-
.name("HOME_Admin")
95+
.name("HOME_1")
10196
.size(420)
10297
.typeId(FOLDER.getId())
10398
.visibleForGroupIds(new long[]{UNDEFINED.getGroupId(), FAMILY.getGroupId(), ADMIN.getGroupId()})
10499
.itemIds(new long[]{1})
105100
.build()),
106101
fileSystemRepository.save(FileSystemEntity.builder()
107-
.createdByUserId(1)
108-
.fileSystemId(1)
109-
.isFile(true)
102+
.lastUpdatedBy(RUNTIME_USER_ID)
110103
.lastUpdated(Instant.now().getEpochSecond())
104+
.ownerId(1).fileSystemId(1)
105+
.isFile(true)
111106
.name("dummyFile.txt")
112107
.size(420)
113108
.typeId(TEXT.getId())
109+
.mimeType("text/plain")
114110
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
115111
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
116112
.build()));
@@ -136,7 +132,7 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo
136132
}
137133

138134
@Bean
139-
@Profile("dev")
135+
@Profile({"dev", "debug"})
140136
CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepository accessTokenRepository, FileSystemRepository fileSystemRepository) {
141137
return args -> {
142138
log.info("Starting with clean user collection.");
@@ -198,7 +194,7 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo
198194
log.error("Inserting Users " + MESSAGE_ON_FAILURE);
199195
}
200196

201-
if (fileSystemRepository.findAll().size() == 6) {
197+
if (fileSystemRepository.findAll().size() == 8) {
202198
log.info("Inserting FileSystemEntities " + MESSAGE_ON_SUCCESS);
203199
} else {
204200
log.error("Inserting FileSystemEntities " + MESSAGE_ON_FAILURE);
@@ -266,75 +262,111 @@ private void addDefaultAdminAndRuntimeUser(UserRepository userRepository) {
266262
}
267263

268264
private void addTestingFileSystemItems(FileSystemRepository fileSystemRepository) {
269-
log.info("Inserting default fsItems:\n {}\n {}\n {}\n {}\n {}\n {}.",
265+
log.info("Inserting default fsItems:\n {}\n {}\n {}\n {}\n {}\n {}\n {}\n {}.",
270266
fileSystemRepository.save(FileSystemEntity.builder()
271-
.createdByUserId(RUNTIME_USER_ID)
267+
.lastUpdatedBy(RUNTIME_USER_ID)
268+
.ownerId(1)
269+
.lastUpdated(Instant.now().getEpochSecond())
272270
.fileSystemId(0)
273271
.isFile(false)
274272
.path("/")
275-
.itemIds(new long[]{2, 3})
276-
.lastUpdated(Instant.now().getEpochSecond())
277-
.name("HOME_User")
273+
.name("HOME_1")
278274
.size(4866)
279275
.typeId(FOLDER.getId())
276+
.itemIds(new long[]{2, 3, 7})
280277
.visibleForGroupIds(new long[]{FAMILY.getGroupId(), ADMIN.getGroupId()})
278+
.visibleForUserIds(new long[]{0})
279+
.editableForUserIds(new long[]{0})
281280
.build()),
282281
fileSystemRepository.save(FileSystemEntity.builder()
283-
.createdByUserId(RUNTIME_USER_ID)
282+
.lastUpdatedBy(RUNTIME_USER_ID)
283+
.lastUpdated(Instant.now().getEpochSecond())
284+
.ownerId(2)
284285
.fileSystemId(1)
285286
.isFile(false)
286287
.path("/")
287-
.lastUpdated(Instant.now().getEpochSecond())
288-
.name("HOME_User1")
288+
.name("HOME_2")
289289
.size(0)
290290
.typeId(FOLDER.getId())
291291
.visibleForGroupIds(new long[]{UNDEFINED.getGroupId(), FAMILY.getGroupId(), ADMIN.getGroupId()})
292+
.visibleForUserIds(new long[]{1})
293+
.editableForUserIds(new long[]{1})
292294
.build()),
293295
fileSystemRepository.save(FileSystemEntity.builder()
294-
.createdByUserId(1)
296+
.lastUpdatedBy(1)
297+
.lastUpdated(Instant.now().getEpochSecond())
298+
.ownerId(1)
295299
.fileSystemId(2)
296300
.isFile(true)
297-
.lastUpdated(Instant.now().getEpochSecond())
298301
.name("dummyFile.txt")
299302
.size(420)
300303
.typeId(TEXT.getId())
304+
.mimeType("text/plain")
301305
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
302306
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
303307
.build()),
304308
fileSystemRepository.save(FileSystemEntity.builder()
305-
.createdByUserId(1)
309+
.lastUpdatedBy(1)
310+
.lastUpdated(Instant.now().getEpochSecond())
311+
.ownerId(1)
312+
.fileSystemId(7)
313+
.isFile(true)
314+
.name("visibleNonDeletableText.tex")
315+
.size(42)
316+
.typeId(TEXT.getId())
317+
.mimeType("text/plain")
318+
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
319+
.build()),
320+
fileSystemRepository.save(FileSystemEntity.builder()
321+
.lastUpdatedBy(1)
322+
.lastUpdated(Instant.now().getEpochSecond())
323+
.ownerId(1)
306324
.fileSystemId(3)
307325
.isFile(false)
308326
.path("/somefolder")
309327
.name("SomeFolder")
310-
.lastUpdated(Instant.now().getEpochSecond())
311328
.size(4446)
312329
.typeId(FOLDER.getId())
313330
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
314331
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
315-
.itemIds(new long[]{4, 5})
332+
.itemIds(new long[]{4, 5, 6})
316333
.build()),
317334
fileSystemRepository.save(FileSystemEntity.builder()
318-
.createdByUserId(1)
335+
.lastUpdatedBy(1)
336+
.lastUpdated(Instant.now().getEpochSecond())
337+
.ownerId(1)
319338
.fileSystemId(4)
320339
.isFile(true)
321-
.lastUpdated(Instant.now().getEpochSecond())
322340
.name("secretFileInSomeFolder.txt")
323341
.size(3214)
324342
.typeId(TEXT.getId())
343+
.mimeType("text/plain")
325344
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
326345
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
327346
.build()),
328347
fileSystemRepository.save(FileSystemEntity.builder()
329-
.createdByUserId(1)
348+
.lastUpdatedBy(1)
349+
.lastUpdated(Instant.now().getEpochSecond())
350+
.ownerId(1)
330351
.fileSystemId(5)
331352
.isFile(true)
332-
.lastUpdated(Instant.now().getEpochSecond())
333353
.name("definitelyNotPorn.mp4")
334354
.size(1232)
335355
.typeId(VIDEO.getId())
356+
.mimeType("video/mp4")
336357
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
337358
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
359+
.build()),
360+
fileSystemRepository.save(FileSystemEntity.builder()
361+
.lastUpdatedBy(1)
362+
.lastUpdated(Instant.now().getEpochSecond())
363+
.ownerId(1)
364+
.fileSystemId(6)
365+
.isFile(true)
366+
.name("invisible_secret_video.mp4")
367+
.size(1232)
368+
.typeId(VIDEO.getId())
369+
.mimeType("video/mp4")
338370
.build())
339371
);
340372
}

src/main/java/de/filefighter/rest/domain/authentication/AuthenticationBusinessService.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package de.filefighter.rest.domain.authentication;
22

3-
import de.filefighter.rest.domain.common.exceptions.InputSanitizerService;
3+
import de.filefighter.rest.domain.common.InputSanitizerService;
44
import de.filefighter.rest.domain.common.exceptions.RequestDidntMeetFormalRequirementsException;
55
import de.filefighter.rest.domain.token.data.dto.AccessToken;
66
import de.filefighter.rest.domain.user.business.UserDTOService;
@@ -21,10 +21,12 @@ public class AuthenticationBusinessService {
2121

2222
private final UserRepository userRepository;
2323
private final UserDTOService userDtoService;
24+
private final InputSanitizerService inputSanitizerService;
2425

25-
public AuthenticationBusinessService(UserRepository userRepository, UserDTOService userDtoService) {
26+
public AuthenticationBusinessService(UserRepository userRepository, UserDTOService userDtoService, InputSanitizerService inputSanitizerService) {
2627
this.userRepository = userRepository;
2728
this.userDtoService = userDtoService;
29+
this.inputSanitizerService = inputSanitizerService;
2830
}
2931

3032
public User authenticateUserWithUsernameAndPassword(String base64encodedUserAndPassword) {
@@ -42,8 +44,8 @@ public User authenticateUserWithUsernameAndPassword(String base64encodedUserAndP
4244
if (split.length != 2)
4345
throw new RequestDidntMeetFormalRequirementsException("Credentials didnt meet formal requirements.");
4446

45-
String lowerCaseUsername = InputSanitizerService.sanitizeString(split[0].toLowerCase());
46-
String password = InputSanitizerService.sanitizeString(split[1]);
47+
String lowerCaseUsername = inputSanitizerService.sanitizeString(split[0].toLowerCase());
48+
String password = inputSanitizerService.sanitizeString(split[1]);
4749

4850
UserEntity userEntity = userRepository.findByLowercaseUsernameAndPassword(lowerCaseUsername, password);
4951
if (null == userEntity)

src/main/java/de/filefighter/rest/domain/authentication/AuthenticationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package de.filefighter.rest.domain.authentication;
22

3-
import de.filefighter.rest.domain.common.exceptions.InputSanitizerService;
3+
import de.filefighter.rest.domain.common.InputSanitizerService;
44
import de.filefighter.rest.domain.token.business.AccessTokenBusinessService;
55
import de.filefighter.rest.domain.token.data.dto.AccessToken;
66
import de.filefighter.rest.domain.user.data.dto.User;
Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
package de.filefighter.rest.domain.common.exceptions;
1+
package de.filefighter.rest.domain.common;
22

3+
import de.filefighter.rest.domain.common.exceptions.RequestDidntMeetFormalRequirementsException;
34
import org.springframework.stereotype.Service;
45

6+
import java.util.regex.Matcher;
7+
import java.util.regex.Pattern;
8+
59
@Service
610
public class InputSanitizerService {
711

@@ -10,18 +14,25 @@ public static boolean stringIsValid(String s) {
1014
}
1115

1216
/**
13-
*
1417
* Sanitizes a String, so it can be used.
18+
*
1519
* @param string String that needs to be sanitized.
1620
* @return string without whitespaces and without illegal characters.
1721
* @throws RequestDidntMeetFormalRequirementsException when string was empty.
1822
*/
19-
public static String sanitizeString(String string) {
20-
if(!InputSanitizerService.stringIsValid(string))
23+
public String sanitizeString(String string) {
24+
if (!InputSanitizerService.stringIsValid(string))
2125
throw new RequestDidntMeetFormalRequirementsException("String was empty.");
2226
return string.replaceAll("\\s", "");
2327
}
2428

29+
public String sanitizePath(String path) {
30+
if (!pathIsValid(path))
31+
throw new RequestDidntMeetFormalRequirementsException("Path was not valid.");
32+
33+
return sanitizeString(path);
34+
}
35+
2536
public String sanitizeRequestHeader(String header, String testString) {
2637
if (!(stringIsValid(testString) && stringIsValid(header)))
2738
throw new RequestDidntMeetFormalRequirementsException("Header does not contain a valid String.");
@@ -32,7 +43,18 @@ public String sanitizeRequestHeader(String header, String testString) {
3243
return split[1];
3344
}
3445

35-
public String sanitizeTokenValue(String tokenValue){
36-
return InputSanitizerService.sanitizeString(tokenValue);
46+
public boolean pathIsValid(String path) {
47+
String validString = sanitizeString(path);
48+
49+
Pattern pattern = Pattern.compile("[~#@*+:!?&%<>|\"^\\\\]");
50+
Matcher matcher = pattern.matcher(validString);
51+
52+
boolean stringContainsDoubleSlash = validString.contains("//");
53+
54+
return !(matcher.find() || stringContainsDoubleSlash);
55+
}
56+
57+
public String sanitizeTokenValue(String tokenValue) {
58+
return this.sanitizeString(tokenValue);
3759
}
3860
}

0 commit comments

Comments
 (0)