Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
briar
briar
Commits
d665fc17
Verified
Commit
d665fc17
authored
Dec 13, 2021
by
Torsten Grote
Browse files
Add /status and /setup mailbox API call with tests
parent
65be2d2b
Changes
8
Hide whitespace changes
Inline
Side-by-side
bramble-core/build.gradle
View file @
d665fc17
...
...
@@ -20,6 +20,7 @@ dependencies {
//noinspection GradleDependency
implementation
"com.squareup.okhttp3:okhttp:$okhttp_version"
implementation
"com.fasterxml.jackson.core:jackson-databind:$jackson_version"
annotationProcessor
"com.google.dagger:dagger-compiler:$dagger_version"
...
...
@@ -30,6 +31,7 @@ dependencies {
testImplementation
"org.jmock:jmock:$jmock_version"
testImplementation
"org.jmock:jmock-junit4:$jmock_version"
testImplementation
"org.jmock:jmock-imposters:$jmock_version"
testImplementation
"com.squareup.okhttp3:mockwebserver:4.9.3"
testAnnotationProcessor
"com.google.dagger:dagger-compiler:$dagger_version"
...
...
bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java
0 → 100644
View file @
d665fc17
package
org.briarproject.bramble.mailbox
;
import
java.io.IOException
;
import
javax.annotation.concurrent.Immutable
;
interface
MailboxApi
{
/**
* Sets up the mailbox with the setup token.
*
* @param properties MailboxProperties with the setup token
* @return the owner token
* @throws PermanentFailureException for 401 response.
*/
String
setup
(
MailboxProperties
properties
)
throws
IOException
,
PermanentFailureException
;
/**
* Checks the status of the mailbox.
*
* @return true if the status is OK, false otherwise.
* @throws PermanentFailureException for 401 response.
*/
boolean
checkStatus
(
MailboxProperties
properties
)
throws
IOException
,
PermanentFailureException
;
@Immutable
class
MailboxProperties
{
final
String
baseUrl
;
final
String
token
;
final
boolean
isOwner
;
MailboxProperties
(
String
baseUrl
,
String
token
,
boolean
isOwner
)
{
this
.
baseUrl
=
baseUrl
;
this
.
token
=
token
;
this
.
isOwner
=
isOwner
;
}
}
@Immutable
class
PermanentFailureException
extends
Exception
{
/**
* If true, the failure is fatal and requires user attention.
* The entire task queue will most likely need to stop.
*/
final
boolean
fatal
;
PermanentFailureException
(
boolean
fatal
)
{
this
.
fatal
=
fatal
;
}
}
}
bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApiImpl.java
0 → 100644
View file @
d665fc17
package
org.briarproject.bramble.mailbox
;
import
com.fasterxml.jackson.core.JacksonException
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.json.JsonMapper
;
import
org.briarproject.bramble.api.WeakSingletonProvider
;
import
org.briarproject.bramble.api.nullsafety.NotNullByDefault
;
import
java.io.IOException
;
import
javax.inject.Inject
;
import
okhttp3.OkHttpClient
;
import
okhttp3.Request
;
import
okhttp3.Response
;
import
okhttp3.ResponseBody
;
import
static
com
.
fasterxml
.
jackson
.
databind
.
MapperFeature
.
BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES
;
import
static
okhttp3
.
internal
.
Util
.
EMPTY_REQUEST
;
@NotNullByDefault
class
MailboxApiImpl
implements
MailboxApi
{
private
final
WeakSingletonProvider
<
OkHttpClient
>
httpClientProvider
;
private
final
JsonMapper
mapper
=
JsonMapper
.
builder
()
.
enable
(
BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES
)
.
build
();
@Inject
MailboxApiImpl
(
WeakSingletonProvider
<
OkHttpClient
>
httpClientProvider
)
{
this
.
httpClientProvider
=
httpClientProvider
;
}
@Override
public
String
setup
(
MailboxProperties
properties
)
throws
IOException
,
PermanentFailureException
{
if
(!
properties
.
isOwner
)
throw
new
IllegalArgumentException
();
Request
request
=
getRequestBuilder
(
properties
.
token
)
.
url
(
properties
.
baseUrl
+
"/setup"
)
.
put
(
EMPTY_REQUEST
)
.
build
();
OkHttpClient
client
=
httpClientProvider
.
get
();
Response
response
=
client
.
newCall
(
request
).
execute
();
if
(
response
.
code
()
==
401
)
{
throw
new
PermanentFailureException
(
true
);
}
if
(!
response
.
isSuccessful
())
throw
new
IOException
();
ResponseBody
body
=
response
.
body
();
if
(
body
==
null
)
throw
new
PermanentFailureException
(
false
);
try
{
JsonNode
node
=
mapper
.
readTree
(
body
.
string
());
JsonNode
tokenNode
=
node
.
get
(
"token"
);
if
(
tokenNode
==
null
)
{
throw
new
PermanentFailureException
(
false
);
}
String
ownerToken
=
tokenNode
.
textValue
();
if
(
ownerToken
==
null
)
{
throw
new
PermanentFailureException
(
false
);
}
return
ownerToken
;
}
catch
(
JacksonException
e
)
{
throw
new
PermanentFailureException
(
false
);
}
}
@Override
public
boolean
checkStatus
(
MailboxProperties
properties
)
throws
IOException
,
PermanentFailureException
{
if
(!
properties
.
isOwner
)
throw
new
IllegalArgumentException
();
Request
request
=
getRequestBuilder
(
properties
.
token
)
.
url
(
properties
.
baseUrl
+
"/status"
)
.
build
();
OkHttpClient
client
=
httpClientProvider
.
get
();
Response
response
=
client
.
newCall
(
request
).
execute
();
if
(
response
.
code
()
==
401
)
{
throw
new
PermanentFailureException
(
true
);
}
return
response
.
isSuccessful
();
}
private
Request
.
Builder
getRequestBuilder
(
String
token
)
{
return
new
Request
.
Builder
()
.
addHeader
(
"Authorization"
,
"Bearer "
+
token
);
}
}
bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java
0 → 100644
View file @
d665fc17
package
org.briarproject.bramble.mailbox
;
import
org.briarproject.bramble.api.WeakSingletonProvider
;
import
org.briarproject.bramble.mailbox.MailboxApi.MailboxProperties
;
import
org.briarproject.bramble.mailbox.MailboxApi.PermanentFailureException
;
import
org.briarproject.bramble.test.BrambleTestCase
;
import
org.junit.Test
;
import
java.io.IOException
;
import
javax.annotation.Nonnull
;
import
javax.net.SocketFactory
;
import
okhttp3.OkHttpClient
;
import
okhttp3.mockwebserver.MockResponse
;
import
okhttp3.mockwebserver.MockWebServer
;
import
okhttp3.mockwebserver.RecordedRequest
;
import
static
java
.
util
.
concurrent
.
TimeUnit
.
MILLISECONDS
;
import
static
org
.
briarproject
.
bramble
.
util
.
StringUtils
.
getRandomString
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertThrows
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
public
class
MailboxApiTest
extends
BrambleTestCase
{
private
final
OkHttpClient
client
=
new
OkHttpClient
.
Builder
()
.
socketFactory
(
SocketFactory
.
getDefault
())
.
connectTimeout
(
60_000
,
MILLISECONDS
)
.
build
();
private
final
WeakSingletonProvider
<
OkHttpClient
>
httpClientProvider
=
new
WeakSingletonProvider
<
OkHttpClient
>()
{
@Override
@Nonnull
public
OkHttpClient
createInstance
()
{
return
client
;
}
};
private
final
MailboxApiImpl
api
=
new
MailboxApiImpl
(
httpClientProvider
);
private
final
String
token
=
getRandomString
(
64
);
private
final
String
token2
=
getRandomString
(
64
);
@Test
public
void
testSetup
()
throws
Exception
{
String
validResponse
=
"{\"token\":\""
+
token2
+
"\"}"
;
String
invalidResponse
=
"{\"foo\":\"bar\"}"
;
String
invalidTokenResponse
=
"{\"token\":{\"foo\":\"bar\"}}"
;
MockWebServer
server
=
new
MockWebServer
();
server
.
enqueue
(
new
MockResponse
().
setBody
(
validResponse
));
server
.
enqueue
(
new
MockResponse
());
server
.
enqueue
(
new
MockResponse
().
setBody
(
invalidResponse
));
server
.
enqueue
(
new
MockResponse
().
setResponseCode
(
401
));
server
.
enqueue
(
new
MockResponse
().
setResponseCode
(
500
));
server
.
enqueue
(
new
MockResponse
().
setBody
(
invalidTokenResponse
));
server
.
start
();
String
baseUrl
=
getBaseUrl
(
server
);
MailboxProperties
properties
=
new
MailboxProperties
(
baseUrl
,
token
,
true
);
MailboxProperties
properties2
=
new
MailboxProperties
(
baseUrl
,
token2
,
true
);
assertEquals
(
token2
,
api
.
setup
(
properties
));
PermanentFailureException
e2
=
assertThrows
(
PermanentFailureException
.
class
,
()
->
api
.
setup
(
properties
)
);
PermanentFailureException
e3
=
assertThrows
(
PermanentFailureException
.
class
,
()
->
api
.
setup
(
properties
)
);
PermanentFailureException
e4
=
assertThrows
(
PermanentFailureException
.
class
,
()
->
api
.
setup
(
properties2
)
);
assertThrows
(
IOException
.
class
,
()
->
api
.
setup
(
properties
)
);
PermanentFailureException
e6
=
assertThrows
(
PermanentFailureException
.
class
,
()
->
api
.
setup
(
properties
)
);
RecordedRequest
request1
=
server
.
takeRequest
();
assertEquals
(
"/setup"
,
request1
.
getPath
());
assertEquals
(
"PUT"
,
request1
.
getMethod
());
assertToken
(
request1
,
token
);
RecordedRequest
request2
=
server
.
takeRequest
();
assertEquals
(
"/setup"
,
request2
.
getPath
());
assertEquals
(
"PUT"
,
request2
.
getMethod
());
assertToken
(
request2
,
token
);
assertFalse
(
e2
.
fatal
);
RecordedRequest
request3
=
server
.
takeRequest
();
assertEquals
(
"/setup"
,
request3
.
getPath
());
assertEquals
(
"PUT"
,
request3
.
getMethod
());
assertToken
(
request3
,
token
);
assertFalse
(
e3
.
fatal
);
RecordedRequest
request4
=
server
.
takeRequest
();
assertEquals
(
"/setup"
,
request4
.
getPath
());
assertEquals
(
"PUT"
,
request4
.
getMethod
());
assertToken
(
request4
,
token2
);
assertTrue
(
e4
.
fatal
);
RecordedRequest
request5
=
server
.
takeRequest
();
assertEquals
(
"/setup"
,
request5
.
getPath
());
assertEquals
(
"PUT"
,
request5
.
getMethod
());
assertToken
(
request5
,
token
);
RecordedRequest
request6
=
server
.
takeRequest
();
assertEquals
(
"/setup"
,
request6
.
getPath
());
assertEquals
(
"PUT"
,
request6
.
getMethod
());
assertToken
(
request6
,
token
);
assertFalse
(
e6
.
fatal
);
}
@Test
public
void
testSetupOnlyForOwner
()
{
MailboxProperties
properties
=
new
MailboxProperties
(
""
,
token
,
false
);
assertThrows
(
IllegalArgumentException
.
class
,
()
->
api
.
setup
(
properties
)
);
}
@Test
public
void
testStatus
()
throws
Exception
{
MockWebServer
server
=
new
MockWebServer
();
server
.
enqueue
(
new
MockResponse
());
server
.
enqueue
(
new
MockResponse
().
setResponseCode
(
401
));
server
.
enqueue
(
new
MockResponse
().
setResponseCode
(
500
));
server
.
start
();
String
baseUrl
=
getBaseUrl
(
server
);
MailboxProperties
properties
=
new
MailboxProperties
(
baseUrl
,
token
,
true
);
MailboxProperties
properties2
=
new
MailboxProperties
(
baseUrl
,
token2
,
true
);
assertTrue
(
api
.
checkStatus
(
properties
));
PermanentFailureException
e2
=
assertThrows
(
PermanentFailureException
.
class
,
()
->
api
.
checkStatus
(
properties2
)
);
assertFalse
(
api
.
checkStatus
(
properties
));
RecordedRequest
request1
=
server
.
takeRequest
();
assertEquals
(
"/status"
,
request1
.
getPath
());
assertToken
(
request1
,
token
);
RecordedRequest
request2
=
server
.
takeRequest
();
assertEquals
(
"/status"
,
request2
.
getPath
());
assertToken
(
request2
,
token2
);
assertTrue
(
e2
.
fatal
);
RecordedRequest
request3
=
server
.
takeRequest
();
assertEquals
(
"/status"
,
request3
.
getPath
());
assertToken
(
request3
,
token
);
}
@Test
public
void
testStatusOnlyForOwner
()
{
MailboxProperties
properties
=
new
MailboxProperties
(
""
,
token
,
false
);
assertThrows
(
IllegalArgumentException
.
class
,
()
->
api
.
checkStatus
(
properties
)
);
}
private
String
getBaseUrl
(
MockWebServer
server
)
{
String
baseUrl
=
server
.
url
(
""
).
toString
();
return
baseUrl
.
substring
(
0
,
baseUrl
.
length
()
-
1
);
}
private
void
assertToken
(
RecordedRequest
request
,
String
token
)
{
assertNotNull
(
request
.
getHeader
(
"Authorization"
));
assertEquals
(
"Bearer "
+
token
,
request
.
getHeader
(
"Authorization"
));
}
}
bramble-core/witness.gradle
View file @
d665fc17
dependencyVerification
{
verify
=
[
'cglib:cglib:3.2.8:cglib-3.2.8.jar:3f64de999ecc5595dc84ca8ff0879d8a34c8623f9ef3c517a53ed59023fcb9db'
,
'com.fasterxml.jackson.core:jackson-annotations:2.13.0:jackson-annotations-2.13.0.jar:81f9724d8843e8b08f8f6c0609e7a2b030d00c34861c4ac7e2099a7235047d6f'
,
'com.fasterxml.jackson.core:jackson-core:2.13.0:jackson-core-2.13.0.jar:348bc59b348df2e807b356f1d62d2afb41a974073328abc773eb0932b855d2c8'
,
'com.fasterxml.jackson.core:jackson-databind:2.13.0:jackson-databind-2.13.0.jar:9c826d27176268777adcf97e1c6e2051c7e33a7aaa2c370c2e8c6077fd9da3f4'
,
'com.google.code.findbugs:annotations:3.0.1:annotations-3.0.1.jar:6b47ff0a6de0ce17cbedc3abb0828ca5bce3009d53ea47b3723ff023c4742f79'
,
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7'
,
'com.google.dagger:dagger-compiler:2.33:dagger-compiler-2.33.jar:aa8a0d8370c578fd6999802d0d90b9829377a46d2c1141e11b8f737970e7155e'
,
...
...
@@ -15,8 +18,11 @@ dependencyVerification {
'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99'
,
'com.google.j2objc:j2objc-annotations:1.1:j2objc-annotations-1.1.jar:2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6'
,
'com.h2database:h2:1.4.192:h2-1.4.192.jar:225b22e9857235c46c93861410b60b8c81c10dc8985f4faf188985ba5445126c'
,
'com.squareup.okhttp3:mockwebserver:4.9.3:mockwebserver-4.9.3.jar:9c8c581c29f22f877a35d11380462f75bb24bf1886204fe835ee695594a2784e'
,
'com.squareup.okhttp3:okhttp:3.12.13:okhttp-3.12.13.jar:508234e024ef7e270ab1a6d5b356f5b98e786511239ca986d684fd1e2cf7bc82'
,
'com.squareup.okhttp3:okhttp:4.9.3:okhttp-4.9.3.jar:93ecd6cba19d87dccfe566ec848d91aae799e3cf16c00709358ea69bd9227219'
,
'com.squareup.okio:okio:1.15.0:okio-1.15.0.jar:693fa319a7e8843300602b204023b7674f106ebcb577f2dd5807212b66118bd2'
,
'com.squareup.okio:okio:2.8.0:okio-jvm-2.8.0.jar:4496b06e73982fcdd8a5393f46e5df2ce2fa4465df5895454cac68a32f09bbc8'
,
'com.squareup:javapoet:1.13.0:javapoet-1.13.0.jar:4c7517e848a71b36d069d12bb3bf46a70fd4cda3105d822b0ed2e19c00b69291'
,
'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f'
,
'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff'
,
...
...
@@ -40,7 +46,11 @@ dependencyVerification {
'org.hamcrest:hamcrest-library:2.1:hamcrest-library-2.1.jar:b7e2b6895b3b679f0e47b6380fda391b225e9b78505db9d8bdde8d3cc8d52a21'
,
'org.hamcrest:hamcrest:2.1:hamcrest-2.1.jar:ba93b2e3a562322ba432f0a1b53addcc55cb188253319a020ed77f824e692050'
,
'org.hsqldb:hsqldb:2.3.5:hsqldb-2.3.5.jar:6676a6977ac98997a80f827ddbd3fe8ca1e0853dad1492512135fd1a222ccfad'
,
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.10:kotlin-stdlib-common-1.4.10.jar:4681f2d436a68c7523595d84ed5758e1382f9da0f67c91e6a848690d711274fe'
,
'org.jetbrains.kotlin:kotlin-stdlib-common:1.4.20:kotlin-stdlib-common-1.4.20.jar:a7112c9b3cefee418286c9c9372f7af992bd1e6e030691d52f60cb36dbec8320'
,
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10:kotlin-stdlib-jdk7-1.4.10.jar:f9566380c08722c780ce33ceee23e98ddf765ca98fabd3e2fabae7975c8d232b'
,
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10:kotlin-stdlib-jdk8-1.4.10.jar:39b7a9442d7a3865e0f4a732c56c1d5da0e11ffb3bb82a461d32deb0c0ca7673'
,
'org.jetbrains.kotlin:kotlin-stdlib:1.4.10:kotlin-stdlib-1.4.10.jar:01ecb09782c042b931c1839acf21a188340b295d05400afd6e3415d4475b8daa'
,
'org.jetbrains.kotlin:kotlin-stdlib:1.4.20:kotlin-stdlib-1.4.20.jar:b8ab1da5cdc89cb084d41e1f28f20a42bd431538642a5741c52bbfae3fa3e656'
,
'org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0:kotlinx-metadata-jvm-0.1.0.jar:9753bb39efef35957c5c15df9a3cb769aabf2cdfa74b47afcb7760e5146be3b5'
,
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478'
,
...
...
briar-headless/build.gradle
View file @
d665fc17
...
...
@@ -23,7 +23,7 @@ dependencies {
implementation
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32'
implementation
'io.javalin:javalin:3.5.0'
implementation
'org.slf4j:slf4j-simple:1.7.30'
implementation
'
com.fasterxml.jackson.core:jackson-databind:
2.12.2'
implementation
"
com.fasterxml.jackson.core:jackson-databind:
$jackson_version"
implementation
'com.github.ajalt:clikt:2.2.0'
def
daggerVersion
=
'2.24'
...
...
briar-headless/witness.gradle
View file @
d665fc17
dependencyVerification
{
verify
=
[
'com.fasterxml.jackson.core:jackson-annotations:2.1
2.2
:jackson-annotations-2.1
2.2
.jar:
558561786c071af202e849b6ae3d39c87ed417ecc83d45e398c12eb3bffa557b
'
,
'com.fasterxml.jackson.core:jackson-core:2.1
2.2
:jackson-core-2.1
2.2
.jar:
7883331763729b72735fdd8a117f32eb7d22695babfb37cc99df8392c196efc3
'
,
'com.fasterxml.jackson.core:jackson-databind:2.1
2.2
:jackson-databind-2.1
2.2
.jar:
c4002f861d8d33f3202bf8effabb53acc320c5276cc50c1bfaae73c36ce8db32
'
,
'com.fasterxml.jackson.core:jackson-annotations:2.1
3.0
:jackson-annotations-2.1
3.0
.jar:
81f9724d8843e8b08f8f6c0609e7a2b030d00c34861c4ac7e2099a7235047d6f
'
,
'com.fasterxml.jackson.core:jackson-core:2.1
3.0
:jackson-core-2.1
3.0
.jar:
348bc59b348df2e807b356f1d62d2afb41a974073328abc773eb0932b855d2c8
'
,
'com.fasterxml.jackson.core:jackson-databind:2.1
3.0
:jackson-databind-2.1
3.0
.jar:
9c826d27176268777adcf97e1c6e2051c7e33a7aaa2c370c2e8c6077fd9da3f4
'
,
'com.github.ajalt:clikt:2.2.0:clikt-2.2.0.jar:beb3136d06764ec8ce0810a8fd6c8b7b49d04287d1deef3a07c016e43a458d33'
,
'com.github.gundy:semver4j:0.16.4:semver4j-0.16.4.jar:def9b4225fa37219e18f81d01f0e52d73dca1257a38f5475be9dd58f87736510'
,
'com.google.code.findbugs:jsr305:3.0.2:jsr305-3.0.2.jar:766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7'
,
...
...
build.gradle
View file @
d665fc17
...
...
@@ -37,6 +37,7 @@ buildscript {
dagger_version
=
"2.33"
// okhttp 3.12.x is supported until end of 2021, newer versions need minSdk 21
okhttp_version
=
"3.12.13"
jackson_version
=
"2.13.0"
tor_version
=
"0.3.5.17"
obfs4proxy_version
=
"0.0.12-dev-40245c4a"
junit_version
=
"4.13.2"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment