aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2019-01-30 16:40:15 +0300
committerGravatar Vitaly Takmazov2019-01-30 16:40:15 +0300
commit6d83f5614a5273ff53f1ddc5f4c614460e228993 (patch)
tree4369f064fbb7c9753d8df4b4cad8a5e152d03b40
parenta2a86393941e9520a8f8a126fbad0c4fad406720 (diff)
fix user deletion flow when invalid key is present
-rw-r--r--src/main/java/com/juick/server/SignatureManager.java45
-rw-r--r--src/main/java/com/juick/server/api/activity/Profile.java4
-rw-r--r--src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java25
-rw-r--r--src/test/java/com/juick/server/tests/ServerTests.java7
4 files changed, 44 insertions, 37 deletions
diff --git a/src/main/java/com/juick/server/SignatureManager.java b/src/main/java/com/juick/server/SignatureManager.java
index 032f71ee..c863ae0f 100644
--- a/src/main/java/com/juick/server/SignatureManager.java
+++ b/src/main/java/com/juick/server/SignatureManager.java
@@ -86,32 +86,33 @@ public class SignatureManager {
public User verifySignature(String method, String path, Map<String, String> headers) {
String signatureString = headers.get("signature");
- if (StringUtils.isNotEmpty(signatureString)) {
- logger.info("Signature: {}", signatureString);
- Signature signature = Signature.fromString(signatureString);
- Optional<Context> context = getContext(URI.create(signature.getKeyId()));
- if (context.isPresent() && context.get() instanceof Person) {
- Person person = (Person) context.get();
- Key key = KeystoreManager.publicKeyOf(person);
+ logger.info("Signature: {}", signatureString);
+ Signature signature = Signature.fromString(signatureString);
+ Optional<Context> context = getContext(UriComponentsBuilder.fromUriString(signature.getKeyId())
+ .fragment(null).build().toUri());
+ if (context.isPresent() && context.get() instanceof Person) {
+ Person person = (Person) context.get();
+ Key key = KeystoreManager.publicKeyOf(person);
- Verifier verifier = new Verifier(key, signature);
- try {
- boolean result = verifier.verify(method, path, headers);
- logger.info("signature of {} is valid: {}", signature.getKeyId(), result);
- if (result) {
- User user = new User();
- user.setUri(URI.create(person.getId()));
- if (key.equals(keystoreManager.getPublicKey())) {
- return userService.getUserByName(person.getName());
- }
- return user;
- } else {
- return AnonymousUser.INSTANCE;
+ Verifier verifier = new Verifier(key, signature);
+ try {
+ boolean result = verifier.verify(method, path, headers);
+ logger.info("signature of {} is valid: {}", signature.getKeyId(), result);
+ if (result) {
+ User user = new User();
+ user.setUri(URI.create(person.getId()));
+ if (key.equals(keystoreManager.getPublicKey())) {
+ return userService.getUserByName(person.getName());
}
- } catch (NoSuchAlgorithmException | SignatureException | IOException e) {
- logger.warn("Invalid signature {}", signatureString);
+ return user;
+ } else {
+ return AnonymousUser.INSTANCE;
}
+ } catch (NoSuchAlgorithmException | SignatureException | IOException e) {
+ logger.warn("Invalid signature {}", signatureString);
}
+ } else {
+ logger.warn("Unknown keyId");
}
return AnonymousUser.INSTANCE;
}
diff --git a/src/main/java/com/juick/server/api/activity/Profile.java b/src/main/java/com/juick/server/api/activity/Profile.java
index ff9df4fc..bd8b9ea8 100644
--- a/src/main/java/com/juick/server/api/activity/Profile.java
+++ b/src/main/java/com/juick/server/api/activity/Profile.java
@@ -358,9 +358,7 @@ public class Profile {
if (activity.getObject() instanceof String) {
// Delete gone user
if (activity.getActor().equals(activity.getObject())) {
- if (signatureManager.getContext(URI.create(activity.getActor())).isEmpty()) {
- return new ResponseEntity<>(HttpStatus.ACCEPTED);
- }
+ return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
}
}
diff --git a/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java b/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java
index 3fb16dce..22dc3b9c 100644
--- a/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java
+++ b/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java
@@ -4,6 +4,7 @@ import com.juick.User;
import com.juick.server.SignatureManager;
import com.juick.service.UserService;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
@@ -40,17 +41,19 @@ public class HTTPSignatureAuthenticationFilter extends OncePerRequestFilter {
Map<String, String> headers = Collections.list(request.getHeaderNames())
.stream()
.collect(Collectors.toMap(String::toLowerCase, request::getHeader));
- User user = signatureManager.verifySignature(request.getMethod(), request.getRequestURI(), headers);
- if (!user.isAnonymous()) {
- String userUri = user.getUri().toString();
- if (userUri.length() == 0) {
- User userWithPassword = userService.getUserByName(user.getName());
- userWithPassword.setAuthHash(userService.getHashByUID(userWithPassword.getUid()));
- Authentication authentication = new UsernamePasswordAuthenticationToken(userWithPassword.getName(), userWithPassword.getCredentials());
- SecurityContextHolder.getContext().setAuthentication(authentication);
- } else {
- Authentication authentication = new AnonymousAuthenticationToken(userUri, user, Collections.singletonList(new SimpleGrantedAuthority("ROLE_ANONYMOUS")));
- SecurityContextHolder.getContext().setAuthentication(authentication);
+ if (StringUtils.isNotEmpty(headers.get("signature"))) {
+ User user = signatureManager.verifySignature(request.getMethod(), request.getRequestURI(), headers);
+ if (!user.isAnonymous()) {
+ String userUri = user.getUri().toString();
+ if (userUri.length() == 0) {
+ User userWithPassword = userService.getUserByName(user.getName());
+ userWithPassword.setAuthHash(userService.getHashByUID(userWithPassword.getUid()));
+ Authentication authentication = new UsernamePasswordAuthenticationToken(userWithPassword.getName(), userWithPassword.getCredentials());
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ } else {
+ Authentication authentication = new AnonymousAuthenticationToken(userUri, user, Collections.singletonList(new SimpleGrantedAuthority("ROLE_ANONYMOUS")));
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
}
}
}
diff --git a/src/test/java/com/juick/server/tests/ServerTests.java b/src/test/java/com/juick/server/tests/ServerTests.java
index 5ee8b1f4..1e56668d 100644
--- a/src/test/java/com/juick/server/tests/ServerTests.java
+++ b/src/test/java/com/juick/server/tests/ServerTests.java
@@ -1896,12 +1896,17 @@ public class ServerTests {
Delete delete = jsonMapper.readValue(deleteJsonStr, Delete.class);
ClientHttpRequestFactory originalRequestFactory = apClient.getRequestFactory();
MockRestServiceServer restServiceServer = MockRestServiceServer.createServer(apClient);
- restServiceServer.expect(times(1), requestTo((String)delete.getObject()))
+ restServiceServer.expect(times(2), requestTo((String)delete.getObject()))
.andRespond(withStatus(HttpStatus.GONE));
mockMvc.perform(post("/api/inbox")
.contentType(ACTIVITY_MEDIA_TYPE)
.content(deleteJsonStr))
.andExpect(status().isAccepted());
+ mockMvc.perform(post("/api/inbox")
+ .contentType(ACTIVITY_MEDIA_TYPE)
+ .content(deleteJsonStr)
+ .header("Signature", "keyId=\"https://example.com/users/deleted#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest content-type\",signature=\"wHoU91JJBsIYcR1W1/57B0oG98t5Aa/TvGPw1B8KQlAp5KhpePnOzD1MZRgivBx7YKO6eYwDx+AX9dn6tjlAvzRLygv21H6UoDZFihWzeE1HM8pY2Pe4EhUgYBN0YuiKUi7W4TS9bDRAJ5vGNPUWATe+2o5Jcbux5cZYXFKKYbLBLD+/IlqPdHA2IXLZ52HFVVfBkPH5sSklV6XJtD/PHLK9R/I9w/mUpj9moUPQu44rR7KvxiGNuHla3vfDtJbkBqLMdScX91EG8373AulXPUiCCF7R2lJB0fFQedm2nSbcwBoJ32GEyOyOPFgPKG5zd9Fd5TfB1pmA8ZIE0sChfA==\""))
+ .andExpect(status().isAccepted());
apClient.setRequestFactory(originalRequestFactory);
}
}