Skip to content

Commit c1447e8

Browse files
author
Nuno Santos
committed
Make sure RequestID is returned where necessary in case authorisation fails or an exception caused by authorisation code is thrown
1 parent ec8b2cf commit c1447e8

File tree

8 files changed

+115
-39
lines changed

8 files changed

+115
-39
lines changed

src/main/java/io/mewbase/server/impl/ConnectionImpl.java

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,11 @@ public void handlePublish(BsonObject frame) {
130130
};
131131

132132
authorisedCF.handle((res, ex) -> {
133-
handleFrame(frame, frameConsumer, res, ex);
133+
if (ex != null) {
134+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
135+
logAndClose(ex.getMessage());
136+
}
137+
handleFrame(frame, frameConsumer, res);
134138
return null;
135139
});
136140
}
@@ -203,7 +207,11 @@ public void handleSubscribe(BsonObject frame) {
203207
};
204208

205209
authorisedCF.handle((res, ex) -> {
206-
handleFrame(frame, frameConsumer, res, ex);
210+
if (ex != null) {
211+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
212+
logAndClose(ex.getMessage());
213+
}
214+
handleFrame(frame, frameConsumer, res);
207215
return null;
208216
});
209217

@@ -239,8 +247,11 @@ public void handleSubClose(BsonObject frame) {
239247
};
240248

241249
authorisedCF.handle((res, ex) -> {
242-
243-
handleFrame(frame, frameConsumer, res, ex);
250+
if (ex != null) {
251+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
252+
logAndClose(ex.getMessage());
253+
}
254+
handleFrame(frame, frameConsumer, res);
244255
return null;
245256
});
246257
}
@@ -277,8 +288,11 @@ public void handleUnsubscribe(BsonObject frame) {
277288
};
278289

279290
authorisedCF.handle((res, ex) -> {
280-
281-
handleFrame(frame, frameConsumer, res, ex);
291+
if (ex != null) {
292+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
293+
logAndClose(ex.getMessage());
294+
}
295+
handleFrame(frame, frameConsumer, res);
282296
return null;
283297
});
284298
}
@@ -314,8 +328,11 @@ public void handleAckEv(BsonObject frame) {
314328
};
315329

316330
authorisedCF.handle((res, ex) -> {
317-
318-
handleFrame(frame, frameConsumer, res, ex);
331+
if (ex != null) {
332+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
333+
logAndClose(ex.getMessage());
334+
}
335+
handleFrame(frame, frameConsumer, res);
319336
return null;
320337
});
321338
}
@@ -354,8 +371,11 @@ public void handleQuery(BsonObject frame) {
354371
};
355372

356373
authorisedCF.handle((res, ex) -> {
357-
358-
handleFrame(frame, frameConsumer, res, ex);
374+
if (ex != null) {
375+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
376+
logAndClose(ex.getMessage());
377+
}
378+
handleFrame(frame, frameConsumer, res);
359379
return null;
360380
});
361381
}
@@ -384,8 +404,11 @@ public void handleQueryAck(BsonObject frame) {
384404
};
385405

386406
authorisedCF.handle((res, ex) -> {
387-
388-
handleFrame(frame, frameConsumer, res, ex);
407+
if (ex != null) {
408+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed");
409+
logAndClose(ex.getMessage());
410+
}
411+
handleFrame(frame, frameConsumer, res);
389412
return null;
390413
});
391414
}
@@ -422,8 +445,11 @@ public void handleListBinders(BsonObject frame) {
422445
};
423446

424447
authorisedCF.handle((res, ex) -> {
425-
426-
handleFrame(frame, frameConsumer, res, ex);
448+
if (ex != null) {
449+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
450+
logAndClose(ex.getMessage());
451+
}
452+
handleFrame(frame, frameConsumer, res);
427453
return null;
428454
});
429455
}
@@ -461,8 +487,11 @@ public void handleCreateBinder(BsonObject frame) {
461487
};
462488

463489
authorisedCF.handle((res, ex) -> {
464-
465-
handleFrame(frame, frameConsumer, res, ex);
490+
if (ex != null) {
491+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
492+
logAndClose(ex.getMessage());
493+
}
494+
handleFrame(frame, frameConsumer, res);
466495
return null;
467496
});
468497
}
@@ -488,8 +517,11 @@ public void handleListChannels(BsonObject frame) {
488517
};
489518

