update identity detection methods

This commit is contained in:
yggverse 2025-01-23 13:28:18 +02:00
parent 9a7984f345
commit d7f6e2f16b
8 changed files with 47 additions and 41 deletions

View File

@ -164,7 +164,7 @@ fn handle(
.page .page
.profile .profile
.identity .identity
.match_scope(&uri.to_string()) .get(&uri.to_string())
{ {
Some(identity) => match identity.to_tls_certificate() { Some(identity) => match identity.to_tls_certificate() {
Ok(certificate) => Some(certificate), Ok(certificate) => Some(certificate),

View File

@ -43,19 +43,16 @@ impl Default {
Value::ProfileIdentityId(value) => Some(value), Value::ProfileIdentityId(value) => Some(value),
Value::GuestSession => None, Value::GuestSession => None,
Value::GeneratePem => Some( Value::GeneratePem => Some(
match profile profile
.identity .identity
.make(None, &widget.form.name.value().unwrap()) .make(None, &widget.form.name.value().unwrap())
{ .unwrap(), // @TODO handle
Ok(profile_identity_id) => profile_identity_id,
Err(e) => todo!("{e}"),
},
), ),
Value::ImportPem => Some( Value::ImportPem => Some(
match profile.identity.add(&widget.form.file.pem.take().unwrap()) { profile
Ok(profile_identity_id) => profile_identity_id, .identity
Err(e) => todo!("{e}"), .add(&widget.form.file.pem.take().unwrap())
}, .unwrap(), // @TODO handle
), ),
}; };
@ -63,19 +60,20 @@ impl Default {
match option { match option {
// Activate identity for `scope` // Activate identity for `scope`
Some(profile_identity_id) => { Some(profile_identity_id) => {
if let Err(e) = profile if profile
.identity .identity
.auth .auth
.apply(profile_identity_id, &request.to_string()) .apply(profile_identity_id, &request.to_string())
.is_err()
{ {
todo!("{e}") panic!() // unexpected @TODO
}; }
} }
// Remove all identity auths for `scope` // Remove all identity auths for `scope`
None => { None => {
if let Err(e) = profile.identity.auth.remove_scope(&request.to_string()) { if profile.identity.auth.remove(&request.to_string()).is_err() {
todo!("{e}") panic!() // unexpected @TODO
}; }
} }
} }

View File

@ -111,9 +111,7 @@ impl Form {
self.profile self.profile
.identity .identity
.auth .auth
.memory .is_matches(&self.request.to_string(), profile_identity_id),
.match_scope(&self.request.to_string())
.is_some_and(|auth| auth.profile_identity_id == profile_identity_id),
); );
self.save.update(true); self.save.update(true);
} }

View File

@ -9,7 +9,5 @@ pub fn new_for_profile_identity_id(
profile profile
.identity .identity
.auth .auth
.memory .is_matches(auth_url, profile_identity_id) // @TODO direct call?
.match_scope(auth_url)
.is_some_and(|auth| auth.profile_identity_id == profile_identity_id)
} }

View File

@ -77,7 +77,7 @@ impl Navigation {
self.history.update(); self.history.update();
self.reload.update(!request.is_empty()); self.reload.update(!request.is_empty());
self.request self.request
.update(self.profile.identity.match_scope(&request).is_some()); .update(self.profile.identity.get(&request).is_some());
self.home.update(); self.home.update();
} }

View File

@ -126,8 +126,8 @@ impl Identity {
/// Get `Identity` match `request` /// Get `Identity` match `request`
/// * [Client certificates specification](https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates) /// * [Client certificates specification](https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates)
/// * this function work with memory cache (not database) /// * this function work with memory cache (not database)
pub fn match_scope(&self, request: &str) -> Option<Item> { pub fn get(&self, request: &str) -> Option<Item> {
if let Some(auth) = self.auth.memory.match_scope(request) { if let Some(auth) = self.auth.get(request) {
match self.memory.get(auth.profile_identity_id) { match self.memory.get(auth.profile_identity_id) {
Ok(pem) => { Ok(pem) => {
return Some(Item { return Some(Item {

View File

@ -41,14 +41,15 @@ impl Auth {
/// * deactivate active auth by remove previous records from `Self` database /// * deactivate active auth by remove previous records from `Self` database
/// * reindex `Self` memory index on success /// * reindex `Self` memory index on success
/// * return last insert `profile_identity_auth_id` on success /// * return last insert `profile_identity_auth_id` on success
pub fn apply(&self, profile_identity_id: i64, auth_url: &str) -> Result<i64, Error> { pub fn apply(&self, profile_identity_id: i64, request: &str) -> Result<i64, Error> {
let scope = filter_scope(auth_url);
// Cleanup records match `scope` (unauthorize) // Cleanup records match `scope` (unauthorize)
self.remove_scope(&scope)?; self.remove(request)?;
// Create new record (auth) // Create new record (auth)
let profile_identity_auth_id = match self.database.add(profile_identity_id, &scope) { let profile_identity_auth_id = match self
.database
.add(profile_identity_id, &filter_scope(request))
{
Ok(id) => id, Ok(id) => id,
Err(e) => return Err(Error::Database(e)), Err(e) => return Err(Error::Database(e)),
}; };
@ -61,8 +62,8 @@ impl Auth {
} }
/// Remove all records match request (unauthorize) /// Remove all records match request (unauthorize)
pub fn remove_scope(&self, scope: &str) -> Result<(), Error> { pub fn remove(&self, request: &str) -> Result<(), Error> {
match self.database.records_scope(Some(scope)) { match self.database.records_scope(Some(&filter_scope(request))) {
Ok(records) => { Ok(records) => {
for record in records { for record in records {
if let Err(e) = self.database.delete(record.id) { if let Err(e) = self.database.delete(record.id) {
@ -113,6 +114,20 @@ impl Auth {
Ok(()) Ok(())
} }
// Getters
/// Check request string matches condition
pub fn is_matches(&self, request: &str, profile_identity_id: i64) -> bool {
self.memory
.match_scope(&filter_scope(request))
.is_some_and(|auth| auth.profile_identity_id == profile_identity_id)
}
/// Get memory item string match request
pub fn get(&self, request: &str) -> Option<memory::Auth> {
self.memory.match_scope(&filter_scope(request))
}
} }
// Tools // Tools

View File

@ -58,20 +58,17 @@ impl Memory {
} }
} }
/// Get identity match `request` /// Get identity exactly match `scope`
/// * [Client certificates specification](https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates) /// * [Client certificates specification](https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates)
/// * contain unspecified length priority implementation @TODO /// * see also parent `is_match_request`
pub fn match_scope(&self, request: &str) -> Option<Auth> { pub fn match_scope(&self, scope: &str) -> Option<Auth> {
let mut result = Vec::new(); let mut result = Vec::new();
// Get all records starts with `scope` for (value, &profile_identity_id) in self.index.borrow().iter() {
let query = super::filter_scope(request); if scope.starts_with(value) {
for (scope, &profile_identity_id) in self.index.borrow().iter() {
if query.starts_with(scope) {
result.push(Auth { result.push(Auth {
profile_identity_id, profile_identity_id,
scope: scope.clone(), scope: value.clone(),
}) })
} }
} }