cedaro / satispress Goto Github PK
View Code? Open in Web Editor NEWExpose installed WordPress plugins and themes as Composer packages.
Expose installed WordPress plugins and themes as Composer packages.
Just for developer sanity, a change log file makes it easier to see the difference between versions.
Suggestion: Add a checkbox which allows the following to be triggered, which in turn enables automatic updates of plugins and themes:
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
The benefit is then that the SatisPress site doesn't need to be checked regularly and have plugins and themes manually updated. While these two lines could be added to any other plugin or theme installed on the site, I think it makes sense in this case to make it a part of SatisPress.
I like to check in on my satispress install to ensure / see what plugins have been updated, would be useful to have a dashboard plugin to summarize any new changes/etc that have happened, or to inform me of any issues (i.e. a plugin failed to update and requires my attention).
Not seen it asked for, but could some packages be exposed as public i.e. bypass Basic Auth, while others stay protected? Might need packages.json
to effectively have a public view and an authenticated view.
Even if it's not built-in, having example code snippet in the /docs for how to amend the visibility and access of specific packages (or even specific releases of packages) would be very cool indeed.
Despite the flags set for plugins when I add the repository to my composer.json
file I get all of the plugins runnig composer install
within the directory wp-content/plugins/hello
.
In my in installation I have gutenberg, hello dolly, user-switching and satispress.
I selected only hello dolly as satipress plugin and I correctly have it in my packages.json
{"packages":{"satispress\/hello":{"1.7":{"name":"satispress\/hello","version":"1.7","version_normalized":"1.7.0.0","dist":{"type":"zip","url":"http:\/\/localhost\/dev_wp\/satispress\/hello\/1.7","shasum":"7d250c9c966d9f19af8bd1aa1dc34989a373e28d"},"require":{"composer\/installers":"^1.0"},"type":"wordpress-plugin","authors":{"name":"Matt Mullenweg","homepage":"http:\/\/ma.tt\/"},"description":"This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly<\/cite> in the upper right of your admin screen on every page.","homepage":"http:\/\/wordpress.org\/plugins\/hello-dolly\/"}}}}
Then in my composer.json
I have:
{
"name": "guido/testing",
"repositories": [
{
"type": "composer",
"url": "http://localhost/dev_wp/satispress/packages.json"
}
],
"require": {
"satispress\/hello": "1.7"
},
"config": {
"secure-http": false
}
}
Composer install output is:
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
- Installing composer/installers (v1.5.0): Loading from cache
- Installing satispress/hello (1.7): Downloading (100%)
That seems correctly but navigating to wp-content/plugins/hello
directory I see all of the plugins I have installed in my dev_wp
site.
I guess a misconfiguration on my composer.json file.
The excludes
variable is set, but appears to be unused:
On first login after updating to the latest code, I get a PHP Warning:
Warning: rename(/app/public/wp-content/uploads/satispress,/app/public/wp-content/uploads/satispress-lAUb9bjyV0ND/): Directory not empty in /app/public/wp-content/plugins/satispress/src/Provider/Upgrade.php on line
(and then it seems I unfortunately didn't manage to copy the line number before refreshing, but I presume its the line with the rename()
call!)
Both the original and the new directories exist, and both seem to have the plugin directories inside them. After refreshing the admin page, the warning disappears.
Moving the @todo
here and out of the code:
The repositories
snippet on the admin page needs to account for HTTPS. My satispress site uses HTTPS, but the snippet suggests http://
. Actually trying this, gives a composer error that references https://getcomposer.org/doc/06-config.md#secure-http
There's a little bit of mismatch between Package
and InstalledPackage
, and likewise for PackageRepository
and InstalledPackageRepository
.
Consider code like this:
The object returned on line 50 is a Package
(according to the DocBlock), but the methods called on line 51 and 52 are only contracted by InstalledPackage
.
Does a Release always reference an installed package?
Likewise, this code:
is calling a get_installed_version()
, which is only defined in InstalledPackage
, yet the repository passed in to the constructor is a PackageRepository
, which is a collection of Package
objects, and not specifically InstalledPackage
objects.
A new InstalledPackageRepository
, containing InstalledPackage
objects would better define the contracts that are currently being assumed.
Here are the undefined methods violations:
Currently, the API Key table shown on the SatisPress settings page just has the User ID, but this could be improved to show the display name / username of the user, and be linked to their profile, to make it easier for administrators to get around.
Also, for the API Key table shown in a profile, the column is redundant and could be removed.
For whatever reason, I'm struggling to set HTTP Basic Auth on the right folder, either manually, or through my hosts cPanel.
Since SatisPress appears to be creating a .htaccess
file in the uploads/satispress
directory anyway, it would be cool if SatisPress could have the option of creating the .htpasswd too and update the .htaccess
file.
<code>...</code>
around the Package type value.target="_blank" rel="noopener noreferer"
to Home Page and Author links./latest
to make it easy to grab the URL / see what version is considered to be / mapped to the latest.See #35 (comment)
Right now, there's no way to get automatic updates. We either need to add GitHub Updater headers to the plugin, or consider adding it to the wp.org repo to support standard updating.
@bradyvercher What would be your preference?
See #37 (comment)
An administrator may want to see how often an API Key is used, or when the last time was. Logging hits to packages.json
, or when releases are downloaded, and displaying that to admins might be a good extension plugin, if not built-in to SatisPress itself.
When the More button on the API Keys table is clicked, the popup appears with the Revoke option. I'd expect this to disappear when clicking elsewhere on the page. Currently, it only disappears if the More button is re-clicked.
Packages are currently cached in the top level of the cache path defined in the service provider, so the directory structure looks something like this:
├─ wp-content
└─ uploads
└─ satispress-xxxx
└─ akismet
└─ akismet-4.0.8.zip
That doesn't really allow for adding anything else in that same location that needs to be stored on the filesystem, so I'm thinking packages should be moved to a /packages
subdirectory:
├─ wp-content
└─ uploads
└─ satispress-xxxx
├─ cache
├─ logs
├─ packages
│ └─ akismet
│ └─ akismet-4.0.8.zip
└─ .htaccess
We currently have 2 throws of exceptions (Exception
and UnexpectedValueException
), but I know that there could be other instances where throwing an exception would be better than returning null
or false
.
Basic authentication comes with security issues as currently detailed in the documentation. Mitigating those issues requires jumping through a few hurdles that are easier to ignore than implement, especially for people not aware of issues:
auth.json
Using credentials for a WordPress user makes it too easy to accidentally leak passwords and conditions users to provide their credentials to third-parties, making them susceptible to phishing attacks or dependent on the security of the third-party who needs to store the password in clear text for future use.
To work around these issues, each user or client that accesses SatisPress needs a separate user account with limited capabilities. This requires manually assigning those capabilities to an existing role, which potentially opens SatisPress up to all users on a system, or creating a new role. That's a lot of work for basic security, and while it might be OK for a single user, it would quickly become a pain for a team of developers or vendors looking to add support for customers.
With those problems outlined, a new solution should:
While Composer has support for authentication schemes specific to popular services (GitHub, GitLab, Bitbucket, tc ), support appears to be limited to Basic Auth for general use. It might be possible to write a Composer plugin to support other auth methods, but that requires an additional step for consumers to require it.
At this point, I'm leaning toward using API keys with Basic Auth rather than WP user credentials with the following workflow:
satispress
as the passwordThe benefits are:
auth.json
This approach can be further extended by allowing each user to have one or more API keys for each client that needs to access SatisPress. Revoking access would just require deleting an API key and wouldn't affect other clients.
API keys are still susceptible to being discovered if used over plain HTTP, but Composer is configured to only work with HTTPS by default and other auth schemes that are better suited for plain HTTP wouldn't work well with Composer without a plugin.
I'm guessing this would likely break backward compatibility for sites using the pre-0.3.0 Basic Auth implementation, but given the security benefits, I think it would be worthwhile.
See comments in #25 for the back story.
After #32 lands, we'll need a build process to create distributable archives that can be uploaded when a new version is tagged.
See #35 (comment)
The WPSSO plugin author uses a dash in his version strings. I think that's why I'm getting this:
[RuntimeException]
Could not load package satispress/wpsso in https://packages.auswebhost.com/satispress:
[UnexpectedValueException] Invalid version string "3.36.2-1"
I tried using wpackagist for WPSSO but it also was having issues, but perhaps for other reasons. I got the message that the WPSSO package didn't exist in the wpackagist repo!
Thoughts? Work-arounds?
A
[Composer\Downloader\TransportException]
"https://satis.example.com/satispress/my-plugin/1.0.0" appears broken, and returned an empty 200 response
While visiting the URL directly correctly downloads a zip file, Composer throws this error.
Any suggestions?
The SatisPress_Package
is extended by SatisPress_Package_Plugin
and SatisPress_Package_Theme
. Some methods exist in both child classes, with some being class-specific, and some being identical.
Elsewhere in the code, arrays of $packages
are correctly treated without caring what type of package they are. Methods are called against them. This existence of polymorphism strongly suggests that an interface should exist, so it can be type-hinted against.
What I'd like to see:
SatisPress_Package
being marked as abstract.SatisPress_Package
implementing a new interface which lists all the methods common between plugin and theme classes and in the abstract base class.class-
.get_slug()
into the base class.get_type()
methods moved to class constants, so that the method to retrieve it can be refactored to return that constant, and can therefore be moved into the base class.Give a bit of background in the README about Packagist, and Satis, and therefore why this project exists.
See TGMPA/TGM-Plugin-Activation#746 (comment)
We currently support URLs like https://example.com/satispress/gravityforms/2.3.1
, but this would require a URL like https://example.com/satispress/gravityforms/latest
that would automagically resolve to the highest version. No other constraint-resolution would be needed.
@bradyvercher What is the minimum support version of PHP for this plugin?
I'm planning on moving this repo to the Cedaro GitHub organization to make it easier to track and provide more visibility since the Blazer Six GitHub organization isn't active. This issue is to document that change and any steps users might need to take to make the switch.
Warning: count(): Parameter must be an array or an object that implements Countable in /Users/guido/Sites/dev_wp/wp-content/plugins/satispress/src/Storage/Local.php on line 104
Within the plugins SatisPress table column
DirectoryIterator
doesn't implement Countable
interface, for this case use iterator_count
@bradyvercher Was this line a debug line that was committed accidentally?
Hey @blazersix,
This is awesome! Thank you very much for this plugin!
I'm having some problems with my setup though. When I have HTTP Basic Authentication on I'm not able to update my plugins. I have been using the administrators Username and Password but it won't work. If I'm signed into wordpress in a browser it will download but if I open a new window it won't let me in.
Any thoughts?
Thank you,
Ian
Since the VersionParser has now been extracted out of Composer and into it's own repo, we should consider pulling in composer/semver
as a dependency, instead of having a manual copy.
Having watched Capability-Driven Development WCEU talk by @felixarntz, I think we could improve the capabilities situation in SatisPress. We already have custom capabilities for viewing or downloading packages, but I think they could be applied to Administrators in a different way, and we could use a custom capability of the admin screen.
Currently, we register the admin screen with manage_options
.
Instead, we could use a new capability like manage_satispress_options
, and then filter user_has_cap
so that anyone with manage_options
can see the SatisPress page, but site owners have more flexibility about who else might be granted that capability - see 21:25 in the video.
If manage_satispress_options
was added, then it should be checked against when displaying the plugins checkbox, and also when saving the result of the Ajax call.
All seems good here, though adding a mapping for manage_satispress_option
would also be needed if the above was done.
09:30 of the video says that a guideline is to "Never add capabilities to the database, unless you introduce an entire new role".
Right now, I think we add download packages and view packages capabilities directly to the administrator role, breaking this guideline.
I think if we filtered user_has_cap
again to add the download packages and view packages capabilities, then we could avoid breaking this guideline, and allow site owners to remove our filter if needed.
Alternatively, we could add a new "SatisPress Manager" role for managing the SatisPress settings + Plugins checkboxes - see 24:00 of the video.
Thoughts? (@bradyvercher, @felixarntz or anyone else)
Hello all,
I'm trying to set up a simple wordpress site (localhost) so that it is under the git version control system (in a KISS way, ie without having to save all wordpress installation folder).
I have recently discovered that a similar result can be achieved through the use of composer and wpackagist (eg here is a random guide from the internet).
Digging into the internet I found your repo, if I understand correctly, it allows me to generate a "composer.json" file directly from the list of installed plugins / themes? (reusable in other installations?)
It would be interesting if it were possible to change the base URL domain from "http://localhost/"
to "https://wpackagist.org/"
(or any custom one)
Leaving aside any digression..
Like the issue #23:
My current system is: WP 4.9.4, PHP 7.0.9 and Satipress 0.2.3
Any way, thanks for the effort!
Hi Brady. Huge thanks for this - very useful!
Regarding the setting to enable/disable HTTP Basic Auth, I noticed that although this setting does indeed modify the .htaccess file within /wp-content/uploads/satispress/ thereby denying direct access to package archives files such as https://example.com/wp-content/uploads/satispress/my-package/my-package-1.0.0.zip, it doesn't disable Authentication altogether.
Attempting to access a package at the URL provided by the SatisPress packages.json file (such as https://example.com/satispress/my-package/1.0.0) still brings up a login prompt.
Is this expected behaviour? I would expect unchecking the 'Enable HTTP Basic Authentication?' option should disable authentication altogether. If you agree, I can try and send a PR to fix?
If there's no JS, the Settings -> SatisPress -> Packages release links act as a normal (download) link - that's fine.
When JS is present, the link should be changed to / replaced with a button
since the only behaviour is to expand the panel with the extra fields and Download button.
This toggle button should also have a aria-expanded
attribute, set to false
by default, but toggled to true when it has been activated and the panel is open.
This will help to improve accessibility a little bit.
I have a must use plugin installed. My composer.json has this content:
{ "name": "pms72/pms72-soil", "homepage": "https://bitbucket.org/pms72/pms72-soil", "authors": [ { "name" : "Jurgen Oldenburg", "email" : "[email protected]", "homepage" : "http://www.pms72.com" } ], "type": "wordpress-muplugin", "require": { "composer/installers": "~1.0" } }
Unfortunately, satispress does not pick up the type from the composer file, but sets it statically, so the plugin is placed in the standard plugins folder, in stead of the mu-plugins folder. Can this be fixed?
Similar to how wpackagist allows you to click on a release and opens a text input with the package and version constructed and selected:
I would love to see this added, it would make grabbing the packages at the versions you specify much easier and foolproof (sometimes I don't look closely enough at the package names, i.e. some plugins don't use spaces/hyphens where you would think).
Going a step further and making this work with whatever version you select (again similar to wpackagist) would be helpful.
When trying to create an API Key from either Settings -> SatisPress, or from my user profile, clicking the button results in an admin-ajax.php response of 500
, and no visible change to the table (the spinner flashes briefly).
After refreshing the page, I get the following error:
Fatal error: Uncaught Exception: DateTimeZone::__construct(): Unknown or bad timezone () in /app/public/wp-content/plugins/satispress/src/Authentication/ApiKey/ApiKey.php on line 160
My get_option( 'timezone_string' );
resolves to an empty string. The Settings->General has it as "UTC+0".
Changing it to "Europe/London" correctly populates the option value and the fatal error is gone.
Changing it to "UTC-5" and I get the previous fatal error. It seems that the manual offset does not produce a timezone string valid for DateTimeZone().
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.