1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-04 20:52:43 +01:00
Commit graph

797 commits

Author SHA1 Message Date
epriestley
7593a265d5 When Herald changes object subscribers, always hide the feed story
Summary:
Fixes T8952. These feed stories are not interesting and tend to be generated as collateral damage when a non-story update is made to an old task and someone has a "subscribe me" Herald rule.

Also clean up some of the Herald field/condition indexing behavior slightly.

Test Plan: Wrote a "Subscribe X" herald rule, made a trivial update to a task. Before: low-value feed story; after: no feed story.

Maniphest Tasks: T8952

Differential Revision: https://secure.phabricator.com/D20797
2019-09-09 13:17:36 -07:00
epriestley
0943561dcb Fix incorrect construction of subtype map when validating "subtype" transactions against non-subtypable objects
Summary:
Fixes T13389. Currently, we try to "newSubtypeMap()" unconditionally, even if the underlying object does not support subtypes.

  - Only try to build a subtype map if subtype transactions are actually being applied.
  - When subtype transactions are applied to a non-subtypable object, fail more explicitly.

Test Plan: Clicked "Make Editable" in a fresh Calendar transaction form, got an editable form instead of a fatal from "newSubtypeMap()". (Calendar events are not currently subtypable.)

Maniphest Tasks: T13389

Differential Revision: https://secure.phabricator.com/D20741
2019-08-28 06:57:04 -07:00
epriestley
a0a3879712 In Phortune, send order email to account external addresses
Summary: Depends on D20738. Ref T13366. Fixes T8389. Now that the infrastructure is in place, actually send email to external addresses.

Test Plan: Used `bin/phortune invoice` to generate invoices and saw associated external accounts receive mail in `bin/mail list-outbound`.

Maniphest Tasks: T13366, T8389

Differential Revision: https://secure.phabricator.com/D20739
2019-08-26 07:48:27 -07:00
epriestley
8e263a2f64 Support "date" custom fields in "*.edit" endpoints
Summary: Fixes T13355. This didn't appear to be a ton of extra work, we just didn't get it for free in the original implementation in D14635.

Test Plan:
  - Saw "date" custom fields appear in Conduit API documentation for "maniphest.edit".
  - Set custom "date" field to null and non-null values via the API.

{F6666582}

Maniphest Tasks: T13355

Differential Revision: https://secure.phabricator.com/D20690
2019-07-31 13:10:14 -07:00
Arturas Moskvinas
cd44925425 Allow users with no CAN_EDIT permissions to silence projects if they want to
Summary: Humble user cannot silence/mute project if he/she has no CAN_EDIT permissions in it. You can actually leave it but if project is locked - then you're scr*wed.

Test Plan:
1. On a testing phabricator instance created a dummy project
2. Changed that project permissions CAN_EDIT to be by admin only
3. Added poor soul with no CAN_EDIT permissions
4. Logged it in with poor soul
5. Tried to silence the project
6. The Project is successfully silenced
7. User is happy :)

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin, Pawka

Differential Revision: https://secure.phabricator.com/D20675
2019-07-23 13:13:54 +03:00
epriestley
41ea204144 Update one straggling "CAN_INTERACT" check in comment removal
Summary: See rPaacc62463d61. D20551 added some `CAN_INTERACT` checks, but `CAN_INTERACT` needs to be checked with `canInteract()` to fall back to `CAN_VIEW` properly. D20558 cleaned up most of this but missed one callsite; fix that up too.

Test Plan: Removed a comment on a commit.

Reviewers: amckinley, 20after4

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20648
2019-07-11 16:09:52 -07:00
epriestley
159fd44203 Correct transaction strengths after inconsitent scaling by 100 vs 1000
Summary:
See D20540. I mistakenly multiplied some strenghts by 100 and others by 1000 when converting them to integers for `PhutilSortVector`.

Multiply them all by 100 (that is, divide the ones which were multiplied by 1000 by 10) to put things back the way they were.

Test Plan: quick mafs

Reviewers: amckinley, richardvanvelzen

Reviewed By: richardvanvelzen

Differential Revision: https://secure.phabricator.com/D20622
2019-06-26 07:19:33 -07:00
Austin McKinley
6b9f4a918b Modularize PhabricatorEditEngineConfigurationTransaction
Summary: Ref T13319. Ref PHI1302. Migrate `PhabricatorEditEngineConfigurationTransaction` to modular transactions and add some additional transaction rendering to make these edits less opaque.

Test Plan: Hit all the form edit controllers, viewed resulting transaction timeline.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T13319

Differential Revision: https://secure.phabricator.com/D20595
2019-06-20 16:25:21 -07:00
epriestley
37e26f1b45 Improve rendering of "default value changed" custom form transactions to at least have all the information
Summary:
Ref T13319. Currently, transactions about changes to a default form value use a raw internal key for the affected field and don't show the actual value change.

