Let’s get started with a barebones authentication example. First, we’ll define a few simple types.
use microrm::prelude::*;
#[derive(Entity)]
struct User {
#[key]
username: String,
password_hash: String,
authz: microrm::Map<Action>,
}
#[derive(Entity)]
struct Action {
#[key]
title: String,
}
#[derive(Schema)]
struct AuthSchema {
users: microrm::Table<User>,
actions: microrm::Table<Action>,
}
That’s it; this defines a database schema of users and actions, where users can be configured to be authorized for a set of actions. Now let’s open the database and insert some example data:
let (cpool, schema) =
microrm::ConnectionPool::open::<AuthSchema>("auth.db")
.expect("couldn't connect to database");
cpool.run_transaction(1, |txn| {
// add some users
let alice = schema.users.insert_and_return(txn, User {
username: "alice".into(),
password_hash: "somehash".into(),
authz: Default::default(),
})?;
let barbara = schema.users.insert_and_return(txn, User {
username: "barbara".into(),
password_hash: "someotherhash".into(),
authz: Default::default(),
})?;
// now a few different actions as well
let front_door_id = schema.actions.insert(txn, Action {
title: "unlock front door".into()
})?;
let oven_id = schema.actions.insert(txn, Action {
title: "turn on the oven".into()
})?;
let feed_cat_id = schema.actions.insert(txn, Action {
title: "feed the cat".into()
})?;
// and now let's assign some simple authz
alice.authz.connect(txn, front_door_id)?;
alice.authz.connect(txn, feed_cat_id)?;
barbara.authz.connect(txn, front_door_id)?;
barbara.authz.connect(txn, oven_id)?;
Ok(())
}).expect("couldn't insert data into database");
Now we can run queries against the database! For example, is ‘alice’ allowed to ‘turn on the oven’?
let allowed : bool = cpool.run_transaction(1, |txn| {
Ok(schema
.users
.keyed("alice")
.join(User::Authz)
.keyed("turn on the oven")
.count(txn)? > 0
)
}).expect("couldn't run query");
Barbara forgot to turn off the oven again, let’s revoke her privilege:
cpool.run_transaction(1, |txn| {
let barbara = schema
.users
.keyed("barbara")
.get(txn)?
.unwrap();
let oven_authz = schema
.authz
.keyed("turn on the oven")
.get(txn)?
.unwrap();
barbara.authz.disconnect(txn, oven_authz)?;
Ok(())
}).expect("couldn't run query");
For more possible queries, check out the API documentation.
Congrats! You’ve defined a schema, added some data, and run some queries. For more information on what exactly was happening here, see the next chapter, Entities and Schemas.