implement identity remove action

This commit is contained in:
yggverse 2024-11-29 05:44:40 +02:00
parent 00afa70d5d
commit 29083f50d9
8 changed files with 241 additions and 18 deletions

View file

@ -68,6 +68,20 @@ impl Gemini {
}
}
/// Delete record from database including children dependencies, update memory index
pub fn delete(&self, profile_identity_gemini_id: i64) -> Result<(), Error> {
match self.auth.remove_ref(profile_identity_gemini_id) {
Ok(_) => match self.database.delete(profile_identity_gemini_id) {
Ok(_) => {
self.index()?;
Ok(())
}
Err(reason) => Err(Error::Database(reason)),
},
Err(e) => Err(Error::Auth(e)),
}
}
/// Generate new certificate and insert record to DB, update memory index
/// * return new `profile_identity_gemini_id` on success
pub fn make(&self, time: Option<(DateTime, DateTime)>, name: &str) -> Result<i64, Error> {

View file

@ -43,7 +43,7 @@ impl Auth {
/// * return last insert `profile_identity_gemini_auth_id` on success
pub fn apply(&self, profile_identity_gemini_id: i64, scope: &str) -> Result<i64, Error> {
// Cleanup records match `scope` (unauthorize)
self.remove(scope)?;
self.remove_scope(scope)?;
// Create new record (auth)
let profile_identity_gemini_auth_id =
@ -60,8 +60,24 @@ impl Auth {
}
/// Remove all records match request (unauthorize)
pub fn remove(&self, scope: &str) -> Result<(), Error> {
match self.database.records(Some(scope)) {
pub fn remove_scope(&self, scope: &str) -> Result<(), Error> {
match self.database.records_scope(Some(scope)) {
Ok(records) => {
for record in records {
if let Err(reason) = self.database.delete(record.id) {
return Err(Error::Database(reason));
}
}
}
Err(reason) => return Err(Error::Database(reason)),
}
self.index()?;
Ok(())
}
/// Remove all records match `profile_identity_gemini_id` foreign reference key
pub fn remove_ref(&self, profile_identity_gemini_id: i64) -> Result<(), Error> {
match self.database.records_ref(profile_identity_gemini_id) {
Ok(records) => {
for record in records {
if let Err(reason) = self.database.delete(record.id) {
@ -83,7 +99,7 @@ impl Auth {
}
// Build new index
match self.database.records(None) {
match self.database.records_scope(None) {
Ok(records) => {
for record in records {
if let Err(reason) = self

View file

@ -60,10 +60,17 @@ impl Database {
// Getters
/// Get records from database match current `profile_id` optionally filtered by `scope`
pub fn records(&self, scope: Option<&str>) -> Result<Vec<Table>, Error> {
pub fn records_scope(&self, scope: Option<&str>) -> Result<Vec<Table>, Error> {
let readable = self.connection.read().unwrap(); // @TODO
let tx = readable.unchecked_transaction()?;
select(&tx, scope)
select_scope(&tx, scope)
}
/// Get records from database match current `profile_id` optionally filtered by `scope`
pub fn records_ref(&self, profile_identity_gemini_id: i64) -> Result<Vec<Table>, Error> {
let readable = self.connection.read().unwrap(); // @TODO
let tx = readable.unchecked_transaction()?;
select_ref(&tx, profile_identity_gemini_id)
}
}
@ -105,7 +112,7 @@ pub fn delete(tx: &Transaction, id: i64) -> Result<usize, Error> {
)
}
pub fn select(tx: &Transaction, scope: Option<&str>) -> Result<Vec<Table>, Error> {
pub fn select_scope(tx: &Transaction, scope: Option<&str>) -> Result<Vec<Table>, Error> {
let mut stmt = tx.prepare(
"SELECT `id`,
`profile_identity_gemini_id`,
@ -133,6 +140,34 @@ pub fn select(tx: &Transaction, scope: Option<&str>) -> Result<Vec<Table>, Error
Ok(records)
}
pub fn select_ref(tx: &Transaction, profile_identity_gemini_id: i64) -> Result<Vec<Table>, Error> {
let mut stmt = tx.prepare(
"SELECT `id`,
`profile_identity_gemini_id`,
`scope`
FROM `profile_identity_gemini_auth`
WHERE `profile_identity_gemini_id` = ?",
)?;
let result = stmt.query_map([profile_identity_gemini_id], |row| {
Ok(Table {
id: row.get(0)?,
profile_identity_gemini_id: row.get(1)?,
scope: row.get(2)?,
})
})?;
let mut records = Vec::new();
for record in result {
let table = record?;
records.push(table);
}
Ok(records)
}
pub fn last_insert_id(tx: &Transaction) -> i64 {
tx.last_insert_rowid()
}

View file

@ -45,6 +45,22 @@ impl Database {
}
}
/// Delete record with given `id` from database
pub fn delete(&self, id: i64) -> Result<(), Error> {
// Begin new transaction
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
// Create new record
delete(&tx, id)?;
// Done
match tx.commit() {
Ok(_) => Ok(()),
Err(reason) => Err(reason),
}
}
/// Get single record match `id`
pub fn record(&self, id: i64) -> Result<Option<Table>, Error> {
let readable = self.connection.read().unwrap();
@ -94,6 +110,10 @@ pub fn insert(tx: &Transaction, profile_identity_id: i64, pem: &str) -> Result<u
)
}
pub fn delete(tx: &Transaction, id: i64) -> Result<usize, Error> {
tx.execute("DELETE FROM `profile_identity_gemini` WHERE `id` = ?", [id])
}
pub fn select(tx: &Transaction, profile_identity_id: i64) -> Result<Vec<Table>, Error> {
let mut stmt = tx.prepare(
"SELECT `id`,

View file

@ -11,14 +11,14 @@ pub enum Error {
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
Self::Auth(reason) => write!(f, "Could not create auth: {reason}"),
Self::Certificate(reason) => {
write!(f, "Could not create certificate: {reason}")
Self::Auth(e) => write!(f, "Could not create auth: {e}"),
Self::Certificate(e) => {
write!(f, "Could not create certificate: {e}")
}
Self::Database(reason) => {
write!(f, "Database error: {reason}")
Self::Database(e) => {
write!(f, "Database error: {e}")
}
Self::Memory(reason) => write!(f, "Memory error: {reason}"),
Self::Memory(e) => write!(f, "Memory error: {e}"),
}
}
}