490519
authorisedCF.handle((res, ex) -> {
491-
492-
handleFrame(frame, frameConsumer, res, ex);
520+
if (ex != null) {
521+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
522+
logAndClose(ex.getMessage());
523+
}
524+
handleFrame(frame, frameConsumer, res);
493525
return null;
494526
});
495527
}
@@ -527,22 +559,22 @@ public void handleCreateChannel(BsonObject frame) {
527559
};
528560

529561
authorisedCF.handle((res, ex) -> {
530-
531-
handleFrame(frame, frameConsumer, res, ex);
562+
if (ex != null) {
563+
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "Authorisation failed", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
564+
logAndClose(ex.getMessage());
565+
}
566+
handleFrame(frame, frameConsumer, res);
532567
return null;
533568
});
534569

535570
}
536571

537-
private void handleFrame(BsonObject frame, Consumer<BsonObject> consumer, boolean res, Throwable ex) {
538-
if (ex != null ) {
539-
sendErrorResponse(Client.ERR_AUTHORISATION_FAILED, "An error occurred when authorising user");
540-
logAndClose(ex.getMessage());
541-
} else if (res){
572+
private void handleFrame(BsonObject frame, Consumer<BsonObject> consumer, boolean res) {
573+
if (res){
542574
consumer.accept(frame);
543575
} else {
544-
sendErrorResponse(Client.ERR_NOT_AUTHORISED, "User is not authorised");
545-
logAndClose(ex.getMessage());
576+
sendErrorResponse(Client.ERR_NOT_AUTHORISED, "User is not authorised", frame.getInteger(Protocol.REQUEST_REQUEST_ID));
577+
logAndClose("User is not authorised");
546578
}
547579
}
548580

src/main/java/io/mewbase/server/impl/auth/VertxUser.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ public CompletableFuture<Boolean> isAuthorised(String protocolFrame) {
1818

1919
CompletableFuture<Boolean> cf = new CompletableFuture<>();
2020

21-
user.isAuthorised(protocolFrame, vertxRes -> cf.complete(vertxRes.succeeded()));
21+
user.isAuthorised(protocolFrame, vertxRes -> {
22+
if (!vertxRes.succeeded()) {
23+
cf.completeExceptionally(vertxRes.cause());
24+
} else {
25+
cf.complete(vertxRes.result()) ;
26+
}
27+
});
2228

2329
return cf;
2430
}

src/test/java/io/mewbase/auth/AuthenticationTest.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.mewbase.auth;
22

33
import io.mewbase.bson.BsonObject;
4+
import io.mewbase.client.Client;
45
import io.vertx.ext.unit.TestContext;
56
import io.vertx.ext.unit.junit.VertxUnitRunner;
67
import org.junit.Test;
@@ -23,14 +24,27 @@ public class AuthenticationTest extends AuthenticationTestBase {
2324

2425
@Test
2526
public void testSuccessfulAuthentication(TestContext context) throws Exception {
26-
authInfo = new BsonObject().put("success", true);
27+
authInfo = new BsonObject().put("success", true).put("isAuthorised", true).put("throwAuthorisationEx", false);
2728
execSimplePubSub(true, context);
2829
}
2930

3031
@Test
3132
public void testFailedAuthentication(TestContext context) throws Exception {
32-
authInfo = new BsonObject().put("success", false);
33-
execSimplePubSub(false, context);
33+
authInfo = new BsonObject().put("success", false).put("isAuthorised", true).put("throwAuthorisationEx", true);
34+
execSimplePubSub(false,"Authentication failed", Client.ERR_AUTHENTICATION_FAILED, context);
3435
}
3536

37+
@Test
38+
public void testFailedAuthorisation(TestContext context) throws Exception {
39+
authInfo = new BsonObject().put("success", true).put("isAuthorised", false).put("throwAuthorisationEx", true);
40+
execSimplePubSub(false,"Authorisation failed", Client.ERR_AUTHORISATION_FAILED, context);
41+
}
42+
43+
@Test
44+
public void testUnauthorised(TestContext context) throws Exception {
45+
authInfo = new BsonObject().put("success", true).put("isAuthorised", false).put("throwAuthorisationEx", false);
46+
execSimplePubSub(false,"User is not authorised", Client.ERR_NOT_AUTHORISED, context);
47+
}
48+
49+
3650
}

src/test/java/io/mewbase/auth/AuthenticationTestBase.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ protected MewbaseAuthProvider createAuthProvider() {
6161
}
6262

6363
protected Async execSimplePubSub(boolean success, TestContext context) throws Exception {
64+
return execSimplePubSub(success, "", 0, context);
65+
}
66+
67+
protected Async execSimplePubSub(boolean success, String errMsg, int errCode, TestContext context) throws Exception {
6468
startClient();
6569

6670
SubDescriptor descriptor = new SubDescriptor();
@@ -84,8 +88,8 @@ protected Async execSimplePubSub(boolean success, TestContext context) throws Ex
8488
Throwable cause = e.getCause();
8589
assertTrue(cause instanceof MewException);
8690
MewException mcause = (MewException)cause;
87-
assertEquals("Authentication failed", mcause.getMessage());
88-
Assert.assertEquals(Client.ERR_AUTHENTICATION_FAILED, mcause.getErrorCode());
91+
assertEquals(errMsg, mcause.getMessage());
92+
Assert.assertEquals(errCode, mcause.getErrorCode());
8993
} else {
9094
context.fail("Exception received");
9195
}

src/test/java/io/mewbase/auth/ShiroPropertiesAuthenticationTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.mewbase.auth;
22

3+
import io.mewbase.client.Client;
34
import io.mewbase.server.impl.auth.MewbaseVertxAuthProvider;
45
import io.mewbase.bson.BsonObject;
56
import io.mewbase.server.ServerOptions;
@@ -44,7 +45,13 @@ public void testSuccessfulAuthentication(TestContext context) throws Exception {
4445
@Test
4546
public void testFailedAuthentication(TestContext context) throws Exception {
4647
authInfo = new BsonObject().put("username", "error").put("password", "error");
47-
execSimplePubSub(false, context);
48+
execSimplePubSub(false, "Authentication failed", Client.ERR_AUTHENTICATION_FAILED, context);
49+
}
50+
51+
@Test
52+
public void testFailedAuthorisation(TestContext context) throws Exception {
53+
authInfo = new BsonObject().put("username", "base").put("password", "mew");
54+
execSimplePubSub(false, "User is not authorised", Client.ERR_NOT_AUTHORISED, context);
4855
}
4956

5057
}

src/test/java/io/mewbase/auth/TestAuthProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ public CompletableFuture<MewbaseUser> authenticate(BsonObject authInfo) {
1414
CompletableFuture cf = new CompletableFuture();
1515

1616
boolean success = authInfo.getBoolean("success");
17+
boolean throwAuthorisationEx = authInfo.getBoolean("throwAuthorisationEx");
1718

1819
if (!success) {
1920
cf.completeExceptionally(new MewException("Incorrect username/password"));
2021
} else {
21-
cf.complete(new TestUser(success));
22+
boolean isAuthorised = authInfo.getBoolean("isAuthorised");
23+
cf.complete(new TestUser(isAuthorised, throwAuthorisationEx));
2224
}
2325

2426
return cf;

src/test/java/io/mewbase/auth/TestUser.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
package io.mewbase.auth;
22

3+
import io.mewbase.client.MewException;
34
import io.mewbase.server.MewbaseUser;
45

56
import java.util.concurrent.CompletableFuture;
67

78
public class TestUser implements MewbaseUser {
89
private final boolean isAuthorised;
10+
private final boolean throwException;
911

10-
public TestUser(boolean isAuthorised) {
12+
public TestUser(boolean isAuthorised, boolean throwException) {
1113
this.isAuthorised = isAuthorised;
14+
this.throwException = throwException;
1215
}
1316

1417
@Override
1518
public CompletableFuture<Boolean> isAuthorised(String protocolFrame) {
1619
CompletableFuture<Boolean> cf = new CompletableFuture<>();
1720

18-
cf.complete(isAuthorised);
21+
if (throwException) {
22+
cf.completeExceptionally(new MewException("Authorisation failed"));
23+
} else {
24+
cf.complete(isAuthorised);
25+
}
26+
1927

2028
return cf;
2129
}
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
user.mew=base
2-
user.base=mew
1+
user.mew=base,subscriber,publisher
2+
user.base=mew
3+
4+
role.subscriber=SUBSCRIBE
5+
role.publisher=PUB

0 commit comments

Comments
 (0)