An ideal implementation will likely require us to specialize a great deal of rendering, but we can do much better than we currently do without too much work:

  - Try to pull the actual `EditField` object for the key so we can `getLabel()` it and get a human-readable label (like `Visible To` instead of `policy.view`).
  - Add a "(Show Changes)" action that dumps the raw values as more-or-less JSON, so you can at least figure out what happened if you're sophisticated enough.

Test Plan:
Before:

{F6516640}

After:

{F6516642}

The quality of "Show Details" varies a lot. For some fields, like "Description", it's pretty good:

{F6516645}

For others, like "Assigned To", it's better than nothing but pretty technical:

{F6516647}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13319

Differential Revision: https://secure.phabricator.com/D20594
2019-06-19 13:47:07 -07:00
epriestley
7538286499 Fix missing link targets for "View Object" header buttons in HTML email
Summary:
See <https://discourse.phabricator-community.org/t/view-task-from-maniphest-e-mail-doesnt-have-url/2827>.

I added "View Task" / "View Commit" buttons recently but the logic for generating URIs isn't quite right. Fix it up.

Test Plan:
  - Commented on a task.
  - Used `bin/mail show-outbound --id ... --dump-html > out.html` to dump the HTML.
  - Previewed the HTML in a browser.
  - This time, actually clicked the button to go to the task.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20586
2019-06-18 13:20:56 -07:00
epriestley
874282db75 Correct "msort()" vs "msortv()" to more fully stabilize transaction sorts after recent changes
Summary: Ref T13303. I upgraded this to a vector-based sort but forgot to type a "v", which means the sort has different stability under PHP 5.5. See D20582 for a root cause fix.

Test Plan: Locally, on PHP7, not much changes. I expect this to fix the odd selection of title stories in mail and notification stories on `secure`, which is running PHP 5.5.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13303

Differential Revision: https://secure.phabricator.com/D20583
2019-06-17 13:07:38 -07:00
epriestley
81134d7e7d After reloading transactions for the recipient while building transaction mail, put them in the input order
Summary:
Ref T13303. In D20525 I fixed an issue where transaction rendering could use cached values with the wrong viewer by reloading transactions.

However, reloading transactions may also reorder them as a side effect, since `withPHIDs(...)` does not imply an order. This can make transaction rendering order in mail wrong/inconsistent.

Instead, reorder the transactions before continuing so mail transaction order is consistent.

Test Plan: Applied a group of transactions to a task, saw a more consistent rendering order in mail after the change.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13303

Differential Revision: https://secure.phabricator.com/D20563
2019-05-30 17:14:54 -07:00
epriestley
9a32a563f0 Add a "View Task" button to HTML mail from Maniphest
Summary:
See downstream <https://phabricator.wikimedia.org/T1050>. Some time ago, we added a "View Revision" button to Differential mail. This hasn't created any problems and generally seems good / desirable.

It isn't trivial to just add everywhere since we need a translation string in each case, but at least add it to Maniphest for now. Going forward, we can fill in more applications as they come up.

Test Plan:
Used `bin/mail show-outbound --id <x> --dump-html`:

{F6470461}

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20561
2019-05-30 15:24:22 -07:00
epriestley
fb5dec4c03 Require valid comments to contain at least one non-whitespace character
Summary:
See downstream <https://phabricator.wikimedia.org/T88655>. This is very marginal, but we currently allow comments consisting of //only// whitespace.

These are probably always mistakes, so treat them like completely empty comments.

(We intentionally do not trim leading or trailing whitespace from comments when posting them becuase leading spaces can be used to trigger codeblock formatting.)

Test Plan:
  - Posted empty, nonempty, and whitespace-only comments.
  - Whitespace-only comments now have the same behavior as truly empty comments (e.g., do not actually generate a transaction).

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20562
2019-05-30 15:15:24 -07:00
epriestley
53b9acfb7d Test for "CAN_INTERACT" on comment edits in a way that survives objects which only implement "CAN_VIEW"
Summary:
Ref T13289. See D20551. In D20551, I implemented some "CAN_INTERACT" checks against certain edits, but these checks end up testing "CAN_INTERACT" against objects like Conpherence threads which do not support a distinct "CAN_INTERACT" permission. I misrembered how the "CAN_INTERACT" fallback to "CAN_VIEW" actually works: it's not fully automatic, and needs some explicit "interact, or view if interact is not available" checks.

Use the "interact" wrappers to test these policies so they fall back to "CAN_VIEW" if an object does not support "CAN_INTERACT". Generally, objects which have a "locked" state have a separate "CAN_INTERACT" permission; objects which don't have a "locked" state do not.

Test Plan: Created and edited comments in Conpherence (or most applications other than Maniphest).

Reviewers: amckinley

Maniphest Tasks: T13289

