New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
politeiawww: Rate limit email. #1398
Comments
Hi, I would leave some thoughts here (disscuss a possible implementation).
I believe rate limiting can be eventually consistent, its probably not a big deal if some user from time to time performs 110 or even 210 requests per day instead of 100.
if that's not enough (e.g. we want this "rate limiting data" to be stored between server restarts), we can make it persistent:
also, while implementing this (better even, before implementing this), in order to be able to test rate limiting (as well as cover new email-sending functionality with unit-tests in the future - looks like there are no tests covering that at all at the moment) and not increase the complexity of If nobody is working on it, I could try to start working on this to get myself familiar with the project. |
Also, maybe for everyone to be on the same page, can you provide some description for "why we need this rate limiting in the first place ?", some user stories that require addressing this issue. |
There are user actions that trigger email notifications that could be abused in order to get the email server classified as spam. For example, a malicious user could run a bot that continually resets the user's password, each one triggering a new notification email. It makes more sense to rate limit the number of daily emails that can be sent rather than rate limiting the individual user actions.
Agreed.
We're in the process of removing all memory caches so that politeiawww instances can be scaled out. We're going to want to persist this email rate limit data.
This option is what we're going to want to do. Email notifications are setup at the application level (pi, cms). Examle: pi notifications. The notifications are already being sent in a separate go routine, which I think alleviates any performance concerns that I originally had. Thinking through this a little more, here's how I would probably impelement it:
This is just a rough outline off the top of my head. I'm open to other ideas if you think there is a better way to do it or if you encounter potential issues during the implementation. The existing user database implemenation and a lot of the user layer is going to be rewritten as part of the upcoming pi proposal roadmap. A lot of the old code in
@LasTshaMAN great! Please do. |
Thanks for elaborating.
Nice to know, got it! Overall the proposed solution looks good to me (striking proper balance between implementation complexity & performance).
// NotificationIsEnabled returns whether the user has the provided notification
// bit enabled. This function will always return false if the user has been
// deactivated.
func (u *User) NotificationIsEnabled(ntfnBit uint64) bool {
if u.Deactivated {
return false
}
return u.EmailNotifications&ntfnBit != 0
} so that both There are some places in the code, e.g. here, where we don't readily have The approach I've described above (lets call it approach 1) assumes that we store "email history" with the Alternatively I can think of approach 2, based on extending Let me know whether any of these 2 approaches seem OK to you, so I can start some implementation. |
One thing to keep in mind is that most of this code will be refactored in the near future as part of the user layer work outlined in the pi proposal. A plugin architecture is going to be applied to the user layer that is similar to the plugin architecture that was applied to politeiad in the v1.0.0 release. Email notifications are going to abstracted into an optional user plugin. All of this functionality will be moved into the email notifications plugin.
Right now the event handlers iterate through every user in the db and manually check their notification prefence. This is not scalable. The user layer rewrite will allow the db to be queried by notification setting so the
The event handler code will live in the application packages. The only application package that currently exist is the The reason I wanted to include the rate limit logic in the I agree though that it doesn't really belong there. I like your
Don't worry about the CMS code for now. Its legacy code that will be rewritten in the near future once the user plugin architecture has been implement. You can use the
I think if the user db interface had transaction capabilities it would be fine, but it doesn't so I agree. Lets use a separate table to prevent races on the user record. To summarize, let's go with your |
Okay, sounds good, I'll drop a PR maybe in 2-3 days. |
Add a configurable email limit for user accounts. The limit should default to 100 emails per user per day. It should be possible to specify a different value on startup if the server operator wants to.
A potential issue with this is going to be the performance overhead of updating a large batch of users in the database everytime a email notification is sent. This needs to be done in a scalable way.
The text was updated successfully, but these errors were encountered: