I don't really have any great plan for HaRSS. I don't intent to make it a start up, nor anthing like this, but I intent to make it available for free to everyone, as long as it doesn't cost me too much money. Or time. Or sanity.
So all of this implies have some kind of users management.
The present
Currently, the user model looks like this:
Field | Type | Extra |
---|---|---|
id | int (serial) | primary key, auto increments, not null |
username | text | unique, not null |
password | text | not null, argon2 hashed |
role | enum | admin / basic |
Or as rust structure, because I write rust (on arch) by the way™
/// A HaRss user
#[derive(Debug, Clone, Serialize)]
pub struct User {
pub id: i32,
pub username: String,
#[serde(skip)] // Never ever serialize this field, it's hashed anyway
pub password: String,
pub role: UserRole,
}
#[derive(sqlx::Type, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[sqlx(type_name = "user_role", rename_all = "lowercase")]
pub enum UserRole {
Admin,
User,
}
So yeah, it's really simple. I don't see why I would want something more complicated. Not that I am not a privacy advocate (I think I am?), but the truth is that I don't care about having more information about the users.
But what happens is a user forgot it's passord and/or username. I now need the user's email to send them a new one, and it comes with some little challenges.
What's next
I am not a lawyer. At all. I watched Ally McBeal a lot when I was a teenager but I'm not sure this count as a valuable experience. So when it comes to RGPD stuff, the only thig I know is that I don't want to store a Personally Identifiable Information, a.k.a PII. I'm not sure an email is considered as a PII, but I don't want to take a chance with this.
So I need the user's emails to send them a new passord, but I can't store them (without hiring a Data Protection Officer).
So just let's hash the email before with store it!
The "user lost it's login/password" workflow becomes (heavily inspired by Owaps cheat sheet):
- DarkNaturo666 forget its password.
- DarkNaruto666 calls the "I lost my login/passord" endpoint, providing its email address.
- The email address is hashed, and matched in our
users
table. - If there is a match, A random generated token is stored in redis and sent
to DarkNaruto666 via email. The token will be valid for a certain period
of time, thanks to Redis's
SETEX
`. - DarkNaruto666 will now be able to call an endpoint, providing the given token and its new password.
Conclusion
This way, we can achieve a reset password workflow without storing plain text email address. The model stays simple and I don't store PII at all. Of course, I won't be able to harass (harass... harss... got it?) user with emails about HaRSS's new features or last survey, but I don't care.
Now I still need to send actual, kind of good looking emails, but it will be treated in another post where I'll write about scaleway's transactional email.
Oh, and one day I will probably want to implements Two Factors Authentication. Please send help.