mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-04-01 00:55:28 +00:00
make multi-protocol identity feature
This commit is contained in:
parent
92550a2ccc
commit
12d79792d9
33 changed files with 309 additions and 593 deletions
|
|
@ -164,7 +164,6 @@ fn handle(
|
|||
.page
|
||||
.profile
|
||||
.identity
|
||||
.gemini
|
||||
.match_scope(&uri.to_string())
|
||||
{
|
||||
Some(identity) => match identity.to_tls_certificate() {
|
||||
|
|
|
|||
|
|
@ -42,25 +42,20 @@ impl Gemini {
|
|||
move |response| {
|
||||
// Get option match user choice
|
||||
let option = match response {
|
||||
Value::ProfileIdentityGeminiId(value) => Some(value),
|
||||
Value::ProfileIdentityId(value) => Some(value),
|
||||
Value::GuestSession => None,
|
||||
Value::GeneratePem => Some(
|
||||
match profile
|
||||
.identity
|
||||
.gemini
|
||||
.make(None, &widget.form.name.value().unwrap())
|
||||
{
|
||||
Ok(profile_identity_gemini_id) => profile_identity_gemini_id,
|
||||
Ok(profile_identity_id) => profile_identity_id,
|
||||
Err(e) => todo!("{}", e.to_string()),
|
||||
},
|
||||
),
|
||||
Value::ImportPem => Some(
|
||||
match profile
|
||||
.identity
|
||||
.gemini
|
||||
.add(&widget.form.file.pem.take().unwrap())
|
||||
{
|
||||
Ok(profile_identity_gemini_id) => profile_identity_gemini_id,
|
||||
match profile.identity.add(&widget.form.file.pem.take().unwrap()) {
|
||||
Ok(profile_identity_id) => profile_identity_id,
|
||||
Err(e) => todo!("{}", e.to_string()),
|
||||
},
|
||||
),
|
||||
|
|
@ -69,19 +64,15 @@ impl Gemini {
|
|||
// Apply auth
|
||||
match option {
|
||||
// Activate identity for `auth_uri`
|
||||
Some(profile_identity_gemini_id) => {
|
||||
if let Err(e) = profile
|
||||
.identity
|
||||
.gemini
|
||||
.auth
|
||||
.apply(profile_identity_gemini_id, &auth_url)
|
||||
Some(profile_identity_id) => {
|
||||
if let Err(e) = profile.identity.auth.apply(profile_identity_id, &auth_url)
|
||||
{
|
||||
todo!("{}", e.to_string())
|
||||
};
|
||||
}
|
||||
// Remove all identity auths for `auth_uri`
|
||||
None => {
|
||||
if let Err(e) = profile.identity.gemini.auth.remove_scope(&auth_url) {
|
||||
if let Err(e) = profile.identity.auth.remove_scope(&auth_url) {
|
||||
todo!("{}", e.to_string())
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,19 +104,16 @@ impl Form {
|
|||
self.file.update(matches!(value, Value::ImportPem));
|
||||
|
||||
match value {
|
||||
Value::ProfileIdentityGeminiId(profile_identity_gemini_id) => {
|
||||
Value::ProfileIdentityId(profile_identity_id) => {
|
||||
self.drop.update(true);
|
||||
self.exit.update(
|
||||
true,
|
||||
self.profile
|
||||
.identity
|
||||
.gemini
|
||||
.auth
|
||||
.memory
|
||||
.match_scope(&self.auth_uri.to_string())
|
||||
.is_some_and(|auth| {
|
||||
auth.profile_identity_gemini_id == profile_identity_gemini_id
|
||||
}),
|
||||
.is_some_and(|auth| auth.profile_identity_id == profile_identity_id),
|
||||
);
|
||||
self.save.update(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ impl Drop {
|
|||
let profile = profile.clone();
|
||||
move |_| {
|
||||
match list.selected().value_enum() {
|
||||
Value::ProfileIdentityGeminiId(profile_identity_gemini_id) => {
|
||||
Value::ProfileIdentityId(profile_identity_id) => {
|
||||
// Init sub-widget
|
||||
let alert_dialog = AlertDialog::builder()
|
||||
.heading(HEADING)
|
||||
|
|
@ -74,13 +74,9 @@ impl Drop {
|
|||
let button = button.clone();
|
||||
let list = list.clone();
|
||||
let profile = profile.clone();
|
||||
move |_, _| match profile
|
||||
.identity
|
||||
.gemini
|
||||
.delete(profile_identity_gemini_id)
|
||||
{
|
||||
move |_, _| match profile.identity.delete(profile_identity_id) {
|
||||
Ok(_) => {
|
||||
if list.remove(profile_identity_gemini_id).is_some() {
|
||||
if list.remove(profile_identity_id).is_some() {
|
||||
button.set_css_classes(&["success"]);
|
||||
button.set_label("Identity successfully deleted")
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ impl Exit {
|
|||
move |_| {
|
||||
// Get selected identity from holder
|
||||
match list.selected().value_enum() {
|
||||
Value::ProfileIdentityGeminiId(profile_identity_gemini_id) => {
|
||||
Value::ProfileIdentityId(profile_identity_id) => {
|
||||
// Init sub-widget
|
||||
let alert_dialog = AlertDialog::builder()
|
||||
.heading(HEADING)
|
||||
|
|
@ -91,12 +91,7 @@ impl Exit {
|
|||
let browser_action = browser_action.clone();
|
||||
let widget_action = widget_action.clone();
|
||||
move |_, _| {
|
||||
match profile
|
||||
.identity
|
||||
.gemini
|
||||
.auth
|
||||
.remove_ref(profile_identity_gemini_id)
|
||||
{
|
||||
match profile.identity.auth.remove_ref(profile_identity_id) {
|
||||
Ok(_) => match list
|
||||
.selected()
|
||||
.update(&profile, &auth_uri.to_string())
|
||||
|
|
|
|||
|
|
@ -38,15 +38,12 @@ impl List {
|
|||
list_store.append(&generate_pem);
|
||||
list_store.append(&import_pem);
|
||||
|
||||
match profile.identity.gemini.database.records() {
|
||||
match profile.identity.database.records() {
|
||||
Ok(identities) => {
|
||||
let mut is_guest_session = true;
|
||||
for identity in identities {
|
||||
match Item::new_profile_identity_gemini_id(
|
||||
profile,
|
||||
identity.id,
|
||||
&auth_uri.to_string(),
|
||||
) {
|
||||
match Item::new_profile_identity_id(profile, identity.id, &auth_uri.to_string())
|
||||
{
|
||||
Ok(item) => {
|
||||
if item.is_active() {
|
||||
is_guest_session = false;
|
||||
|
|
@ -178,18 +175,18 @@ impl List {
|
|||
|
||||
// Actions
|
||||
|
||||
/// Find list item by `profile_identity_gemini_id`
|
||||
/// Find list item by `profile_identity_id`
|
||||
/// * return `position` found
|
||||
pub fn find(&self, profile_identity_gemini_id: i64) -> Option<u32> {
|
||||
pub fn find(&self, profile_identity_id: i64) -> Option<u32> {
|
||||
self.list_store.find_with_equal_func(|this| {
|
||||
profile_identity_gemini_id == this.downcast_ref::<Item>().unwrap().value()
|
||||
profile_identity_id == this.downcast_ref::<Item>().unwrap().value()
|
||||
})
|
||||
}
|
||||
|
||||
/// Remove list item by `profile_identity_gemini_id`
|
||||
/// Remove list item by `profile_identity_id`
|
||||
/// * return `position` of removed list item
|
||||
pub fn remove(&self, profile_identity_gemini_id: i64) -> Option<u32> {
|
||||
match self.find(profile_identity_gemini_id) {
|
||||
pub fn remove(&self, profile_identity_id: i64) -> Option<u32> {
|
||||
match self.find(profile_identity_id) {
|
||||
Some(position) => {
|
||||
self.list_store.remove(position);
|
||||
Some(position)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ glib::wrapper! {
|
|||
}
|
||||
|
||||
// C-type property `value` conversion for `Item`
|
||||
// * values > 0 reserved for `profile_identity_gemini_id`
|
||||
// * values > 0 reserved for `profile_identity_id`
|
||||
const G_VALUE_GENERATE_PEM: i64 = 0;
|
||||
const G_VALUE_IMPORT_PEM: i64 = -1;
|
||||
const G_VALUE_GUEST_SESSION: i64 = -2;
|
||||
|
|
@ -53,42 +53,34 @@ impl Item {
|
|||
.build()
|
||||
}
|
||||
|
||||
pub fn new_profile_identity_gemini_id(
|
||||
pub fn new_profile_identity_id(
|
||||
profile: &Rc<Profile>,
|
||||
profile_identity_gemini_id: i64,
|
||||
profile_identity_id: i64,
|
||||
auth_url: &str,
|
||||
) -> Result<Self, Error> {
|
||||
// Get PEM by ID
|
||||
match profile
|
||||
.identity
|
||||
.gemini
|
||||
.memory
|
||||
.get(profile_identity_gemini_id)
|
||||
{
|
||||
match profile.identity.memory.get(profile_identity_id) {
|
||||
// Extract certificate details from PEM string
|
||||
Ok(ref pem) => match TlsCertificate::from_pem(pem) {
|
||||
// Collect certificate scopes for item
|
||||
Ok(ref certificate) => match scope(profile, profile_identity_gemini_id) {
|
||||
Ok(ref certificate) => match scope(profile, profile_identity_id) {
|
||||
// Ready to build `Item` GObject
|
||||
Ok(ref scope) => Ok(Object::builder()
|
||||
.property("value", profile_identity_gemini_id)
|
||||
.property(
|
||||
"title",
|
||||
title::new_for_profile_identity_gemini_id(certificate),
|
||||
)
|
||||
.property("value", profile_identity_id)
|
||||
.property("title", title::new_for_profile_identity_id(certificate))
|
||||
.property(
|
||||
"subtitle",
|
||||
subtitle::new_for_profile_identity_gemini_id(certificate, scope),
|
||||
subtitle::new_for_profile_identity_id(certificate, scope),
|
||||
)
|
||||
.property(
|
||||
"tooltip",
|
||||
tooltip::new_for_profile_identity_gemini_id(certificate, scope),
|
||||
tooltip::new_for_profile_identity_id(certificate, scope),
|
||||
)
|
||||
.property(
|
||||
"is-active",
|
||||
is_active::new_for_profile_identity_gemini_id(
|
||||
is_active::new_for_profile_identity_id(
|
||||
profile,
|
||||
profile_identity_gemini_id,
|
||||
profile_identity_id,
|
||||
auth_url,
|
||||
),
|
||||
)
|
||||
|
|
@ -107,36 +99,31 @@ impl Item {
|
|||
pub fn update(&self, profile: &Rc<Profile>, auth_url: &str) -> Result<(), Error> {
|
||||
// Update item depending on value type
|
||||
match self.value_enum() {
|
||||
Value::ProfileIdentityGeminiId(profile_identity_gemini_id) => {
|
||||
Value::ProfileIdentityId(profile_identity_id) => {
|
||||
// Get PEM by ID
|
||||
match profile
|
||||
.identity
|
||||
.gemini
|
||||
.memory
|
||||
.get(profile_identity_gemini_id)
|
||||
{
|
||||
match profile.identity.memory.get(profile_identity_id) {
|
||||
// Extract certificate details from PEM string
|
||||
Ok(ref pem) => match TlsCertificate::from_pem(pem) {
|
||||
Ok(ref certificate) => {
|
||||
// Get current scope
|
||||
let scope = &scope(profile, profile_identity_gemini_id)?;
|
||||
let scope = &scope(profile, profile_identity_id)?;
|
||||
|
||||
// Update properties
|
||||
self.set_title(title::new_for_profile_identity_gemini_id(certificate));
|
||||
self.set_title(title::new_for_profile_identity_id(certificate));
|
||||
|
||||
self.set_subtitle(subtitle::new_for_profile_identity_gemini_id(
|
||||
self.set_subtitle(subtitle::new_for_profile_identity_id(
|
||||
certificate,
|
||||
scope,
|
||||
));
|
||||
|
||||
self.set_tooltip(tooltip::new_for_profile_identity_gemini_id(
|
||||
self.set_tooltip(tooltip::new_for_profile_identity_id(
|
||||
certificate,
|
||||
scope,
|
||||
));
|
||||
|
||||
self.set_is_active(is_active::new_for_profile_identity_gemini_id(
|
||||
self.set_is_active(is_active::new_for_profile_identity_id(
|
||||
profile,
|
||||
profile_identity_gemini_id,
|
||||
profile_identity_id,
|
||||
auth_url,
|
||||
));
|
||||
|
||||
|
|
@ -162,21 +149,21 @@ impl Item {
|
|||
G_VALUE_GENERATE_PEM => Value::GeneratePem,
|
||||
G_VALUE_GUEST_SESSION => Value::GuestSession,
|
||||
G_VALUE_IMPORT_PEM => Value::ImportPem,
|
||||
value => Value::ProfileIdentityGeminiId(value),
|
||||
value => Value::ProfileIdentityId(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tools
|
||||
|
||||
/// Collect certificate scope vector from `Profile` database for `profile_identity_gemini_id`
|
||||
fn scope(profile: &Rc<Profile>, profile_identity_gemini_id: i64) -> Result<Vec<String>, Error> {
|
||||
match profile.identity.gemini.auth.database.records_scope(None) {
|
||||
/// Collect certificate scope vector from `Profile` database for `profile_identity_id`
|
||||
fn scope(profile: &Rc<Profile>, profile_identity_id: i64) -> Result<Vec<String>, Error> {
|
||||
match profile.identity.auth.database.records_scope(None) {
|
||||
Ok(result) => {
|
||||
let mut scope = Vec::new();
|
||||
for auth in result
|
||||
.iter()
|
||||
.filter(|this| this.profile_identity_gemini_id == profile_identity_gemini_id)
|
||||
.filter(|this| this.profile_identity_id == profile_identity_id)
|
||||
{
|
||||
scope.push(auth.scope.clone())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
use crate::profile::Profile;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub fn new_for_profile_identity_gemini_id(
|
||||
pub fn new_for_profile_identity_id(
|
||||
profile: &Rc<Profile>,
|
||||
profile_identity_gemini_id: i64,
|
||||
profile_identity_id: i64,
|
||||
auth_url: &str,
|
||||
) -> bool {
|
||||
profile
|
||||
.identity
|
||||
.gemini
|
||||
.auth
|
||||
.memory
|
||||
.match_scope(auth_url)
|
||||
.is_some_and(|auth| auth.profile_identity_gemini_id == profile_identity_gemini_id)
|
||||
.is_some_and(|auth| auth.profile_identity_id == profile_identity_id)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,7 @@ use gtk::{gio::TlsCertificate, prelude::TlsCertificateExt};
|
|||
|
||||
const DATE_FORMAT: &str = "%Y.%m.%d";
|
||||
|
||||
pub fn new_for_profile_identity_gemini_id(
|
||||
certificate: &TlsCertificate,
|
||||
scope: &[String],
|
||||
) -> String {
|
||||
pub fn new_for_profile_identity_id(certificate: &TlsCertificate, scope: &[String]) -> String {
|
||||
format!(
|
||||
"{} - {} | scope: {}",
|
||||
certificate
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use gtk::{gio::TlsCertificate, glib::gformat, prelude::TlsCertificateExt};
|
||||
|
||||
pub fn new_for_profile_identity_gemini_id(certificate: &TlsCertificate) -> String {
|
||||
pub fn new_for_profile_identity_id(certificate: &TlsCertificate) -> String {
|
||||
certificate
|
||||
.subject_name()
|
||||
.unwrap_or(gformat!("Unknown"))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
use gtk::{gio::TlsCertificate, prelude::TlsCertificateExt};
|
||||
|
||||
pub fn new_for_profile_identity_gemini_id(
|
||||
certificate: &TlsCertificate,
|
||||
scope: &[String],
|
||||
) -> String {
|
||||
pub fn new_for_profile_identity_id(certificate: &TlsCertificate, scope: &[String]) -> String {
|
||||
let mut tooltip = "<b>Certificate</b>\n".to_string();
|
||||
|
||||
if let Some(subject_name) = certificate.subject_name() {
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@ pub enum Value {
|
|||
GeneratePem,
|
||||
GuestSession,
|
||||
ImportPem,
|
||||
ProfileIdentityGeminiId(i64),
|
||||
ProfileIdentityId(i64),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,12 +40,12 @@ impl Save {
|
|||
move |_| {
|
||||
// Get selected identity from holder
|
||||
match list.selected().value_enum() {
|
||||
Value::ProfileIdentityGeminiId(profile_identity_gemini_id) => {
|
||||
Value::ProfileIdentityId(profile_identity_id) => {
|
||||
// Lock open button (prevent double click)
|
||||
button.set_sensitive(false);
|
||||
|
||||
// Create PEM file based on option ID selected
|
||||
match Certificate::new(profile.clone(), profile_identity_gemini_id) {
|
||||
match Certificate::new(profile.clone(), profile_identity_id) {
|
||||
Ok(certificate) => {
|
||||
// Init file filters related with PEM extension
|
||||
let filters = ListStore::new::<FileFilter>();
|
||||
|
|
|
|||
|
|
@ -15,13 +15,8 @@ impl Certificate {
|
|||
// Constructors
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new(profile: Rc<Profile>, profile_identity_gemini_id: i64) -> Result<Self, Error> {
|
||||
match profile
|
||||
.identity
|
||||
.gemini
|
||||
.database
|
||||
.record(profile_identity_gemini_id)
|
||||
{
|
||||
pub fn new(profile: Rc<Profile>, profile_identity_id: i64) -> Result<Self, Error> {
|
||||
match profile.identity.database.record(profile_identity_id) {
|
||||
Ok(record) => match record {
|
||||
Some(identity) => match TlsCertificate::from_pem(&identity.pem) {
|
||||
Ok(certificate) => Ok(Self {
|
||||
|
|
@ -30,7 +25,7 @@ impl Certificate {
|
|||
}),
|
||||
Err(e) => Err(Error::TlsCertificate(e)),
|
||||
},
|
||||
None => Err(Error::NotFound(profile_identity_gemini_id)),
|
||||
None => Err(Error::NotFound(profile_identity_id)),
|
||||
},
|
||||
Err(e) => Err(Error::Database(e)),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ impl Display for Error {
|
|||
Self::Database(e) => {
|
||||
write!(f, "Database error: {e}")
|
||||
}
|
||||
Self::NotFound(profile_identity_gemini_id) => {
|
||||
write!(f, "Record for `{profile_identity_gemini_id}` not found")
|
||||
Self::NotFound(profile_identity_id) => {
|
||||
write!(f, "Record for `{profile_identity_id}` not found")
|
||||
}
|
||||
Self::TlsCertificate(e) => {
|
||||
write!(f, "TLS certificate error: {e}")
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ impl Navigation {
|
|||
self.request.update(
|
||||
self.profile
|
||||
.identity
|
||||
.gemini
|
||||
.auth
|
||||
.memory
|
||||
.match_scope(&request)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue