Merge "Reject invalid hashtags with 400 Bad Request"

This commit is contained in:
Edwin Kempin
2017-09-19 09:10:56 +00:00
committed by Gerrit Code Review
3 changed files with 44 additions and 21 deletions

View File

@@ -30,6 +30,7 @@ import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.HashtagsInput;
import com.google.gerrit.extensions.common.ChangeMessageInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.testutil.TestTimeUtil;
import org.junit.AfterClass;
import org.junit.Before;
@@ -76,6 +77,15 @@ public class HashtagsIT extends AbstractDaemonTest {
assertMessage(r, "Hashtag added: tag1");
}
@Test
public void addInvalidHashtag() throws Exception {
PushOneCommit.Result r = createChange();
exception.expect(BadRequestException.class);
exception.expectMessage("hashtags may not contain commas");
addHashtags(r, "invalid,hashtag");
}
@Test
public void addMultipleHashtags() throws Exception {
PushOneCommit.Result r = createChange();

View File

@@ -23,6 +23,18 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HashtagsUtil {
public static class InvalidHashtagException extends Exception {
private static final long serialVersionUID = 1L;
static InvalidHashtagException hashtagsMayNotContainCommas() {
return new InvalidHashtagException("hashtags may not contain commas");
}
InvalidHashtagException(String message) {
super(message);
}
}
private static final CharMatcher LEADER = CharMatcher.whitespace().or(CharMatcher.is('#'));
private static final String PATTERN = "(?:\\s|\\A)#[\\p{L}[0-9]-_]+";
@@ -43,14 +55,14 @@ public class HashtagsUtil {
return result;
}
static Set<String> extractTags(Set<String> input) throws IllegalArgumentException {
static Set<String> extractTags(Set<String> input) throws InvalidHashtagException {
if (input == null) {
return Collections.emptySet();
}
HashSet<String> result = new HashSet<>();
for (String hashtag : input) {
if (hashtag.contains(",")) {
throw new IllegalArgumentException("Hashtags may not contain commas");
throw InvalidHashtagException.hashtagsMayNotContainCommas();
}
hashtag = cleanupHashtag(hashtag);
if (!hashtag.isEmpty()) {

View File

@@ -29,6 +29,7 @@ import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.change.HashtagsUtil.InvalidHashtagException;
import com.google.gerrit.server.extensions.events.HashtagsEdited;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
@@ -99,31 +100,31 @@ public class SetHashtagsOp implements BatchUpdateOp {
ChangeUpdate update = ctx.getUpdate(change.currentPatchSetId());
ChangeNotes notes = update.getNotes().load();
Set<String> existingHashtags = notes.getHashtags();
Set<String> updated = new HashSet<>();
toAdd = new HashSet<>(extractTags(input.add));
toRemove = new HashSet<>(extractTags(input.remove));
try {
Set<String> existingHashtags = notes.getHashtags();
Set<String> updated = new HashSet<>();
toAdd = new HashSet<>(extractTags(input.add));
toRemove = new HashSet<>(extractTags(input.remove));
for (HashtagValidationListener validator : validationListeners) {
validator.validateHashtags(update.getChange(), toAdd, toRemove);
}
} catch (ValidationException e) {
updated.addAll(existingHashtags);
toAdd.removeAll(existingHashtags);
toRemove.retainAll(existingHashtags);
if (updated()) {
updated.addAll(toAdd);
updated.removeAll(toRemove);
update.setHashtags(updated);
addMessage(ctx, update);
}
updatedHashtags = ImmutableSortedSet.copyOf(updated);
return true;
} catch (ValidationException | InvalidHashtagException e) {
throw new BadRequestException(e.getMessage());
}
updated.addAll(existingHashtags);
toAdd.removeAll(existingHashtags);
toRemove.retainAll(existingHashtags);
if (updated()) {
updated.addAll(toAdd);
updated.removeAll(toRemove);
update.setHashtags(updated);
addMessage(ctx, update);
}
updatedHashtags = ImmutableSortedSet.copyOf(updated);
return true;
}
private void addMessage(ChangeContext ctx, ChangeUpdate update) throws OrmException {