mirror of https://github.com/apibillme/broker
add http basic auth
This commit is contained in:
parent
0ab4c72281
commit
31bbed2019
|
@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [8.1.x] - 2021-04-25
|
||||
|
||||
### Added
|
||||
- Adds http basic auth
|
||||
|
||||
## [8.0.x] - 2021-03-23
|
||||
|
||||
### Added
|
||||
|
|
|
@ -461,10 +461,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "broker"
|
||||
version = "8.0.0"
|
||||
version = "8.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-std",
|
||||
"base64 0.13.0",
|
||||
"driftwood",
|
||||
"futures",
|
||||
"go-flag",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "broker"
|
||||
version = "8.0.0"
|
||||
version = "8.1.0"
|
||||
authors = ["Bevan Hunt <bevan@bevanhunt.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
|
@ -31,3 +31,4 @@ http-types = "2"
|
|||
tide-rustls = "0.3"
|
||||
futures = "0.3"
|
||||
tide-acme = "0.1.0"
|
||||
base64 = "0.13"
|
||||
|
|
|
@ -21,7 +21,8 @@ Broker follows an insert-only/publish/subscribe paradigm rather than a REST CRUD
|
|||
* Add users with admin token permission
|
||||
* Multi-tenant
|
||||
* Supports SSL - full end-to-end encryption
|
||||
* Provides user authentication with JWTs with stored Argon2 passwords
|
||||
* Provides user authentication with JWTs or HTTP Basic
|
||||
* Secure passwords with Argon2 encoding
|
||||
* Uses Global NTP servers and doesn't rely on your local server time
|
||||
* Insert event via JSON POST request
|
||||
* Sync latest events on SSE client connection
|
||||
|
@ -90,7 +91,7 @@ will return
|
|||
```html
|
||||
GET /sse
|
||||
```
|
||||
- authenticated endpoint (Authorization: Bearer {jwt})
|
||||
- authenticated endpoint (Authorization: Bearer {jwt}) or (Authorization: Basic {username:password})
|
||||
- connect your sse-client to this endpoint using [broker-client](https://www.npmjs.com/package/broker-client)
|
||||
- `note`: broker-client uses fetch as eventsource doesn't support headers
|
||||
|
||||
|
@ -99,7 +100,7 @@ GET /sse
|
|||
```html
|
||||
POST /insert
|
||||
```
|
||||
- authenticated endpoint (Authorization: Bearer {jwt})
|
||||
- authenticated endpoint (Authorization: Bearer {jwt}) or (Authorization: Basic {username:password})
|
||||
- POST JSON to insert an event
|
||||
```json
|
||||
{"event":{...}, "data":{...}, "tenant_name":{...}}
|
||||
|
|
54
src/main.rs
54
src/main.rs
|
@ -219,7 +219,7 @@ fn env_var_config() -> EnvVarConfig {
|
|||
EnvVarConfig{port, origin, jwt_expiry, jwt_secret, secure, domain, certs, db, admin_token}
|
||||
}
|
||||
|
||||
fn jwt_verify(token: String) -> Result<Option<TokenData<Claims>>> {
|
||||
async fn jwt_verify(token: String) -> Result<Option<TokenData<Claims>>> {
|
||||
|
||||
let configure = env_var_config();
|
||||
|
||||
|
@ -228,16 +228,45 @@ fn jwt_verify(token: String) -> Result<Option<TokenData<Claims>>> {
|
|||
if auth_type == "Bearer" {
|
||||
let token = parts.next().unwrap();
|
||||
let _ = match decode::<Claims>(&token, &DecodingKey::from_secret(configure.jwt_secret.as_ref()), &Validation::default()) {
|
||||
Ok(c) => {
|
||||
return Ok(Some(c));
|
||||
},
|
||||
Err(_) => {
|
||||
return Ok(None);
|
||||
}
|
||||
Ok(c) => { return Ok(Some(c)); },
|
||||
Err(_) => { return Ok(None); }
|
||||
};
|
||||
} else if auth_type == "Basic" {
|
||||
let basic_encoded = parts.next().unwrap();
|
||||
|
||||
let _ = match base64::decode(basic_encoded) {
|
||||
Ok(c) => {
|
||||
let _ = match std::str::from_utf8(&c) {
|
||||
Ok(basic) => {
|
||||
let mut basic_parts = basic.split(":");
|
||||
let user_name = basic_parts.next().unwrap();
|
||||
let password = basic_parts.next().unwrap();
|
||||
let user_value = get_user_by_username(user_name.to_string())?;
|
||||
match user_value {
|
||||
Some(user) => {
|
||||
if argon2::verify_encoded(&user.password, password.as_ref())? {
|
||||
let app = env_var_config();
|
||||
let iat = nippy::get_unix_ntp_time().await?;
|
||||
let exp = iat + app.jwt_expiry;
|
||||
let iss = "Dispatcher".to_string();
|
||||
let my_claims = Claims{sub: user.clone().username, exp, iat, iss};
|
||||
let my_token = TokenData{
|
||||
header: Header::default(),
|
||||
claims: my_claims,
|
||||
};
|
||||
return Ok(Some(my_token));
|
||||
}
|
||||
},
|
||||
None => { return Ok(None); }
|
||||
}
|
||||
},
|
||||
Err(_) => { return Ok(None); }
|
||||
};
|
||||
},
|
||||
Err(_) => { return Ok(None); }
|
||||
};
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
// insert an event
|
||||
|
@ -301,7 +330,7 @@ async fn insert_event(mut req: Request<()>) -> tide::Result {
|
|||
match token_value {
|
||||
Some(token_header) => {
|
||||
let token = token_header.last().to_string();
|
||||
let jwt_value = jwt_verify(token)?;
|
||||
let jwt_value = jwt_verify(token).await?;
|
||||
match jwt_value {
|
||||
Some(jwt) => {
|
||||
let r = req.body_string().await?;
|
||||
|
@ -340,13 +369,14 @@ async fn main() -> tide::Result<()> {
|
|||
match token_value {
|
||||
Some(token_header) => {
|
||||
let token = token_header.last().to_string();
|
||||
let jwt_value = jwt_verify(token)?;
|
||||
let jwt_value = jwt_verify(token).await?;
|
||||
match jwt_value {
|
||||
Some(jwt) => {
|
||||
let user_value = get_user_by_username(jwt.claims.sub)?;
|
||||
|
||||
match user_value {
|
||||
Some(user) => {
|
||||
|
||||
let mut cache: HashMap<String, Event> = HashMap::new();
|
||||
|
||||
let mut interval = stream::interval(Duration::from_millis(100));
|
||||
|
@ -369,7 +399,7 @@ async fn main() -> tide::Result<()> {
|
|||
cache.insert(evt.event.clone(), evt.clone());
|
||||
}
|
||||
},
|
||||
None => { return Ok(()); }
|
||||
None => { println!("helo"); return Ok(()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue