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

feat: challenge endpoint #56

Merged
merged 13 commits into from
Oct 5, 2023
52 changes: 52 additions & 0 deletions app/src/main/java/gateway/controller/CtrlAuthRefresh.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package gateway.controller;

import gateway.config.Config;
import gateway.soap.request.Authorization;
import gateway.soap.response.ResSession;
import org.json.JSONObject;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class CtrlAuthRefresh {

public static ResSession auth_refresh (Authorization authorization)
{
ResSession res = new ResSession ();

String url = Config.getAuthBaseUrl () + "/challenge";

try {

HttpResponse<String> response = HttpClient.newHttpClient ().send (
HttpRequest.newBuilder ()
.uri (URI.create (url))
.POST (HttpRequest.BodyPublishers.noBody ())
.uri (URI.create (url))
.header("Authorization", "Bearer " + authorization.token)
.build (),
HttpResponse.BodyHandlers.ofString ());

// Response
JSONObject jsonObject = new JSONObject (response.body ());
res.code = response.statusCode ();

if (res.code == 200) {
res.auth = new Authorization();
res.error = false;
res.auth.token = jsonObject.getString ("jwt");
} else {
res.error = true;
res.msg = jsonObject.getString ("msg");
}

} catch (IOException | InterruptedException e) {
e.printStackTrace ();
}

return res;
}
}
5 changes: 4 additions & 1 deletion app/src/main/java/gateway/soap/ServiceImp.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
return CtrlAuthLogin.auth_login (credentials);
}

@WebMethod public ResSession auth_refresh (Authorization auth) { return null; }
@WebMethod public ResSession auth_refresh (Authorization auth) {

return CtrlAuthRefresh.auth_refresh (auth);
}

