Re: [PATCH] Exclude suspended Users from being notified
Alright, that's the final patch revision. This change ultimately just removes suspended users from the sql results in `notify.py`, which excludes them from all email notifications. On Fri, Jul 3, 2020 at 6:29 PM Kevin Morris wrote: > The existing notify.py script was grabbing entries regardless > of user suspension. This has been modified to only send notifications > to unsuspended users. > > This change was written as a solution to > https://bugs.archlinux.org/task/65554. > > Signed-off-by: Kevin Morris > --- > aurweb/scripts/notify.py | 31 --- > 1 file changed, 20 insertions(+), 11 deletions(-) > > diff --git a/aurweb/scripts/notify.py b/aurweb/scripts/notify.py > index 5b18a476..223ed61f 100755 > --- a/aurweb/scripts/notify.py > +++ b/aurweb/scripts/notify.py > @@ -124,7 +124,7 @@ class ResetKeyNotification(Notification): > def __init__(self, conn, uid): > cur = conn.execute('SELECT UserName, Email, BackupEmail, ' + > 'LangPreference, ResetKey ' + > - 'FROM Users WHERE ID = ?', [uid]) > + 'FROM Users WHERE ID = ? AND Suspended = 0', > [uid]) > self._username, self._to, self._backup, self._lang, > self._resetkey = cur.fetchone() > super().__init__() > > @@ -171,7 +171,8 @@ class CommentNotification(Notification): > 'ON PackageNotifications.UserID = Users.ID > WHERE ' + > 'Users.CommentNotify = 1 AND ' + > 'PackageNotifications.UserID != ? AND ' + > - 'PackageNotifications.PackageBaseID = ?', > + 'PackageNotifications.PackageBaseID = ? AND ' + > + 'Users.Suspended = 0' +, > [uid, pkgbase_id]) > self._recipients = cur.fetchall() > cur = conn.execute('SELECT Comments FROM PackageComments WHERE ID > = ?', > @@ -218,7 +219,8 @@ class UpdateNotification(Notification): > 'ON PackageNotifications.UserID = Users.ID > WHERE ' + > 'Users.UpdateNotify = 1 AND ' + > 'PackageNotifications.UserID != ? AND ' + > - 'PackageNotifications.PackageBaseID = ?', > + 'PackageNotifications.PackageBaseID = ? AND ' + > + 'Users.Suspended = 0', > [uid, pkgbase_id]) > self._recipients = cur.fetchall() > super().__init__() > @@ -264,7 +266,8 @@ class FlagNotification(Notification): > 'INNER JOIN PackageBases ' + > 'ON PackageBases.MaintainerUID = Users.ID OR ' > + > 'PackageBases.ID = > PackageComaintainers.PackageBaseID ' + > - 'WHERE PackageBases.ID = ?', [pkgbase_id]) > + 'WHERE PackageBases.ID = ? AND ' + > + 'Users.Suspended = 0', [pkgbase_id]) > self._recipients = cur.fetchall() > cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE > ' + > 'ID = ?', [pkgbase_id]) > @@ -302,7 +305,8 @@ class OwnershipEventNotification(Notification): > 'ON PackageNotifications.UserID = Users.ID > WHERE ' + > 'Users.OwnershipNotify = 1 AND ' + > 'PackageNotifications.UserID != ? AND ' + > - 'PackageNotifications.PackageBaseID = ?', > + 'PackageNotifications.PackageBaseID = ? AND ' + > + 'Users.Suspended = 0', > [uid, pkgbase_id]) > self._recipients = cur.fetchall() > cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE > ' + > @@ -341,7 +345,7 @@ class ComaintainershipEventNotification(Notification): > def __init__(self, conn, uid, pkgbase_id): > self._pkgbase = pkgbase_from_id(conn, pkgbase_id) > cur = conn.execute('SELECT Email, LangPreference FROM Users ' + > - 'WHERE ID = ?', [uid]) > + 'WHERE ID = ? AND Suspended = 0', [uid]) > self._to, self._lang = cur.fetchone() > super().__init__() > > @@ -384,7 +388,8 @@ class DeleteNotification(Notification): > 'INNER JOIN PackageNotifications ' + > 'ON PackageNotifications.UserID = Users.ID > WHERE ' + > 'PackageNotifications.UserID != ? AND ' + > - 'PackageNotifications.PackageBaseID = ?', > + 'PackageNotifications.PackageBaseID = ? AND ' + > + 'Users.Suspended = 0', > [uid, old_pkgbase_id]) > self._recipients = cur.fetchall() >
[PATCH] Exclude suspended Users from being notified
The existing notify.py script was grabbing entries regardless of user suspension. This has been modified to only send notifications to unsuspended users. This change was written as a solution to https://bugs.archlinux.org/task/65554. Signed-off-by: Kevin Morris --- aurweb/scripts/notify.py | 31 --- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/aurweb/scripts/notify.py b/aurweb/scripts/notify.py index 5b18a476..223ed61f 100755 --- a/aurweb/scripts/notify.py +++ b/aurweb/scripts/notify.py @@ -124,7 +124,7 @@ class ResetKeyNotification(Notification): def __init__(self, conn, uid): cur = conn.execute('SELECT UserName, Email, BackupEmail, ' + 'LangPreference, ResetKey ' + - 'FROM Users WHERE ID = ?', [uid]) + 'FROM Users WHERE ID = ? AND Suspended = 0', [uid]) self._username, self._to, self._backup, self._lang, self._resetkey = cur.fetchone() super().__init__() @@ -171,7 +171,8 @@ class CommentNotification(Notification): 'ON PackageNotifications.UserID = Users.ID WHERE ' + 'Users.CommentNotify = 1 AND ' + 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', + 'PackageNotifications.PackageBaseID = ? AND ' + + 'Users.Suspended = 0' +, [uid, pkgbase_id]) self._recipients = cur.fetchall() cur = conn.execute('SELECT Comments FROM PackageComments WHERE ID = ?', @@ -218,7 +219,8 @@ class UpdateNotification(Notification): 'ON PackageNotifications.UserID = Users.ID WHERE ' + 'Users.UpdateNotify = 1 AND ' + 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', + 'PackageNotifications.PackageBaseID = ? AND ' + + 'Users.Suspended = 0', [uid, pkgbase_id]) self._recipients = cur.fetchall() super().__init__() @@ -264,7 +266,8 @@ class FlagNotification(Notification): 'INNER JOIN PackageBases ' + 'ON PackageBases.MaintainerUID = Users.ID OR ' + 'PackageBases.ID = PackageComaintainers.PackageBaseID ' + - 'WHERE PackageBases.ID = ?', [pkgbase_id]) + 'WHERE PackageBases.ID = ? AND ' + + 'Users.Suspended = 0', [pkgbase_id]) self._recipients = cur.fetchall() cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE ' + 'ID = ?', [pkgbase_id]) @@ -302,7 +305,8 @@ class OwnershipEventNotification(Notification): 'ON PackageNotifications.UserID = Users.ID WHERE ' + 'Users.OwnershipNotify = 1 AND ' + 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', + 'PackageNotifications.PackageBaseID = ? AND ' + + 'Users.Suspended = 0', [uid, pkgbase_id]) self._recipients = cur.fetchall() cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE ' + @@ -341,7 +345,7 @@ class ComaintainershipEventNotification(Notification): def __init__(self, conn, uid, pkgbase_id): self._pkgbase = pkgbase_from_id(conn, pkgbase_id) cur = conn.execute('SELECT Email, LangPreference FROM Users ' + - 'WHERE ID = ?', [uid]) + 'WHERE ID = ? AND Suspended = 0', [uid]) self._to, self._lang = cur.fetchone() super().__init__() @@ -384,7 +388,8 @@ class DeleteNotification(Notification): 'INNER JOIN PackageNotifications ' + 'ON PackageNotifications.UserID = Users.ID WHERE ' + 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', + 'PackageNotifications.PackageBaseID = ? AND ' + + 'Users.Suspended = 0', [uid, old_pkgbase_id]) self._recipients = cur.fetchall() super().__init__() @@ -431,7 +436,8 @@ class RequestOpenNotification(Notification): 'INNER JOIN Users ' + 'ON Users.ID = PackageRequests.UsersID ' + 'OR Users.ID = PackageBases.MaintainerUID ' + - 'WHERE PackageRequests.ID = ?', [reqid]) + 'WHERE PackageRequests.ID = ?
Re: [PATCH] Remove PackageNotifications when User is suspended
Updated patch inc which only modifies `scripts/notify.py` and preserves notification records. On Fri, Jul 3, 2020 at 12:02 PM Kevin Morris wrote: > This path will only trigger when suspending a user through an > account page; if the database is managed manually or through > another script, PackageNotifications will also need manual > modifications if intended. > > This change was written as a solution to > https://bugs.archlinux.org/task/65554. > > Signed-off-by: Kevin Morris > --- > web/lib/acctfuncs.inc.php | 4 > 1 file changed, 4 insertions(+) > > diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php > index d238c0e0..fb7cca8c 100644 > --- a/web/lib/acctfuncs.inc.php > +++ b/web/lib/acctfuncs.inc.php > @@ -403,6 +403,10 @@ function > process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$BE="",$H="",$P=" > $q.= " WHERE ID = ".intval($UID); > $result = $dbh->exec($q); > > + // Clean up PackageNotifications for $UID as well. > + $q = "DELETE FROM PackageNotifications WHERE UserID = > ".intval($UID); > + $result = $dbh->exec($q); > + > if (isset($ssh_keys) && count($ssh_keys) > 0) { > $ssh_key_result = account_set_ssh_keys($UID, > $ssh_keys, $ssh_fingerprints); > } else { > -- > 2.20.1 > > -- Kevin Morris Software Developer Personal Inquiries: kevr.gt...@gmail.com Personal Phone: (415) 583-9687 Technologies: C, C++, Python, Django, Ruby, Rails, ReactJS, jQuery, Javascript, SQL, Redux
[PATCH] Exclude suspended Users from being notified
The existing notify.py script was grabbing entries regardless of user suspension. This has been modified to only send notifications to unsuspended users, except for a Trusted User Vote Notification. This change was written as a solution to https://bugs.archlinux.org/task/65554. Signed-off-by: Kevin Morris --- aurweb/scripts/notify.py | 22 +++--- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/aurweb/scripts/notify.py b/aurweb/scripts/notify.py index 5b18a476..94ca1936 100755 --- a/aurweb/scripts/notify.py +++ b/aurweb/scripts/notify.py @@ -170,6 +170,7 @@ class CommentNotification(Notification): 'FROM Users INNER JOIN PackageNotifications ' + 'ON PackageNotifications.UserID = Users.ID WHERE ' + 'Users.CommentNotify = 1 AND ' + + 'Users.Suspended = 0 AND ' + 'PackageNotifications.UserID != ? AND ' + 'PackageNotifications.PackageBaseID = ?', [uid, pkgbase_id]) @@ -217,6 +218,7 @@ class UpdateNotification(Notification): 'INNER JOIN PackageNotifications ' + 'ON PackageNotifications.UserID = Users.ID WHERE ' + 'Users.UpdateNotify = 1 AND ' + + 'Users.Suspended = 0 AND ' + 'PackageNotifications.UserID != ? AND ' + 'PackageNotifications.PackageBaseID = ?', [uid, pkgbase_id]) @@ -264,7 +266,8 @@ class FlagNotification(Notification): 'INNER JOIN PackageBases ' + 'ON PackageBases.MaintainerUID = Users.ID OR ' + 'PackageBases.ID = PackageComaintainers.PackageBaseID ' + - 'WHERE PackageBases.ID = ?', [pkgbase_id]) + 'WHERE PackageBases.ID = ? AND ' + + 'Users.Suspended = 0', [pkgbase_id]) self._recipients = cur.fetchall() cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE ' + 'ID = ?', [pkgbase_id]) @@ -302,7 +305,8 @@ class OwnershipEventNotification(Notification): 'ON PackageNotifications.UserID = Users.ID WHERE ' + 'Users.OwnershipNotify = 1 AND ' + 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', + 'PackageNotifications.PackageBaseID = ? AND ' + + 'Users.Suspended = 0', [uid, pkgbase_id]) self._recipients = cur.fetchall() cur = conn.execute('SELECT FlaggerComment FROM PackageBases WHERE ' + @@ -341,7 +345,7 @@ class ComaintainershipEventNotification(Notification): def __init__(self, conn, uid, pkgbase_id): self._pkgbase = pkgbase_from_id(conn, pkgbase_id) cur = conn.execute('SELECT Email, LangPreference FROM Users ' + - 'WHERE ID = ?', [uid]) + 'WHERE ID = ? AND Suspended = 0', [uid]) self._to, self._lang = cur.fetchone() super().__init__() @@ -384,7 +388,8 @@ class DeleteNotification(Notification): 'INNER JOIN PackageNotifications ' + 'ON PackageNotifications.UserID = Users.ID WHERE ' + 'PackageNotifications.UserID != ? AND ' + - 'PackageNotifications.PackageBaseID = ?', + 'PackageNotifications.PackageBaseID = ? AND ' + + 'Users.Suspended = 0', [uid, old_pkgbase_id]) self._recipients = cur.fetchall() super().__init__() @@ -431,7 +436,8 @@ class RequestOpenNotification(Notification): 'INNER JOIN Users ' + 'ON Users.ID = PackageRequests.UsersID ' + 'OR Users.ID = PackageBases.MaintainerUID ' + - 'WHERE PackageRequests.ID = ?', [reqid]) + 'WHERE PackageRequests.ID = ? AND ' + + 'Users.Suspended = 0', [reqid]) self._to = aurweb.config.get('options', 'aur_request_ml') self._cc = [row[0] for row in cur.fetchall()] cur = conn.execute('SELECT Comments FROM PackageRequests WHERE ID = ?', @@ -485,7 +491,8 @@ class RequestCloseNotification(Notification): 'INNER JOIN Users ' + 'ON Users.ID = PackageRequests.UsersID ' + 'OR Users.ID = PackageBases.MaintainerUID ' + - 'WHERE PackageRequests.ID = ?', [reqid]) + 'WHERE
[PATCH] Remove PackageNotifications when User is suspended
This path will only trigger when suspending a user through an account page; if the database is managed manually or through another script, PackageNotifications will also need manual modifications if intended. This change was written as a solution to https://bugs.archlinux.org/task/65554. Signed-off-by: Kevin Morris --- web/lib/acctfuncs.inc.php | 4 1 file changed, 4 insertions(+) diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index d238c0e0..fb7cca8c 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -403,6 +403,10 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$BE="",$H="",$P=" $q.= " WHERE ID = ".intval($UID); $result = $dbh->exec($q); + // Clean up PackageNotifications for $UID as well. + $q = "DELETE FROM PackageNotifications WHERE UserID = ".intval($UID); + $result = $dbh->exec($q); + if (isset($ssh_keys) && count($ssh_keys) > 0) { $ssh_key_result = account_set_ssh_keys($UID, $ssh_keys, $ssh_fingerprints); } else { -- 2.20.1
Re: [PATCH] Add POST support for RPC API
Apologies, `application/data` in the commit message's example should be `application/json`, and will need to be updated after review(s) in the final commit. On Fri, Jul 3, 2020 at 10:53 AM Kevin Morris wrote: > When we received a POST method from a client, deduce our `$data` > by determining which `Content-Type` is used. > > Supported `Content-Type`s > = > > * `application/json` > * `multipart/form-data` > > `application/json` POST Example, searching for 'test': > ``` > curl -X POST -H 'Content-Type: application/data' \ > --data '{"v": "5", "type": "search", "arg": "test"}' \ > https://aur.archlinux.org/rpc/ > ``` > > `multipart/form-data` POST Example, search for 'test': > ``` > curl -X POST -H 'Content-Type: multipart/form-data' \ > -F v=5 -F type=search -F arg=test \ > https://aur.archlinux.org/rpc/ > ``` > > This change was written as a solution to > https://bugs.archlinux.org/task/49089. > > NOTE: This commit is not final; would like a review and a bit more > consideration on `multipart/form-data` and ensuring that we're > handling everything we need to. > > Signed-off-by: Kevin Morris > --- > web/html/rpc.php | 37 ++--- > 1 file changed, 34 insertions(+), 3 deletions(-) > > diff --git a/web/html/rpc.php b/web/html/rpc.php > index 64c95622..41762aa3 100644 > --- a/web/html/rpc.php > +++ b/web/html/rpc.php > @@ -2,16 +2,47 @@ > set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); > include_once("aurjson.class.php"); > > -if ( $_SERVER['REQUEST_METHOD'] != 'GET' ) { > +$exposed_methods = array('GET', 'POST'); > +$request_method = strtoupper($_SERVER['REQUEST_METHOD']); > + > +if ( !in_array($request_method, $exposed_methods) ) { > header('HTTP/1.1 405 Method Not Allowed'); > exit(); > } > > -if ( isset($_GET['type']) ) { > +if ( $request_method === 'GET' ) { > + $data = $_GET; > +} else { > + // Otherwise, we were given a POST method, and we'll do some more > + // work to deduce our data input. > + > + // Extract Content-Type; remove any trailing arguments from the > string. > + $content_type = $_SERVER['CONTENT_TYPE']; > + if ( strpos($content_type, ';') ) { > + // Example: `multipart/form-data; boundary blahblah` is > extracted as > + // `multipart/form-data`. > + $content_type = explode(';', $content_type)[0]; > + } > + $content_type = rtrim(trim($content_type)); > + > + if ($content_type === 'application/json') { > + $json = file_get_contents('php://input'); > + $data = json_decode($json, true); > + } elseif ($content_type === 'multipart/form-data') { > + $data = $_POST; > + } else { > + header('HTTP/1.1 400 Bad Request'); > + echo "Error: Unsupported Content-Type header.\n"; > + exit(); > + } > +} > + > +if ( isset($data['type']) ) { > $rpc_o = new AurJSON(); > - echo $rpc_o->handle($_GET); > + echo $rpc_o->handle($data); > } > else { > echo file_get_contents('../../doc/rpc.html'); > } > + > ?> > -- > 2.20.1 > > -- Kevin Morris Software Developer Personal Inquiries: kevr.gt...@gmail.com Personal Phone: (415) 583-9687 Technologies: C, C++, Python, Django, Ruby, Rails, ReactJS, jQuery, Javascript, SQL, Redux
[PATCH] Add POST support for RPC API
When we received a POST method from a client, deduce our `$data` by determining which `Content-Type` is used. Supported `Content-Type`s = * `application/json` * `multipart/form-data` `application/json` POST Example, searching for 'test': ``` curl -X POST -H 'Content-Type: application/data' \ --data '{"v": "5", "type": "search", "arg": "test"}' \ https://aur.archlinux.org/rpc/ ``` `multipart/form-data` POST Example, search for 'test': ``` curl -X POST -H 'Content-Type: multipart/form-data' \ -F v=5 -F type=search -F arg=test \ https://aur.archlinux.org/rpc/ ``` This change was written as a solution to https://bugs.archlinux.org/task/49089. NOTE: This commit is not final; would like a review and a bit more consideration on `multipart/form-data` and ensuring that we're handling everything we need to. Signed-off-by: Kevin Morris --- web/html/rpc.php | 37 ++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/web/html/rpc.php b/web/html/rpc.php index 64c95622..41762aa3 100644 --- a/web/html/rpc.php +++ b/web/html/rpc.php @@ -2,16 +2,47 @@ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); include_once("aurjson.class.php"); -if ( $_SERVER['REQUEST_METHOD'] != 'GET' ) { +$exposed_methods = array('GET', 'POST'); +$request_method = strtoupper($_SERVER['REQUEST_METHOD']); + +if ( !in_array($request_method, $exposed_methods) ) { header('HTTP/1.1 405 Method Not Allowed'); exit(); } -if ( isset($_GET['type']) ) { +if ( $request_method === 'GET' ) { + $data = $_GET; +} else { + // Otherwise, we were given a POST method, and we'll do some more + // work to deduce our data input. + + // Extract Content-Type; remove any trailing arguments from the string. + $content_type = $_SERVER['CONTENT_TYPE']; + if ( strpos($content_type, ';') ) { + // Example: `multipart/form-data; boundary blahblah` is extracted as + // `multipart/form-data`. + $content_type = explode(';', $content_type)[0]; + } + $content_type = rtrim(trim($content_type)); + + if ($content_type === 'application/json') { + $json = file_get_contents('php://input'); + $data = json_decode($json, true); + } elseif ($content_type === 'multipart/form-data') { + $data = $_POST; + } else { + header('HTTP/1.1 400 Bad Request'); + echo "Error: Unsupported Content-Type header.\n"; + exit(); + } +} + +if ( isset($data['type']) ) { $rpc_o = new AurJSON(); - echo $rpc_o->handle($_GET); + echo $rpc_o->handle($data); } else { echo file_get_contents('../../doc/rpc.html'); } + ?> -- 2.20.1