Notification blacklists should be user-editable
Categories
(Taskcluster :: Services, enhancement)
Tracking
(Not tracked)
People
(Reporter: dustin, Assigned: ojaswin25111998, Mentored)
Details
We have a blacklist for notifications, but it's a service configuration..
We could, instead, store that information in a table and make it editable via the UI, covered by some administrative scope.
Later, we could potentially track bounces automatically and automatically blacklist addresses that bounce too much, but let's leave that to a followup.
Reporter | ||
Comment 1•7 years ago
|
||
The code for this is in services/notify in https://github.com/taskcluster/taskcluster. You can see that there's a "blacklist" in config.yml in that application already. A few of the pieces of completing this project:
- create an Azure table (or database table) to contain blacklisted notification destinations [1]
- make API methods to modify that table (list, get, add, update, delete)
- make UI changes that use those API methods to manage the data
- make the notification service read from the table to determine if a destination is blacklisted, before sending the notification
[1] Let's not limit this to emails -- any kind of notification should be possible to blacklist
Reporter | ||
Updated•7 years ago
|
Hey i was wondering how should the table be? Just one property for the address?
Reporter | ||
Comment 4•7 years ago
|
||
That makes sense -- or a column for the notification type (irc, email, pulse) and a column for the destination. The format of that destination column may need to be JSON, to hold the irc value.
I started working on the azure table. The PR can be found here https://github.com/taskcluster/taskcluster/pull/127
- make API methods to modify that table (list, get, add, update, delete)
should i user the 'fast-azure-storage' library for this?
Also, the methods go in the same data.js as methods of the entity's prototype, am I right?
Also, the methods go in the same data.js as methods of the entity's prototype, am I right?
Okay, so I looked around some more. I think I had the wrong idea and will have to use the APIBuilder similar to azure.js in services/auth. Please correct me if I'm wrong :)
Reporter | ||
Comment 8•7 years ago
|
||
Sounds like you're close -- a better example might be the APIBuilder in services/notify/src/api.js.
I pushed a new commit with the APIs and schemas. I'll wait for your review before proceeding further. I have some questions though:-
-
For the method to fetch a single notification, should I use the post method since I can't use the GET as address is JSON
-
How should I go about testing my APIs. Right now I have no idea if they'll work or not :p
Reporter | ||
Comment 10•7 years ago
|
||
-
Maybe we should establish some unique id's for blacklist item entries, rather than keying by the contents. We use
slugid
for unique id's elsewhere in Taskcluster. Thenconst blacklistId = slugid.nice() await notify.createBlacklistItem(blacklistId, {notificationType: 'irc-user', notificationAddress: 'dustin'}); const bl = await notify.getBlacklistItem(blacklistId); assert(bl.notificationType === 'irc-user'); await notifiy.removeBlacklistItem(blacklistId);
Also, now that I look at the schemas you've developed, all four notification types (pulse, email, irc-user, irc-channel) have a string as their "address". I remembered incorrectly (I should have checked) that the irc methods specified both a server and a name. So we could generalize the table and the API responses to contain only those two fields (type, address). That would simplify the schemas and APIs quite a bit!
-
You can find some examples of tests in the other services. The secrets service is a good example -- it only has one table and has list, get, set, and remove methods on that table. Its
api_test.js
callswithSecret
which sets up a fake Azure table that is fast and doesn't require you to have access to Azure. Spend a bit of time working that out and show me what you come up with, at which time I can help fill in the details -- there are a lot of parts to set up for tests and I don't want you to spend too much time on it.
Assignee | ||
Comment 11•7 years ago
|
||
(In reply to Dustin J. Mitchell [:dustin] pronoun: he from comment #10)
Maybe we should establish some unique id's for blacklist item entries, rather than keying by the contents. We use
slugid
for unique id's elsewhere in Taskcluster. Thenconst blacklistId = slugid.nice() await notify.createBlacklistItem(blacklistId, {notificationType: 'irc-user', notificationAddress: 'dustin'}); const bl = await notify.getBlacklistItem(blacklistId); assert(bl.notificationType === 'irc-user'); await notifiy.removeBlacklistItem(blacklistId);
Also, now that I look at the schemas you've developed, all four notification types (pulse, email, irc-user, irc-channel) have a string as their "address". I remembered incorrectly (I should have checked) that the irc methods specified both a server and a name. So we could generalize the table and the API responses to contain only those two fields (type, address). That would simplify the schemas and APIs quite a bit!
If the address itself is unique we can directly use it as a query param for retrieval rather than generating a unique slugid. Won't the slugId just add an extra step of passing the generated id back to the user?
- You can find some examples of tests in the other services. The secrets service is a good example -- it only has one table and has list, get, set, and remove methods on that table. Its
api_test.js
callswithSecret
which sets up a fake Azure table that is fast and doesn't require you to have access to Azure. Spend a bit of time working that out and show me what you come up with, at which time I can help fill in the details -- there are a lot of parts to set up for tests and I don't want you to spend too much time on it.
Alright, I'll look around :)
Reporter | ||
Comment 12•7 years ago
|
||
That's true -- there's no need for a blacklistId if the address is always just a string. So I agree, let's do it that way.
Assignee | ||
Comment 13•7 years ago
|
||
(In reply to Dustin J. Mitchell [:dustin] pronoun: he from comment #1)
The code for this is in services/notify in https://github.com/taskcluster/taskcluster. You can see that there's a "blacklist" in config.yml in that application already. A few of the pieces of completing this project:
- create an Azure table (or database table) to contain blacklisted notification destinations [1]
- make API methods to modify that table (list, get, add, update, delete)
- make UI changes that use those API methods to manage the data
- make the notification service read from the table to determine if a destination is blacklisted, before sending the notification
[1] Let's not limit this to emails -- any kind of notification should be possible to blacklist
Hey, so will the UI changes be in taskcluster-web?
Reporter | ||
Comment 14•7 years ago
|
||
Indeed they will!
Assignee | ||
Comment 15•7 years ago
|
||
And any pointers on how i should go about doing that?
Will we create a new page in the side bar for it?
Reporter | ||
Comment 16•7 years ago
|
||
I think so. Hassan will be back on Monday to offer more guidance. Maybe you could make a quick sketch of what you think it might look like, for him to evaluate?
Assignee | ||
Comment 17•7 years ago
|
||
Right, almost forgot the weekend had started haha. I'll get to work then!
Assignee | ||
Comment 18•7 years ago
|
||
Alright, so I didn't get much time over the weekend as I was busy traveling but I started looking into this today. I believe we will need to write a graphql query in the web-server as well?
Also, for the blacklist, if we add a sidebar item maybe that would be a bit out of place, because as I see it, the blacklist would be used by a select few people and won't be relevant to everybody. Maybe we can make a SideBarGroup named settings and add the blacklist there or maybe we can add it somewhere else. I would love your thoughts on it, Dustin and Hassan
Updated•7 years ago
|
Assignee | ||
Comment 19•7 years ago
|
||
Okay so Brian helped me shift the addresses from current config file to the denylist. I have also added the queries to the web-server whose PR can be found below. I believe now the only work left is to implement the UI. I am not sure where to add the blacklist in the UI as I mentioned in comment 18. Hassan can you help me a bit here :)
Comment 20•7 years ago
|
||
Awesome work on the web-server! Regarding the UI, feel free to create a new view "Blacklist" under the "Authorization" section. I created https://github.com/taskcluster/taskcluster/issues/282. Let's continue the discussion there :)
Comment 21•6 years ago
|
||
https://taskcluster-web.netlify.com/notify/denylist
Now that I think about it, is this view OK to display for everyone? I'm not sure these email addresses should be available for everyone to see.
Reporter | ||
Comment 22•6 years ago
|
||
It's a good question. I think it's OK because people will wonder if their messages are being blocked by the denylist, and in general the notifications are from tasks and other public things. But I have my doubts, too.
We could also add protections to the API method and only list denylist items that the user has permission to manage. We used to do that with secrets, and it made the UI a bit confusing (it was hard to check that a secret name was correct, for example). But that's a different situation since secret names are not PII.
Let's play it safe and open a new bug to add protections to the list
endpoint such that it only returns permitted entries, and adjust the UI to make it clear that things might be omitted.
Comment 23•6 years ago
|
||
Created https://bugzilla.mozilla.org/show_bug.cgi?id=1542212. Ojaswin, let me know if you want me to assign it to you if you're interested in continuing your work on that :)
Assignee | ||
Comment 24•6 years ago
|
||
I would love to! Will comment on the bug
Updated•6 years ago
|
Description
•