// account

Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/gateway/soap/request/Authorization.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@
public class Authorization
{
public String token;

public Authorization () {}
public Authorization (String token)
{
this.token = token;
}
}
113 changes: 69 additions & 44 deletions app/src/test/java/gateway/ITServiceAuth.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,77 +6,102 @@
import gateway.controller.CtrlAccountRegister;
import gateway.controller.CtrlAuthLogin;
import gateway.services.ServiceAuth;
import gateway.controller.CtrlAuthRefresh;
import gateway.soap.request.Authorization;
import gateway.soap.request.Credentials;
import gateway.soap.response.ResSession;
import gateway.testutils.TestUtilConfig;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class ITServiceAuth
{
@BeforeEach void setup () { Config.initializeFromEnv (); }
class ITServiceAuth {
@BeforeEach
void setup() {
Config.initializeFromEnv();
}

@Test void Authenticate ()
{
@Test
void Authenticate() {
// 200
Credentials cred = new Credentials (UUID.randomUUID ().toString (), "pass");
ResSession res = CtrlAccountRegister.account_register (cred);
assertEquals (201, res.code, "Login successfully");
assertEquals (
200, ServiceAuth.authenticate (res.auth.token).code, () -> "Auth'd successful");
Credentials cred = new Credentials(UUID.randomUUID().toString(), "pass");
ResSession res = CtrlAccountRegister.account_register(cred);
assertEquals(201, res.code, "Login successfully");
assertEquals(
200, ServiceAuth.authenticate(res.auth.token).code, () -> "Auth'd successful");

// 401
assertEquals (401, ServiceAuth.authenticate ("invalid token").code, () -> "Auth failed");
assertEquals(401, ServiceAuth.authenticate("invalid token").code, () -> "Auth failed");

// 500
TestUtilConfig.makeInvalidAll ();
assertEquals (500, ServiceAuth.authenticate ("").code, () -> "Can't reach Auth Server");
TestUtilConfig.makeInvalidAll();
assertEquals(500, ServiceAuth.authenticate("").code, () -> "Can't reach Auth Server");
}

@Test void GetUserUUID ()
{
@Test
void GetUserUUID() {
// 200
Credentials cred = new Credentials (UUID.randomUUID ().toString (), "pass");
ResSession res = CtrlAccountRegister.account_register (cred);
assertEquals (201, res.code, "Login successfully");
assertEquals (
200, ServiceAuth.getUserUUID (res.auth.token, cred.username).code,
"Ok. Username retrieved");
Credentials cred = new Credentials(UUID.randomUUID().toString(), "pass");
ResSession res = CtrlAccountRegister.account_register(cred);
assertEquals(201, res.code, "Login successfully");
assertEquals(
200, ServiceAuth.getUserUUID(res.auth.token, cred.username).code,
"Ok. Username retrieved");

// 401
assertEquals (
401, ServiceAuth.getUserUUID ("invalid token", cred.username).code, "Auth failed");
assertEquals(
401, ServiceAuth.getUserUUID("invalid token", cred.username).code, "Auth failed");

// 500
TestUtilConfig.makeInvalidAll ();
assertEquals (
500, ServiceAuth.getUserUUID (res.auth.token, cred.username).code,
"Can't reach Auth Server");
TestUtilConfig.makeInvalidAll();
assertEquals(
500, ServiceAuth.getUserUUID(res.auth.token, cred.username).code,
"Can't reach Auth Server");
}

@Test void Login ()
{
Credentials cred = new Credentials (UUID.randomUUID ().toString (), "pass");
@Test
void Login() {
Credentials cred = new Credentials(UUID.randomUUID().toString(), "pass");
// register

ResSession res = CtrlAccountRegister.account_register (cred);
assertEquals (201, res.code, "Register successfully");
ResSession res = CtrlAccountRegister.account_register(cred);
assertEquals(201, res.code, "Register successfully");

ResSession login = CtrlAuthLogin.auth_login (cred);
assertEquals (201, login.code, "Login succeed");
ResSession login = CtrlAuthLogin.auth_login(cred);
assertEquals(201, login.code, "Login succeed");

cred.username = UUID.randomUUID ().toString ();
login = CtrlAuthLogin.auth_login (cred);
assertEquals (401, login.code, "Invalid credentials");
cred.username = UUID.randomUUID().toString();
login = CtrlAuthLogin.auth_login(cred);
assertEquals(401, login.code, "Invalid credentials");

cred.username = null;
login = CtrlAuthLogin.auth_login (cred);
assertEquals (400, login.code, "Bad Request: Invalid Field");
login = CtrlAuthLogin.auth_login(cred);
assertEquals(400, login.code, "Bad Request: Invalid Field");

TestUtilConfig.makeInvalidAll();
cred.username = UUID.randomUUID().toString();
login = CtrlAuthLogin.auth_login(cred);
assertEquals(500, login.code, "Internal error, try again later");
}

@Test
void challenge() {
// User register

Credentials cred = new Credentials(UUID.randomUUID().toString(), "pass");

ResSession res = CtrlAccountRegister.account_register(cred);
assertEquals(201, res.code, "Register successfully");

// Challenge validation

Authorization authorization = res.auth;

ResSession challenge = CtrlAuthRefresh.auth_refresh(authorization);
assertEquals(200, challenge.code, "JWT refresh succesfully");

TestUtilConfig.makeInvalidAll ();
cred.username = UUID.randomUUID ().toString ();
login = CtrlAuthLogin.auth_login (cred);
assertEquals (500, login.code, "Internal error, try again later");
res.auth.token = res.auth.token + "unauthorized";
challenge = CtrlAuthRefresh.auth_refresh(authorization);
assertEquals(401, challenge.code, "Unauthorized");
}
}
}
3 changes: 1 addition & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,4 @@ services:
ADMINER_DEFAULT_PORT: 5432
ADMINER_DEFAULT_DB: metadatadb
networks:
- net
attach: false
- net
8 changes: 7 additions & 1 deletion docs/spec.openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,18 @@ paths:
Object:
schema:
$ref: '#/components/schemas/ResSession'
'401':
description: Unauthorized
content:
Object:
schema:
$ref: '#/components/schemas/ResSession'
'default':
description: An error occurred, see other codes at [Authentication API Spec `POST /challenge`](https://github.com/hawks-atlanta/authentication-go/blob/main/docs/spec.openapi.yaml)
content:
Object:
schema:
$ref: '#/components/schemas/ResStatus'
$ref: '#/components/schemas/ResSession'
Copy link
Member

@Woynert Woynert Oct 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically we always return a ResSession but it's not guaranteed that the relevant fields will be filled if there is an exception (i.e. a code different from 20x).

So instead let it as ResStatus which is guaranteed to be complete (exception), also it allows us to be consistent with the other endpoints. Which always return a ResStatus in case something wrong happens.


# account

Expand Down
7 changes: 7 additions & 0 deletions soap-python-client.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@

print(result)

token = result['auth']['token']
result = client.service.auth_refresh({
'token': token
})

print(result)

# upload demo
with open ("./LICENSE", "rb") as in_file:

Expand Down