1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! Controller for children `database` and `memory` components
mod database;
mod error;
mod memory;
use database::Database;
pub use error::Error;
use memory::Memory;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
/// API for `profile_identity_gemini_id` + `scope` auth pairs operations
pub struct Auth {
pub database: Rc<Database>,
pub memory: Rc<Memory>,
}
impl Auth {
// Constructors
/// Create new `Self`
pub fn new(connection: Rc<RwLock<Connection>>) -> Result<Self, Error> {
// Init `Self`
let this = Self {
database: Rc::new(Database::new(connection)),
memory: Rc::new(Memory::new()),
};
// Build initial index
Self::index(&this)?;
// Done
Ok(this)
}
// Actions
/// Apply `profile_identity_gemini_id` certificate as the auth for `scope`
/// * deactivate active auth by remove previous records from `Self` database
/// * reindex `Self` memory index on success
/// * 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(scope)?;
// Create new record (auth)
let profile_identity_gemini_auth_id =
match self.database.add(profile_identity_gemini_id, scope) {
Ok(id) => id,
Err(reason) => return Err(Error::Database(reason)),
};
// Reindex
self.index()?;
// Done
Ok(profile_identity_gemini_auth_id)
}
/// Remove all records match request (unauthorize)
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) {
return Err(Error::Database(reason));
}
}
}
Err(reason) => return Err(Error::Database(reason)),
}
self.index()?;
Ok(())
}
/// Create new `Memory` index from `Database` for `Self`
pub fn index(&self) -> Result<(), Error> {
// Clear previous records
if let Err(reason) = self.memory.clear() {
return Err(Error::Memory(reason));
}
// Build new index
match self.database.records_scope(None) {
Ok(records) => {
for record in records {
if let Err(reason) = self
.memory
.add(record.scope, record.profile_identity_gemini_id)
{
return Err(Error::Memory(reason));
}
}
}
Err(reason) => return Err(Error::Database(reason)),
}
Ok(())
}
}
// Tools
pub fn migrate(tx: &Transaction) -> Result<(), String> {
// Migrate self components
if let Err(e) = database::init(tx) {
return Err(e.to_string());
}
// Delegate migration to childs
// nothing yet..
Ok(())
}