Fix an error in the PolicyFilter algorithm

Summary:
`PhabricatorPolicyFilter` has a bug right now where it lets through objects incorrectly if:

  - the query requests two or more policies;
  - the object satisfies at least one of those policies; and
  - policy exceptions are not enabled.

This would be bad, but there's only one call in the codebase which satisfies all of these conditions, in the Maniphest batch editor. And it's moot anyway because edit operations get another policy check slightly later. So there is no policy/security impact from this flaw.

(The next diff relies on this behavior, which is how I caught it.)

Test Plan:
  - Added a failing unit test and made it pass.
  - Grepped the codebase for `requireCapabilities()` and verified that there is no security impact. Basically, 99% of callsites use `executeOne()`, which throws anyway and moots the filtering.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Differential Revision: https://secure.phabricator.com/D7721
Don't show client IP in push logs unless viewer can edit the repository

Summary: This locks push logs down a little bit and makes them slightly more administrative. Primarily, don't show IPs to googlebot, etc.

Test Plan: Viewed push logs as edit and non-edit users.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Differential Revision: https://secure.phabricator.com/D7722
Minor, sort out a change request which was lost in the melee.
Implement "Upload Artifact" build step

Summary: This implements a build step for uploading an artifact from a build machine to Phabricator.  It uses SFTP so that it will work on both UNIX and Windows build machines.

Test Plan: Ran an "Upload Artifact" build against a Windows machine (with FreeSSHD installed).  The artifact uploaded to Phabricator, appeared on the build view and the file contents could be viewed from Phabricator.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T1049

Differential Revision: https://secure.phabricator.com/D7582
Implement explicit build step ordering in Harbormaster

Summary: This implements support for explicitly marking the sequence of build steps.  Users can now drag and re-order build steps in plans, and artifact dependencies are re-calculated so that if you move "Run Command" before "Lease Host", the "Run Command" step has it's artifact setting cleared and thus the step becomes invalid.

Test Plan: Re-ordered build steps and observed dependencies being correctly recalculated.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T1049

Differential Revision: https://secure.phabricator.com/D7715
Multicolor headers

Summary: This adds a handful of 'Main Header' colors to change the look of Phabricator very slightly. I know I would probably set my dev header to a different color.

Test Plan: Tested each css class and color, can add more in the future.

Reviewers: epriestley, btrahan

Reviewed By: btrahan

CC: Korvin, epriestley, aran

Differential Revision: https://secure.phabricator.com/D7731
Fix over-matching of quoted text for message bodies beginning with "On..."

Summary:
A user sent a message to Phabricator which looked like:

  On blah blah blah ?

  On <date>, <user> wrote:
  > blah blah blah

The current algorithm is too aggressive and thinks lines 1-3 are //all// the "On ... wrote:" string. Instead, patch only the most recent "On".

Test Plan: Added a failing test and made it pass.

Reviewers: btrahan, zeeg

Reviewed By: zeeg

CC: aran

Differential Revision: https://secure.phabricator.com/D7732
Make nonscalar field saves raise a more useful exception from LiskDAO

Summary:
If you do something like this:

  // Missing $user->getPHID()!
  $object->setUserPHID($user)->save();

...you get a very unhelpful exception:

  Expected a scalar or null for %s conversion. Query: %s

This doesn't give you any hints about what's wrong. Instead, provide a more useful exception:

  Unable to insert or update object of class DifferentialRevision, field 'title' has a nonscalar value.

Test Plan: {F87614}

Reviewers: hach-que, btrahan

Reviewed By: btrahan

CC: aran

Differential Revision: https://secure.phabricator.com/D7725
Phragment v0

Summary: Ref T4205.  This is an initial implementation of Phragment.  You can create and browse fragments in the system (but you can't yet view a fragment's patches / history).

Test Plan: Clicked around and created fragments.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7726
Implement update and history controllers in Phragment

Summary: Depends on D7726.  This adds a history controller (for viewing a list of patches associated with a fragment) and an update controller, for creating a new patch of a fragment.

