diff --git a/src/app/browser/window/tab/item/client/driver/gemini.rs b/src/app/browser/window/tab/item/client/driver/gemini.rs index a9b76442..d126e4c2 100644 --- a/src/app/browser/window/tab/item/client/driver/gemini.rs +++ b/src/app/browser/window/tab/item/client/driver/gemini.rs @@ -164,7 +164,7 @@ fn handle( .page .profile .identity - .match_scope(&uri.to_string()) + .get(&uri.to_string()) { Some(identity) => match identity.to_tls_certificate() { Ok(certificate) => Some(certificate), diff --git a/src/app/browser/window/tab/item/identity/default.rs b/src/app/browser/window/tab/item/identity/default.rs index 9f2bf8d1..0e7c7e97 100644 --- a/src/app/browser/window/tab/item/identity/default.rs +++ b/src/app/browser/window/tab/item/identity/default.rs @@ -43,19 +43,16 @@ impl Default { Value::ProfileIdentityId(value) => Some(value), Value::GuestSession => None, Value::GeneratePem => Some( - match profile + profile .identity .make(None, &widget.form.name.value().unwrap()) - { - Ok(profile_identity_id) => profile_identity_id, - Err(e) => todo!("{e}"), - }, + .unwrap(), // @TODO handle ), Value::ImportPem => Some( - match profile.identity.add(&widget.form.file.pem.take().unwrap()) { - Ok(profile_identity_id) => profile_identity_id, - Err(e) => todo!("{e}"), - }, + profile + .identity + .add(&widget.form.file.pem.take().unwrap()) + .unwrap(), // @TODO handle ), }; @@ -63,19 +60,20 @@ impl Default { match option { // Activate identity for `scope` Some(profile_identity_id) => { - if let Err(e) = profile + if profile .identity .auth .apply(profile_identity_id, &request.to_string()) + .is_err() { - todo!("{e}") - }; + panic!() // unexpected @TODO + } } // Remove all identity auths for `scope` None => { - if let Err(e) = profile.identity.auth.remove_scope(&request.to_string()) { - todo!("{e}") - }; + if profile.identity.auth.remove(&request.to_string()).is_err() { + panic!() // unexpected @TODO + } } } diff --git a/src/app/browser/window/tab/item/identity/default/widget/form.rs b/src/app/browser/window/tab/item/identity/default/widget/form.rs index 67e8a7f5..71807395 100644 --- a/src/app/browser/window/tab/item/identity/default/widget/form.rs +++ b/src/app/browser/window/tab/item/identity/default/widget/form.rs @@ -111,9 +111,7 @@ impl Form { self.profile .identity .auth - .memory - .match_scope(&self.request.to_string()) - .is_some_and(|auth| auth.profile_identity_id == profile_identity_id), + .is_matches(&self.request.to_string(), profile_identity_id), ); self.save.update(true); } diff --git a/src/app/browser/window/tab/item/identity/default/widget/form/list/item/is_active.rs b/src/app/browser/window/tab/item/identity/default/widget/form/list/item/is_active.rs index ac62095c..8a4a6bea 100644 --- a/src/app/browser/window/tab/item/identity/default/widget/form/list/item/is_active.rs +++ b/src/app/browser/window/tab/item/identity/default/widget/form/list/item/is_active.rs @@ -9,7 +9,5 @@ pub fn new_for_profile_identity_id( profile .identity .auth - .memory - .match_scope(auth_url) - .is_some_and(|auth| auth.profile_identity_id == profile_identity_id) + .is_matches(auth_url, profile_identity_id) // @TODO direct call? } diff --git a/src/app/browser/window/tab/item/page/navigation.rs b/src/app/browser/window/tab/item/page/navigation.rs index 15a21d16..654a8ab2 100644 --- a/src/app/browser/window/tab/item/page/navigation.rs +++ b/src/app/browser/window/tab/item/page/navigation.rs @@ -77,7 +77,7 @@ impl Navigation { self.history.update(); self.reload.update(!request.is_empty()); self.request - .update(self.profile.identity.match_scope(&request).is_some()); + .update(self.profile.identity.get(&request).is_some()); self.home.update(); } diff --git a/src/profile/identity.rs b/src/profile/identity.rs index 3cc10ea5..ca8a3a59 100644 --- a/src/profile/identity.rs +++ b/src/profile/identity.rs @@ -126,8 +126,8 @@ impl Identity { /// Get `Identity` match `request` /// * [Client certificates specification](https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates) /// * this function work with memory cache (not database) - pub fn match_scope(&self, request: &str) -> Option { - if let Some(auth) = self.auth.memory.match_scope(request) { + pub fn get(&self, request: &str) -> Option { + if let Some(auth) = self.auth.get(request) { match self.memory.get(auth.profile_identity_id) { Ok(pem) => { return Some(Item { diff --git a/src/profile/identity/auth.rs b/src/profile/identity/auth.rs index e47d1681..8e24bed8 100644 --- a/src/profile/identity/auth.rs +++ b/src/profile/identity/auth.rs @@ -41,14 +41,15 @@ impl Auth { /// * deactivate active auth by remove previous records from `Self` database /// * reindex `Self` memory index on success /// * return last insert `profile_identity_auth_id` on success - pub fn apply(&self, profile_identity_id: i64, auth_url: &str) -> Result { - let scope = filter_scope(auth_url); - + pub fn apply(&self, profile_identity_id: i64, request: &str) -> Result { // Cleanup records match `scope` (unauthorize) - self.remove_scope(&scope)?; + self.remove(request)?; // 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, Err(e) => return Err(Error::Database(e)), }; @@ -61,8 +62,8 @@ impl Auth { } /// Remove all records match request (unauthorize) - pub fn remove_scope(&self, scope: &str) -> Result<(), Error> { - match self.database.records_scope(Some(scope)) { + pub fn remove(&self, request: &str) -> Result<(), Error> { + match self.database.records_scope(Some(&filter_scope(request))) { Ok(records) => { for record in records { if let Err(e) = self.database.delete(record.id) { @@ -113,6 +114,20 @@ impl Auth { 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 { + self.memory.match_scope(&filter_scope(request)) + } } // Tools diff --git a/src/profile/identity/auth/memory.rs b/src/profile/identity/auth/memory.rs index 737a3c85..8730ea10 100644 --- a/src/profile/identity/auth/memory.rs +++ b/src/profile/identity/auth/memory.rs @@ -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) - /// * contain unspecified length priority implementation @TODO - pub fn match_scope(&self, request: &str) -> Option { + /// * see also parent `is_match_request` + pub fn match_scope(&self, scope: &str) -> Option { let mut result = Vec::new(); - // Get all records starts with `scope` - let query = super::filter_scope(request); - - for (scope, &profile_identity_id) in self.index.borrow().iter() { - if query.starts_with(scope) { + for (value, &profile_identity_id) in self.index.borrow().iter() { + if scope.starts_with(value) { result.push(Auth { profile_identity_id, - scope: scope.clone(), + scope: value.clone(), }) } }