Differential Revision: https://secure.phabricator.com/D20558
2019-05-28 10:14:43 -07:00
epriestley
ce6fc5be90 Fix a looping workflow when trying to submit a partially-effectless transaction group
Summary:
Ref T13289. If you do this:

  - Subscribe to a task (so we don't generate a subscribe side-effect later).
  - Prepare a transaction group: sign with MFA, change projects (don't make any changes), add a comment.
  - Submit the transaction group.

...you'll get prompted "Some actions don't have any effect (the non-change to projects), apply remaining effects?".

If you confirm, you get MFA'd, but the MFA flow loses the "continue" confirmation, so you get trapped in a workflow loop of confirming and MFA'ing.

Instead, retain the "continue" bit through the MFA.

Also, don't show "You can't sign an empty transaction group" if there's a comment.

See also T13295, since the amount of magic here can probably be reduced. There's likely little reason for "continue" or "hisec" to be magic nowadays.

Test Plan:
  - Went through the workflow above.
  - Before: looping workflow.
  - After: "Continue" carries through the MFA gate.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13289

Differential Revision: https://secure.phabricator.com/D20552
2019-05-23 19:16:17 -07:00
epriestley
aacc62463d Prevent editing and deleting comments in locked conversations
Summary:
Ref T13289. This tightens up a couple of corner cases around locked threads.

Locking is primarily motivated by two use cases: stopping nonproductive conversations on open source installs (similar to GitHub's feature); and freezing object state for audit/record-keeping purposes.

Currently, you can edit or remove comments on a locked thread, but neither use case is well-served by allowing this. Require "CAN_INTERACT" to edit or remove a comment.

Administrators can still remove comments from a locked thread to serve "lock a flamewar, then clean it up", since "Remove Comment" on a comment you don't own is fairly unambiguously an administrative action.

Test Plan:
  - On a locked task, tried to edit and remove my comments as a non-administrator. Saw appropriate disabled UI state and error dialogs (actions were disallowed).
  - On a locked task, tried to remove another user's comments as an administrator. This works.
  - On a normal task, edited comments normally.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13289

Differential Revision: https://secure.phabricator.com/D20551
2019-05-23 19:04:55 -07:00
epriestley
31e623afcc Use the same transaction group ID for transactions applied indirectly by a sub-editor
Summary:
Ref T13283. Currently, each Editor sets its own group ID, so if you create a revision and then Herald does some stuff, the two groups of transactions get different group IDs.

This means the test console is slightly misleading (it will only pick up the Herald transactions). It's going to be misleading anyway (Herald obviously can't evaluate Herald transactions) but this is at least a little closer to reality and stops Herald actions from masking non-Herald actions.

Test Plan:
  - Created a revision. Herald applied one transaction.
  - Used the test console.
  - Before: The test console only picked up the single most recent Herald transaction.
  - After: The test console picked up the whole transaction group.

{F6464059}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13283

Differential Revision: https://secure.phabricator.com/D20546
2019-05-22 16:33:03 -07:00
epriestley
1eff4fdca3 Prevent "Differential Revision: ..." from counting as a mention in commit messages
Summary:
Ref T13290. Ref T13291. Now that a full URI is a "mention", the full URI in "Differential Revision: ..." also triggers a mention.

Stop it from doing that, since these mentions are silly/redundant/unintended.

The API here is also slightly odd; simplify it a little bit to get rid of doing "append" with "get + append + set".

Test Plan: Used `bin/repository reparse --publish` to republish commits with "Differential Revision: ..." and verified that the revision PHID was properly dropped from the mention list.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13291, T13290

Differential Revision: https://secure.phabricator.com/D20544
2019-05-22 16:22:01 -07:00
epriestley
fa4dcaa3aa Stabilize sorting of feed stories with similar strength
Summary:
See PHI1222. When we publish several transactions to feed at once, we sort them by "action strength" to figure out which one gets to be the title story.

This sort currently uses `msort()`, which uses `asort()`, which is not a stable sort and has inconsistent behavior across PHP versions:

{F6463721}

Switch to `msortv()`, which is a stable sort. Previously, see also T6861.

If all transactions have the same strength, we'll now consistently pick the first one.

This probably (?) does not impact anything in the upstream, but is good from a consistency point of view.

Test Plan:
Top story was published after this change and uses the chronologically first transaction as the title story.

Bottom story was published before this change and uses the chronologically second transaction as the title story.

Both stories have two transactions with the same strength ("create" + "add reviewer").

{F6463722}

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20540
2019-05-22 15:50:59 -07:00
epriestley
16537f7b32 Support filtering feed transactions by object type
Summary: Depends on D20533. Allow querying for transactions of a specific object type, so you can run queries like "Show all edits to Herald rules between date X and Y".

Test Plan: {F6463478}

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20534
2019-05-21 12:39:10 -07:00
epriestley
642113708a Build a rough transaction-level view of Feed
Summary:
Ref T13294. An install is interested in a way to easily answer audit-focused questions like "what edits were made to any Herald rule in Q1 2019?".

We can answer this kind of question with a more granular version of feed that focuses on being exhaustive rather than being human-readable.

This starts a rough version of it and deals with the two major tricky pieces: transactions are in a lot of different tables; and paging across them is not trivial.

To solve "lots of tables", we just query every table. There's a little bit of sleight-of-hand to get this working, but nothing too awful.

To solve "paging is hard", we order by "<dateCreated, phid>". The "phid" part of this order doesn't have much meaning, but it lets us put every transaction in a single, stable, global order and identify a place in that ordering given only one transaction PHID.

Test Plan: {F6463076}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13294

Differential Revision: https://secure.phabricator.com/D20531
2019-05-21 12:28:00 -07:00
epriestley
b8f6248e07 Fix an issue where handles could load with the incorrect viewer when building mail about changes to related objects
Summary:
See <https://phabricator.wikimedia.org/T179591>. Some time ago, all handle rendering preloaded handles: things emitted a list of PHIDs they'd need handles for, then later used only those PHIDs.

Later, we introduced `HandlePool` and lazy/on-demand handle loading. Modern transactions mostly use this to render object PHIDs.

When we build mail, many newer transactions use an on-demand load to fetch handles to render transactions. This on-demand load may use the original viewer (the acting user) instead of the correct viewer (the mail recipient): we fetch and reset handles using the correct viewer, but do not overwrite the active viewer for on-demand loading. This could cause mail to leak the titles of related objects to users who don't have permission to see them.

Instead, just reload the transactions with the correct viewer when building mail instead of playing a bunch of `setViewer()` and `clone` games. Until we're 100% on modular transactions, several pieces of the stack cache viewer or state information.

Test Plan:
  - Created task A (public) with subtask B (private).
  - Closed subtask B as a user with access to it.
  - Viewed mail sent to subscribers of task A who can not see subtask B.
    - Before change: mail discloses title of subtask B.
    - After change: mail properly labels subtask B as "Restricted Task".

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20525
2019-05-21 12:12:13 -07:00
epriestley
167f06d3eb Label transaction groups with a "group ID" so Herald can reconstruct them faithfully
Summary:
Ref T13283. See PHI1202. See D20519. When we apply a group of transactions, label all of them with the same "group ID".

This allows other things, notably Herald, to figure out which transactions applied together in a faithful way rather than by guessing, even though the guess was probably pretty good most of the time.

Also expose this to `transaction.search` in case callers want to do something similar. They get a list of transaction IDs from webhooks already anyway, but some callers use `transaction.search` outside of webhooks and this information may be useful.

Test Plan:
  - Ran Herald Test Console, saw faithful selection of recent transactions.
  - Changed hard limit from 1000 to 1, saw exception. Users should be very hard-pressed to hit this normally (they'd have to add 990-ish custom fields, then edit every field at once, I think) so I'm just fataling rather than processing some subset of the transaction set.
  - Called `transaction.search`, saw group ID information available.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13283

Differential Revision: https://secure.phabricator.com/D20524
2019-05-17 12:07:37 -07:00
epriestley
e059997e53 Expose subscribers transaction data via Conduit "transaction.search"
Summary:
Depends on D20507. See PHI1232. Previously, see T13255 and D20209.

Since nothing seems to have exploded after "projects" was exposed, give "subscribers" the same treatment.

Test Plan: Added, removed, and modified subscribers. Queried transactions with "transaction.search", saw sensible "type" and data.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20508
2019-05-16 12:19:45 -07:00
epriestley
104eefaa10 Hide the "added a commit/revision" stories from feed and mail
Summary:
Ref T13276. Previously, these edges were added directly with an `EdgeEditor`, so they did not generate transaction stories.

Now, they're added properly, but they aren't terribly useful in feed/mail. Hide them in those contexts, like we already do with other types of similar edges.

Test Plan: Will verify behavior on `secure`.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13276

Differential Revision: https://secure.phabricator.com/D20491
2019-05-14 09:39:26 -07:00
epriestley
3e0391c574 Don't mark subscribes/mentions as "Lock Overridden"
Summary:
See PHI1209. When a task is in "Hard Lock" mode, it's still possible to apply some changes to it. Notably:

  - You can subscribe/unsubscribe.
  - You can mention it on another object.
  - You can add a relationship from some other object to it (e.g., select it as a "Parent Task" for some other task).

Currently, these types of edits will show a "Lock Overridden" timeline emblem icon. However, they should not: you didn't override a lock to make these changes, they just bypass locks.

For now, special case these cases (self subscribe/unsubscribe + inverse edge edits) so they don't get the little icon, since I think this list is exhaustive today.

Some day we should modularize this, but we'd need code like this anyway (since TYPE_SUBSCRIBE is not modular yet), and this seems unlikely to cause problems even if it's a bit rough.

Test Plan:
  - Hard-locked a task.
    - Subscribed/unsubscribed, mentioned, relationship'd it as a non-author. No timeline emblems.
  - Soft-locked a task.
    - Subscribed/unsubscribed, mentioned, relationship'd it, no timeline emblems.
    - Clicked "Edit", answered "yes" to the override prompt, edited it. Got a timeline emblem.
  - Added some comments and stuff to a normal non-locked task, no emblems.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20513
2019-05-14 09:27:24 -07:00
epriestley
45f01dc716 Restore "Limit" to dashboard Query panels
Summary: See PHI1220. Ref T13272. I accidentally left the ability to set a query limit behind when updating this.

Test Plan: Edited a query panel, set/removed the limit, tried to set an invalid limit.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13272

Differential Revision: https://secure.phabricator.com/D20472
2019-05-01 08:41:43 -07:00
epriestley
0d9362355b In ApplicationTransactionEditor, determine new objects with "getID()" instead of "getPHID()"
Summary:
See <https://discourse.phabricator-community.org/t/unable-to-reload-object-that-hasnt-been-loaded/2677>.

When editing "Config" objects, they currently get a PHID set outside of the TransactionEditor. They probably should not, but fixing that is likely an involved change.

This causes us to incorrectly fail to detect `$is_new` correctly and try to `reload()` and object with no ID.

To work around this, test for new objects with `getID()` instead of `getPHID()`.

Test Plan: Edited any config value with the web UI.

Reviewers: amckinley

Differential Revision: https://secure.phabricator.com/D20482
2019-04-29 07:37:03 -07:00
epriestley
b3b1cc64bd When applying transactions, acquire a read lock sooner
Summary:
Depends on D20461. Ref T13276. Ref T13054.

Currently, we acquire the transaction read lock after populating "old values" in transactions and filtering transactions with no effect.

This isn't early enough to prevent all weird chaotic races: if two processes try to apply a "close revision" transaction at the same time, this can happen:

```
PROCESS A             PROCESS B
Old Value = Open      Old Value = Open
Transaction OK: Yes   Transaction OK: Yes
Acquire Read Lock     Acquire Read Lock
Got Read Lock!        Wait...
Apply Transactions    Wait...
New Value = Closed    Wait...
Release Lock          Wait...
                      Got Read Lock!
                      Apply Transactions
                      New Value = Closed
                      Release Lock
```

That's not great: both processes apply an "Open -> Closed" transaction since this was a valid transaction from the viewpoint of each process when it did the checks.

We actually want this:

```
PROCESS A             PROCESS B
Acquire Read Lock     Acquire Read Lock
Got Read Lock!        Wait...
Old Value = Open      Wait...
Transaction OK: Yes   Wait...
Apply Transactions    Wait...
New Value = Closed    Wait...
Release Lock          Wait...
                      Got Read Lock!
                      >>> Old Value = Closed
                      >>> Transaction Has No Effect!
                      >>> Do Nothing / Abort
                      Release Lock
```

Move the "lock" part up so we do that.

This may cause some kind of weird second-order effects, but T13054 went through pretty cleanly and we have to do this to get correct behavior, so we can survive those if/when they arise.

Test Plan:
  - Added a `sleep(10)` before the lock.
  - Ran `bin/repository message --reparse X` in two console windows, where X is a commit that closes revision Y and Y is open.
    - Before patch: both windows closed the revision and added duplicate transactions.
    - After patch: only one of the processes had an effect.

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: jmeador

Maniphest Tasks: T13276, T13054

Differential Revision: https://secure.phabricator.com/D20462
2019-04-24 05:57:29 -07:00
epriestley
a4a1143b18 Fix an issue where internal paging of notifications could fail if some notifications are not visible
Summary:
Ref T13266. See <https://discourse.phabricator-community.org/t/notification-page-throws-unrecoverable-fatal-error/2651/>.

The "notifications" query currently uses offset paging for no apparent reason (just a legacy issue?), so some of the paging code is only reachable internally.

  - Stop it from using offset paging, since modern cursor paging is fine here (and Feed has used cursor paging for a long time).
  - Fix the non-offset paging to work like Feed.

Also:

  - Remove a couple of stub methods with no callsites after cursor refactoring.

Test Plan:
  - Set things up so I had more than 100 notifications and some in the first 100 were policy filtered, to reproduce the issue (I just made `FeedStory` return `NO_ONE` as a visibility policy).
  - Applied the patch, notifications now page cleanly.
  - Verified that "Next Page" took me to the right place in the result list.

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: hskiba

Maniphest Tasks: T13266

Differential Revision: https://secure.phabricator.com/D20455
2019-04-23 11:45:04 -07:00
epriestley
02cfcfa079 Hide revision dependency stories from feed/notifications
Summary:
See PHI1134. Generally, "alice added a dependent revision: ..." isn't a very interesting story. This relationship itself is valuable, but the creation of the relationship is usually pretty obvious from context.

In the specific case of PHI1134, various scripts are racing one another, but I don't think this story is of much value in the general case anyway.

Test Plan: Edited parent/child revisions, no more feed stories.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20437
2019-04-17 17:08:14 -07:00
epriestley
1a52c8f713 Surface custom form instructions as a "Remarkup" field for the transaction layer
Summary: Ref T13263. See <https://discourse.phabricator-community.org/t/image-uploads-for-forms-too-restricted-by-default/2594>. Currently, when you add instructions to a custom form, we don't expose them as remarkup, so `{Fxxx}` references don't get attached correctly and won't get proper permissions.

Test Plan:
Dragged-and-dropped an image into form instructions, saw the file attach to the form:

{F6367710}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13263

Differential Revision: https://secure.phabricator.com/D20387
2019-04-10 11:13:03 -07:00
epriestley
c9d3fb2ac5 Fix the incorrect link target for "Create Revision" as a Menu Item
Summary:
Depends on D20359. Fixes T12098. When you add a new "Form" item and pick "Create Revision", you currently get a bad link. This is because Differential is kind of special and the form isn't usable directly, even though Differential does use EditEngine.

Allow EditEngine to specify a different create URI, then specify the web UI paste-a-diff flow to fix this.

Test Plan:
  - Added "Create Revision" to a portal, clicked it, was sensibly put on the diff flow.
  - Grepped for `getCreateURI()`, the only other real use case is to render the "Create X" dropdowns in the upper right.
    - Clicked one of those, still worked great.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T12098

Differential Revision: https://secure.phabricator.com/D20360
2019-04-02 15:21:59 -07:00
epriestley
15cc475cbd When a comment was signed with MFA, require MFA to edit it
Summary:
Ref PHI1173. Currently, you can edit an MFA'd comment without redoing MFA. This is inconsistent with the intent of the MFA badge, since it means an un-MFA'd comment may have an "MFA" badge on it.

Instead, implement these rules:

  - If a comment was signed with MFA, you MUST MFA to edit it.
  - When removing a comment, add an extra MFA prompt if the user has MFA. This one isn't strictly required, this action is just very hard to undo and seems reasonable to MFA.

Test Plan:
  - Made normal comments and MFA comments.
  - Edited normal comments and MFA comments (got prompted).
  - Removed normal comments and MFA comments (prompted in both cases).
  - Tried to edit an MFA comment without MFA on my account, got a hard "MFA absolutely required" failure.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20340
2019-03-28 15:55:14 -07:00
epriestley
b825570734 Fix transaction queries failing on "withIDs()" after clicking "Show Older"
Summary:
See <https://discourse.phabricator-community.org/t/unhandled-exception-on-show-older-changes/2545/>.

Before T13266, this query got away without having real paging because it used simple ID paging only and results are never actually hidden (today, you can always see all transactions on an object).

Provide `withIDs()` so the new, slightly stricter paging works.

Test Plan: On an object with "Show Older" in the transaction record, clicked the link. Before: exception in paging code (see Discourse link above). After: transactions loaded cleanly.

Reviewers: amckinley, avivey

Reviewed By: avivey

Differential Revision: https://secure.phabricator.com/D20317
2019-03-24 12:25:29 -07:00
epriestley
a6fd8f0479 When performing complex edits, pause sub-editors before they publish to propagate "Must Encrypt" and other state
Summary:
See PHI1134. Previously, see T13082 and D19969 for some sort-of-related stuff.

Currently, edits work roughly like this:

  - Suppose we're editing object X, and we're also going to edit some other object, Y, because X mentioned Y or the edit is making X a child or parent of Y, or unblocking Y.
  - Do the actual edit to X, including inverse edits ("alice mentioned Y on X.", "alice added a child revision: X", etc) which apply to Y.
  - Run Herald rules on X.
  - Publish the edit to X.

The "inverse edits" currently do this whole process inline, in a sub-editor. So the flow expands like this:

  - Begin editing X.
  - Update properties on X.
    - Begin inverse-edge editing Y.
    - Update properties on Y.
    - Run (actually, skip) Herald rules on Y.
    - Publish edits to Y.
  - Run Herald rules on X.
  - Publish edits to X.

Notably, the "Y" stuff publishes before the "X" Herald rules run. This creates potential problems:

  - Herald rules may change the name or visibility policy of "X", but we'll publish mail about it via the edits to Y before those edits apply. This is a problem only in theory, we don't ship any upstream rules like this today.
  - Herald rules may "Require Secure Mail", but we won't know that at the time we're building mail about the indirect change to "Y". This is a problem in practice.

Instead, switch to this new flow, where we stop the sub-editors before they publish, then publish everything at the very end once all the edits are complete:

  - Begin editing X.
  - Update properties on X.
    - Begin inverse-edge editing Y.
    - Update properties on Y.
    - Skip Herald on Y.
  - Run Herald rules on X.
  - Publish X.
    - Publish all child-editors of X.
      - Publish Y.

Test Plan:
  - Created "Must Encrypt" Herald rules for Tasks and Revisions.
  - Edited object "A", an object which the rules applied to directly, and set object "B" (a different object which the rules did not hit) as its parent/child and/or unblocked it.
  - In `bin/mail list-outbound`, saw:
    - Mail about object "A" all flagged as "Must Encrypt".
    - Normal mail from object B not flagged "Must Encrypt".
    - Mail from object B about changing relationships to object A flagged as "Must Encrypt".

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20283
2019-03-18 15:20:45 -07:00
epriestley
04f9e72cbd Don't subscribe bots implicitly when they act on objects, or when they are mentioned
Summary:
See PHI1098. When users comment on objects, they are automatically subscribed. And when `@alice` mentions `@bailey` on a task, that usually subscribes `@bailey`.

These rules make less sense if the user is a bot. There's generally no reason for a bot to automatically subscribe to objects it acts on (it's not going to read email and follow up later), and it can always subscribe itself pretty easily if it wants (since everything is `*.edit` now and supports subscribe transactions).

Also, don't subscribe bots when they're mentioned for similar reasons. If users really want to subscribe bots, they can do so explicitly.

These rules seem slightly like "bad implicit magic" since it's not immediately obvious why `@abc` subscribes that user but `@xyz` may not, but some of these rules are fairly complicated already (e.g., `@xyz` doesn't subscribe them if they unsubscribed or are implicitly subscribed) and this feels like it gets the right/desired result almost-always.

Test Plan:
On a fresh task:

  - Mentioned a bot in a comment with `@bot`.
    - Before patch: bot got CC'd.
    - After patch: no CC.
  - Called `maniphest.edit` via the API to add a comment as a bot.
    - Before patch: bot got CC'd.
    - After patch: no CC.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20284
2019-03-13 16:28:40 -07:00
epriestley
814e6d2de9 Add more type checking to transactions queued by Herald
Summary:
See PHI1096. Depends on D20213. An install is reporting a hard-to-reproduce issue where a non-transaction gets queued by Herald somehow. This might be in third-party code.

Sprinkle the relevant parts of the code with `final` and type checking to try to catch the problem before it causes a fatal we can't pull a stack trace out of.

Test Plan: Poked around locally (e.g., edited revisions to cause Herald to trigger), but hard to know if this will do what it's supposed to or not without deploying and seeing if it catches anything.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20214
2019-02-28 07:10:56 -08:00
epriestley
d1546209c5 Expand documentation for "transaction.search"
Summary: Depends on D20209. Ref T13255. It would probably be nice to make this into a "real" `*.search` API method some day, but at least document the features for now.

Test Plan: Read documentation.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13255

Differential Revision: https://secure.phabricator.com/D20211
2019-02-25 10:52:29 -08:00
epriestley
83aba7b01c Enrich the "change project tags" transaction in "transaction.search"
Summary:
Depends on D20208. Ref T13255. See that task for some long-winded discussion and rationale. Short version:

  - This is a list of operations instead of a list of old/new PHIDs because of scalability issues for large lists (T13056).
  - This is a fairly verbose list (instead of, for example, the more concise internal map we sometimes use with "+" and "-" as keys) to try to make the structure obvious and extensible in the future.
  - The "add" and "remove" echo the `*.edit` operations.

Test Plan: Called `transaction.search` on an object with project tag changes, saw them in the results.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13255

Differential Revision: https://secure.phabricator.com/D20209
2019-02-25 10:50:04 -08:00
epriestley
767afd1780 Support an "authorPHIDs" constraint for "transaction.search"
Summary: Ref T13255. The "transaction.search" API method currently does not support author constraints, but this is a reasonable thing to support.

Test Plan: Queried transactions by author, hit the error cases.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13255

Differential Revision: https://secure.phabricator.com/D20208
2019-02-25 06:33:04 -08:00
epriestley
e44b40ca4d Make "Subscribe/Unsubscribe" require only "CAN_VIEW", not "CAN_INTERACT"
Summary:
Ref T13249. See PHI1059. Currently, Subscribe/Unsubscribe require CAN_INTERACT via the web UI and no permissions (i.e., effectively CAN_VIEW) via the API.

Weaken the requirements from the web UI so that you do not need "CAN_INTERACT". This is a product change to the effect that it's okay to subscribe/unsubscribe from anything you can see, even hard-locked tasks. This generally seems reasonable.

Increase the requirements for the actual transaction, which mostly applies to API changes:

  - To remove subscribers other than yourself, require CAN_EDIT.
  - To add subscribers other than yourself, require CAN_EDIT or CAN_INTERACT. You may have CAN_EDIT but not CAN_INTERACT on "soft locked" tasks. It's okay to click "Edit" on these, click "Yes, override lock", then remove subscribers other than yourself.

This technically plugs some weird, mostly theoretical holes in the API where "attackers" could sometimes make more subscription changes than they should have been able to. Now that we send you email when you're unsubscribed this could only really be used to be mildly mischievous, but no harm in making the policy enforcement more correct.

Test Plan: Against normal, soft-locked, and hard-locked tasks: subscribed, unsubscribed, added and removed subscribers, overrode locks, edited via API. Everything worked like it should and I couldn't find any combination of lock state, policy state, and edit pathway that did anything suspicious.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13249

Differential Revision: https://secure.phabricator.com/D20174
2019-02-19 10:52:34 -08:00
epriestley
0b2d25778d Add basic, rough support for changing field behavior based on object subtype
Summary:
Ref T13248. This will probably need quite a bit of refinement, but we can reasonably allow subtype definitions to adjust custom field behavior.

Some places where we use fields are global, and always need to show all the fields. For example, on `/maniphest/`, where you can search across all tasks, you need to be able to search across all fields that are present on any task.

Likewise, if you "export" a bunch of tasks into a spreadsheet, we need to have columns for every field.

However, when you're clearly in the scope of a particular task (like viewing or editing `T123`), there's no reason we can't hide fields based on the task subtype.

To start with, allow subtypes to override "disabled" and "name" for custom fields.

Test Plan:
  - Defined several custom fields and several subtypes.
  - Disabled/renamed some fields for some subtypes.
  - Viewed/edited tasks of different subtypes, got desired field behavior.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13248

Differential Revision: https://secure.phabricator.com/D20161
2019-02-15 19:17:57 -08:00
epriestley
5892c78986 Replace all "setQueryParam()" calls with "remove/replaceQueryParam()"
Summary: Ref T13250. See D20149. Mostly: clarify semantics. Partly: remove magic "null" behavior.

Test Plan: Poked around, but mostly just inspection since these are pretty much one-for-one.

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: yelirekim

Maniphest Tasks: T13250

Differential Revision: https://secure.phabricator.com/D20154
2019-02-14 11:56:39 -08:00
epriestley
4c12420162 Replace "URI->setQueryParams()" after initialization with a constructor argument
Summary: Ref T13250. See D20149. In a number of cases, we use `setQueryParams()` immediately after URI construction. To simplify this slightly, let the constructor take parameters, similar to `HTTPSFuture`.

Test Plan: See inlines.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13250

Differential Revision: https://secure.phabricator.com/D20151
2019-02-14 11:46:37 -08:00
epriestley
88d5233b77 Fix specifications of some "Visual Only" elements
Summary: See PHI823. These got "visual-only" but should acutally get "aural => false" to pick up "aria-hidden".

Test Plan: Viewed page source, saw both "visual-only" and "aria-hidden".

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20157
2019-02-13 12:26:28 -08:00
epriestley
fcd85b6d7b Replace "getRequestURI()->setQueryParams(array())" with "getPath()"
Summary:
Ref T13250. A handful of callsites are doing `getRequestURI()` + `setQueryParams(array())` to get a bare request path.

They can just use `getPath()` instead.

Test Plan: See inlines.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13250

Differential Revision: https://secure.phabricator.com/D20150
2019-02-12 14:43:33 -08:00
epriestley
a20f108034 When an edit overrides an object lock, note it in the transaction record
Summary:
Ref T13244. See PHI1059. When you lock a task, users who can edit the task can currently override the lock by using "Edit Task" if they confirm that they want to do this.

Mark these edits with an emblem, similar to the "MFA" and "Silent" emblems, so it's clear that they may have bent the rules.

Also, make the "MFA" and "Silent" emblems more easily visible.

Test Plan:
Edited a locked task, overrode the lock, got marked for it.

{F6195005}

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: aeiser

Maniphest Tasks: T13244

Differential Revision: https://secure.phabricator.com/D20131
2019-02-09 06:10:07 -08:00
epriestley
9f5e6bee90 Make the default behavior of getApplicationTransactionCommentObject() "return null" instead of "throw"
Summary:
Depends on D20115. See <https://discourse.phabricator-community.org/t/transaction-search-endpoint-does-not-work-on-differential-diffs/2369/>.

Currently, `getApplicationTransactionCommentObject()` throws by default. Subclasses must override it to `return null` to indicate that they don't support comments.

This is silly, and leads to a bunch of code that does a `try / catch` around it, and at least some code (here, `transaction.search`) which doesn't `try / catch` and gets the wrong behavior as a result.

Just make it `return null` by default, meaning "no support for comments". Then remove the `try / catch` stuff and all the `return null` implementations.

Test Plan:
  - Grepped for `getApplicationTransactionCommentObject()`, fixed each callsite / definition.
  - Called `transaction.search` on a diff with transactions (i.e., not a sourced-from-commit diff).

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: jbrownEP

Differential Revision: https://secure.phabricator.com/D20121
2019-02-07 14:56:38 -08:00