Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #564 - Support of Base64url encoding and decoding #870

Merged
merged 1 commit into from
Aug 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/overview.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,10 @@ Example: `'FRIEND|MENTORS>|<REPORTS_TO'` will match to :FRIEND relationships in
| apoc.text.byteCount(text,[charset]) | return size of text in bytes
| apoc.text.bytes(text,[charset]) - return bytes of the text
| apoc.text.toCypher(value, {skipKeys,keepKeys,skipValues,keepValues,skipNull,node,relationship,start,end}) | tries it's best to convert the value to a cypher-property-string
| apoc.text.base64Encode(text) - Encode a string with Base64
| apoc.text.base64Decode(text) - Decode Base64 encoded string
| apoc.text.base64UrlEncode(url) - Encode a url with Base64
| apoc.text.base64UrlDecode(url) - Decode Base64 encoded url
|===

=== Data Extraction
Expand Down
45 changes: 45 additions & 0 deletions docs/text.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,51 @@ RETURN apoc.text.toUpperCase("foo$$bar") // "FOO_BAR"
RETURN apoc.text.toUpperCase("foo 22 bar") // "FOO_22_BAR"


== Base64

Encode or decode a string in base64 or base64Url

_EncodeBase64_

[source,cypher]
RETURN apoc.text.base64Encode("neo4j") as value

result:

[source,text]
bmVvNGo=


_DecodeBase64_

[source,cypher]
RETURN apoc.text.base64Decode("bmVvNGo=") as value

result:

[source,text]
neo4j


_EncodeBase64Url_

[source,cypher]
RETURN apoc.text.base64EncodeUrl("http://neo4j.com/?test=test") as value

result:
[source,text]
aHR0cDovL25lbzRqLmNvbS8_dGVzdD10ZXN0

_DecodeBase64Url_

[source,cypher]
RETURN apoc.text.base64DecodeUrl("aHR0cDovL25lbzRqLmNvbS8_dGVzdD10ZXN0") as value

result:

[source,text]
http://neo4j.com/?test=test

== Random String

You can generate a random string to a specified length by calling `apoc.text.random` with a length parameter and optional string of valid characters.
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/apoc/text/Strings.java
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,20 @@ public String base64Decode(@Name("text") String text) {
return new String(decoded);
}

@UserFunction
@Description("apoc.text.base64UrlEncode(text) YIELD value - Encode a url with Base64")
public String base64UrlEncode(@Name("url") String url) {
byte[] encoded = Base64.getUrlEncoder().encode(url.getBytes());
return new String(encoded);
}

@UserFunction
@Description("apoc.text.base64UrlDecode(url) YIELD value - Decode Base64 encoded url")
public String base64UrlDecode(@Name("url") String url) {
byte[] decoded = Base64.getUrlDecoder().decode(url.getBytes());
return new String(decoded);
}

@UserFunction
@Description("apoc.text.charAt(text, index) - the decimal value of the character at the given index")
public Long charAt(@Name("text") String text, @Name("index") Long index) {
Expand Down
54 changes: 52 additions & 2 deletions src/test/java/apoc/text/StringsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ public void testRegexGroupsForNPE() {
testCall(db, "RETURN apoc.text.regexGroups(null,'<link (\\\\w+)>(\\\\w+)</link>') AS result", row -> { });
testCall(db, "RETURN apoc.text.regexGroups('abc',null) AS result", row -> { });
}

@Test
public void testSlug() {
testCall(db, "RETURN apoc.text.slug('a-b','-') AS value", row -> assertEquals("a-b", row.get("value")));
Expand Down Expand Up @@ -516,6 +516,56 @@ public void testBase64Decode() {
);
}


@Test
public void testBase64EncodeWithUrl() {
String text = "http://neo4j.com/?test=test";

testCall(
db,
"RETURN apoc.text.base64Encode({text}) as value",
map("text", text),
row -> assertEquals("aHR0cDovL25lbzRqLmNvbS8/dGVzdD10ZXN0", row.get("value").toString())
);
}

@Test
public void testBase64DecodeWithUrl() {
String text = "aHR0cDovL25lbzRqLmNvbS8/dGVzdD10ZXN0";

testCall(
db,
"RETURN apoc.text.base64Decode({text}) as value",
map("text", text),
row -> assertEquals("http://neo4j.com/?test=test", row.get("value").toString())
);
}

@Test
public void testBase64EncodeUrl() {
String text = "http://neo4j.com/?test=test";

testCall(
db,
"RETURN apoc.text.base64UrlEncode({text}) as value",
map("text", text),
row -> assertEquals("aHR0cDovL25lbzRqLmNvbS8_dGVzdD10ZXN0", row.get("value").toString())
);
}

@Test
public void testBase64DecodeUrl() {
String text = "aHR0cDovL25lbzRqLmNvbS8_dGVzdD10ZXN0";

testCall(
db,
"RETURN apoc.text.base64UrlDecode({text}) as value",
map("text", text),
row -> assertEquals("http://neo4j.com/?test=test", row.get("value").toString())
);
}


@Test
public void testSorensenDiceSimilarity() {
String text1 = "belly";
Expand All @@ -542,7 +592,7 @@ public void testSorensenDiceSimilarityWithTurkishLocale() {

@Test
public void testHexvalue() {
testCall(db, "RETURN [x IN {values} | apoc.text.hexValue(x)] as value",
testCall(db, "RETURN [x IN {values} | apoc.text.hexValue(x)] as value",
map("values", Arrays.<Long>asList(null,0L,1L,255L,65534L,65536L,305419896L,2309737967L,4294967294L,187723572702975L)),
row -> assertEquals(Arrays.<String>asList(null,"0000","0001","00FF","FFFE","00010000","12345678","89ABCDEF","FFFFFFFE","0000AABBCCDDEEFF"), row.get("value")));
}
Expand Down