-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
769 additions
and
43 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
use std::collections::HashMap; | ||
use std::sync::Mutex; | ||
use lazy_static::lazy_static; | ||
use simple_log::{info, warn}; | ||
|
||
lazy_static! { | ||
static ref BLACKLIST: Mutex<HashMap<String, u8>> = Mutex::new(HashMap::new()); | ||
} | ||
|
||
pub async fn is_in_blacklist(ip: String) -> bool { | ||
let mut trys = 0; | ||
loop { | ||
trys += 1; | ||
if trys > 100 { | ||
return true; | ||
} | ||
|
||
if let Ok(map) = BLACKLIST.try_lock() { | ||
return match map.get(ip.as_str()) { | ||
None => { | ||
false | ||
} | ||
Some(a) => { | ||
if *a > 50 { | ||
true | ||
} else { | ||
false | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub async fn clear_blacklist() { | ||
loop { | ||
tokio::time::sleep(std::time::Duration::from_secs(1200)).await; | ||
|
||
let mut trys = 0; | ||
loop { | ||
trys += 1; | ||
if trys > 100 { | ||
break; | ||
} | ||
|
||
if let Ok(mut map) = BLACKLIST.try_lock() { | ||
if map.len() > 0 { | ||
map.clear(); | ||
info!("Clearing black list."); | ||
} | ||
break; | ||
} | ||
} | ||
|
||
} | ||
} | ||
|
||
pub async fn record(ip: String) { | ||
warn!("Recording {} into blacklist.", ip.as_str()); | ||
let mut trys = 0; | ||
loop { | ||
trys += 1; | ||
if trys > 100 { | ||
return; | ||
} | ||
|
||
if let Ok(mut map) = BLACKLIST.try_lock() { | ||
let num = match map.get(ip.as_str()) { | ||
None => { | ||
0 | ||
} | ||
Some(a) => { | ||
*a | ||
} | ||
}; | ||
map.insert(ip.clone(), num + 1); | ||
return; | ||
} | ||
} | ||
} | ||
|
||
pub fn init() { | ||
tokio::spawn(clear_blacklist()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
pub mod token; | ||
pub mod black; | ||
|
||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive(Serialize, Deserialize, Debug, Clone)] | ||
pub struct UserInfo {//_id: mc uuid | ||
pub _id: String, | ||
pub display_name: String, | ||
pub enabled: bool, | ||
pub group: Vec<String>, | ||
pub bind_qq: Option<i64>, | ||
pub ban_reason: Option<String> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
use base64::Engine; | ||
use jwt_simple::prelude::{HS256Key, MACLike}; | ||
use simple_log::debug; | ||
use simple_log::log::error; | ||
use crate::authenticate::black::{is_in_blacklist, record}; | ||
use crate::authenticate::UserInfo; | ||
use crate::CONFIG; | ||
|
||
impl UserInfo { | ||
pub async fn from_token(token: String) -> Result<UserInfo, String> { | ||
let key = match &CONFIG.authenticate.secret { | ||
None => { return Err("Key is not defined.".to_string())} | ||
Some(a) => {a} | ||
}; | ||
let key = HS256Key::from_bytes(base64::engine::general_purpose::STANDARD.decode(key).unwrap().as_slice()); | ||
|
||
let claims = key.verify_token::<UserInfo>(&token, None); | ||
match claims { | ||
Ok(info) => Ok(info.custom), | ||
Err(err) => { | ||
|
||
error!("{}", err.to_string()); | ||
Err("Cannot parse token or token is valid".to_string()) | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub async fn authenticate_token(token: String, ip: String) -> Result<(), String> { | ||
if is_in_blacklist(ip.clone()).await { | ||
debug!("{} is in black list.", ip); | ||
return Err("In blacklist.".to_string()); | ||
} | ||
|
||
let info = match UserInfo::from_token(token).await { | ||
Ok(a) => {a} | ||
Err(err) => { | ||
record(ip.clone()).await; | ||
return Err(err); | ||
} | ||
}; | ||
|
||
let group = info.group; | ||
for permission in group { | ||
if permission == "admin" { | ||
return Ok(()); | ||
} | ||
} | ||
|
||
record(ip).await; | ||
Err("No permission".to_string()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.