add http method validation on each route + add pubkey tests
This commit is contained in:
parent
1d2924b7ef
commit
8d3651d6fc
@ -45,13 +45,19 @@ expiration_time = 2 # in hours
|
||||
```bash
|
||||
./simple-auth <ini_path>
|
||||
|
||||
# get a JWT
|
||||
curl http://<ip>:<port>/get/ -d '{"username":"<user>", "password":"<password>"}'
|
||||
# should returned
|
||||
{"token":"<header>.<payload>.<signature>"}
|
||||
|
||||
# validate a JWT
|
||||
curl http://<ip>:<port>/validate/ -d '{"token":"<header>.<payload>.<signature>"}'
|
||||
# should returned (if valid)
|
||||
{"valid":"true"}
|
||||
|
||||
# get the public key for local validation
|
||||
curl http://<ip>:<port>/pubkey/
|
||||
{"pubkey":"<b64_encoded_public_key>"}
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
@ -217,6 +217,10 @@ impl HTTPRequest {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_method(&self) -> String {
|
||||
self.start_line.method.clone()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn is_valid(&self) -> bool {
|
||||
return self.start_line.is_valid();
|
||||
|
||||
@ -14,7 +14,11 @@ const GET_ROUTE: &'static str = "/get/";
|
||||
const VALIDATE_ROUTE: &'static str = "/validate/";
|
||||
const PUBKEY_ROUTE: &'static str = "/pubkey/";
|
||||
|
||||
async fn handle_get(request: HTTPRequest, config: Config) -> HTTPResponse {
|
||||
async fn handle_get(request: HTTPRequest, config: Config, method: &str) -> HTTPResponse {
|
||||
if method.trim().to_lowercase() != "post" {
|
||||
return HTTPResponse::as_400();
|
||||
}
|
||||
|
||||
let mut store = FileStore::new(config.filestore_path.clone());
|
||||
match &request.body {
|
||||
Some(ref b) => {
|
||||
@ -48,7 +52,11 @@ async fn handle_get(request: HTTPRequest, config: Config) -> HTTPResponse {
|
||||
/// validates the token by checking:
|
||||
/// * expiration time
|
||||
/// * signature
|
||||
async fn handle_validate(request: HTTPRequest, config: Config) -> HTTPResponse {
|
||||
async fn handle_validate(request: HTTPRequest, config: Config, method: &str) -> HTTPResponse {
|
||||
if request.get_method().trim().to_lowercase() != method {
|
||||
return HTTPResponse::as_400();
|
||||
}
|
||||
|
||||
let token = {
|
||||
match request.get_body_value("token") {
|
||||
Some(t) => t,
|
||||
@ -90,7 +98,11 @@ async fn handle_validate(request: HTTPRequest, config: Config) -> HTTPResponse {
|
||||
}
|
||||
|
||||
/// returns the JWT public key in base64 encoded
|
||||
async fn handle_public_key(_request: HTTPRequest, config: Config) -> HTTPResponse {
|
||||
async fn handle_public_key(request: HTTPRequest, config: Config, method: &str) -> HTTPResponse {
|
||||
if request.get_method().trim().to_lowercase() != method {
|
||||
return HTTPResponse::as_400();
|
||||
}
|
||||
|
||||
let jwt_signer = {
|
||||
match JWTSigner::new(config).await {
|
||||
Ok(s) => s,
|
||||
@ -114,6 +126,7 @@ async fn handle_public_key(_request: HTTPRequest, config: Config) -> HTTPRespons
|
||||
pub struct Router;
|
||||
|
||||
impl Router {
|
||||
/// routes the request to the corresponding handling method
|
||||
pub async fn route(&self, request_str: &str, addr: String, config: Config) -> HTTPResponse {
|
||||
let mut request = HTTPRequest::from(request_str);
|
||||
request.set_addr(addr);
|
||||
@ -121,9 +134,9 @@ impl Router {
|
||||
let target = request.start_line.get_target();
|
||||
|
||||
match target.as_str() {
|
||||
GET_ROUTE => handle_get(request, config).await,
|
||||
VALIDATE_ROUTE => handle_validate(request, config).await,
|
||||
PUBKEY_ROUTE => handle_public_key(request, config).await,
|
||||
GET_ROUTE => handle_get(request, config, "post").await,
|
||||
VALIDATE_ROUTE => handle_validate(request, config, "post").await,
|
||||
PUBKEY_ROUTE => handle_public_key(request, config, "get").await,
|
||||
_ => HTTPResponse::as_404(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
URL=${SIMPLE_AUTH_URL}
|
||||
if [ -z ${URL} ]
|
||||
then
|
||||
echo "[WARN]: SIMPLE_AUTH_URL is empty, set to http://localhost:9001"
|
||||
URL="http://localhost:9001"
|
||||
echo "[WARN]: SIMPLE_AUTH_URL is empty, set to http://localhost:5555"
|
||||
URL="http://localhost:5555"
|
||||
fi
|
||||
|
||||
for i in {0..10}
|
||||
@ -39,3 +39,14 @@ do
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
for i in {0..10}
|
||||
do
|
||||
http_response=$(curl -s -o response.txt -w "%{http_code}" ${URL}/pubkey/)
|
||||
if [ $http_response != "200" ]
|
||||
then
|
||||
echo "bad http status code : ${http_response}, expect 400"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import base64
|
||||
import jwt
|
||||
import os
|
||||
import requests
|
||||
@ -113,3 +114,23 @@ class TestResponse(TestCase):
|
||||
"the url requested does not exist",
|
||||
"invalid error message returned",
|
||||
)
|
||||
|
||||
def test_get_pubkey(self):
|
||||
resp = requests.get(URL + "/pubkey/")
|
||||
self.assertEqual(resp.status_code, 200, "bad status code returned")
|
||||
self.assertIsNotNone(resp.json(), "response data must not be empty")
|
||||
self.assertIsNotNone(resp.json()["pubkey"], "invalid error message returned")
|
||||
|
||||
b64_pubkey = base64.b64decode(resp.json()["pubkey"])
|
||||
self.assertIsNotNone(b64_pubkey, "public key b64 decoded can't be empty")
|
||||
self.assertIn("-BEGIN PUBLIC KEY-", b64_pubkey.decode())
|
||||
|
||||
def test_get_pubkey_bad_method(self):
|
||||
resp = requests.post(URL + "/pubkey/", json={"tutu": "toto"})
|
||||
self.assertEqual(resp.status_code, 400, "bad status code returned")
|
||||
self.assertIsNotNone(resp.json(), "response data must not be empty")
|
||||
self.assertEqual(
|
||||
resp.json()["error"],
|
||||
"the incoming request is not valid",
|
||||
"invalid error message returned",
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user