Test Plan: Updated and viewed history of fragments.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7727
Implement "Download ZIP" controller for Phragment

Summary: Depends on D7727.  This adds support for downloading a fragment and all it's children as a ZIP file.  Fragments that have children automatically become directories in the ZIP file.

Test Plan: Downloaded a fragment as a ZIP and was able to extract the contents successfully.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7728
Implement support for creating and updating fragments from ZIPs

Summary:
This implements support for creating and updating fragments from ZIP files.  It allows you to upload a ZIP via the Files application, create a fragment from it, and have it recursively imported into Phragment.  Updating that folder with another ZIP will recursively create, update and delete files as appropriate.

The logic for creating and updating fragments from files has also been centralized into the PhragmentFragment class.  Directories are also now supported; a directory fragment is simply a fragment that has no patches; thus a directory fragment can be converted to a file fragment by uploading a first patch for it.

Test Plan: Uploaded ZIP files through the interface and saw all of the fragments get created and updated as expected.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7729
Add UI for choosing header color

Summary: See D7731. Fixes T4194.

Test Plan: {F88020}

Reviewers: chad, btrahan

Reviewed By: chad

CC: aran, mbishopim3

Maniphest Tasks: T4194

Differential Revision: https://secure.phabricator.com/D7740
Fix undefined variables in Subversion

Summary: These variables won't be in scope in Subversion.

See: <https://secure.phabricator.com/rP2ff5541fc59c4be7abd733a39e12db8358004f7a>

Auditors: btrahan
Implicitly detect directories when updating a fragment from a ZIP

Summary: This fixes the update-from-ZIP functionality so that it will automatically detect directories in the ZIP that do not have explicit entries.  Some ZIP programs do not create directory entries explicitly, so if we fail to do this then there's no way for users to access the sub-fragments (even though they exist, there is no directory fragment to click through).

Test Plan: Created and updated fragments from a ZIP that had implicit directories in it.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran, staticshock

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7733
Implement viewing versions and downloading patches in Phragment

Summary:
This adds support for viewing individual versions on a fragment as well as comparing versions and downloading diff_match_patch-based patches.

It does not use the side-by-side diff format as while it works for small changes, it quickly becomes impossible to distingush what changes have been made due to the diff_match_patch format.

Test Plan: Clicked on versions and downloaded patches.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7734
Correctly handle downloading ZIP with empty directories in Phragment

Summary: This logic causes an exception because getPHID() is called on a fragment that has no latest version.  This fixes the code so that in this scenario, it returns an empty array (with no path to be added to the ZIP).

Test Plan: Downloaded the ZIP successfully after the patch was applied.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7735
Fix deletion detection when updating based on ZIP

Summary: When the code to update based on ZIP went to look up the child fragments, it explicitly used the paths provided in the ZIP.  This meant that we could never detect omissions because there'd never be a scenario where a child fragment would return but not exist in the ZIP.  To fix this, the query should be using `withLeadingPath` instead of `withPaths`.

Test Plan: Uploaded a ZIP that omitted a file and saw the `deleteFile` get called (by placing debugging output in the code).

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7736
Render deleted files in Phragment as disabled

Summary: This updates Phragment so that fragments that are currently considered deleted have a disabled status and have an additional attribute 'Deleted'.  It also places this effect on versions (in the history controller) that actually involve deleting the file.

Test Plan: Viewed deleted fragments and versions.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7737
Implement "Revert to Version" functionality in Phragment

Summary:
This functionality allows users to revert a fragment to a previous version from the history page.

Reverting a version actually creates a new version pointing at the same file as the version being "reverted" to.  In this sense it acts pretty much like Git and other distributed VCS where once you have published a commit the only way to undo your changes is to create a new commit that reverts those changes.

Test Plan: Reverted a fragment to a version before it was deleted, then reverted it to when it was deleted and saw the new versions have the correct file PHIDs (including null for the deletion).

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205

Differential Revision: https://secure.phabricator.com/D7738