diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b9ccba5 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +# Auto detect text files and perform LF normalization +* text eol=lf + +/tests export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.phpunit.xml.dist export-ignore +/README.md export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9ec3ff7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/phpunit.xml +/vendor/ +/composer.lock +/coverage.xml \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..cad0fdb --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,19 @@ +**Don't** use issue tracker (nor send any pull request) if you find a **security** issue. +They are public, so please send an email to the address on my [Github profile](https://github.com/Giuseppe-Mazzapica) + +---- + +Before work on features or bug fix you might want to open an issue first. + +No need to do this for small things or evident bugs that need a fix. + +After the change or new feature has been discussed, the contributing flow is: + +1. Fork it +2. Create your feature or bug-fix branch +3. Make your changes +4. Commit your changes +5. Run the tests, adding new ones for your own code if necessary. +6. Repeat 4, 5 and 6 until all tests pass. +6. Push to the branch +7. Create a pull request from your branch to "dev" branch \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..91c59e6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Giuseppe Mazzapica + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5694241 --- /dev/null +++ b/README.md @@ -0,0 +1,286 @@ +Nonces +====== + +[![Travis CI](https://img.shields.io/travis/Brain-WP/Nonces.svg?style=flat-square)](https://travis-ci.org/Brain-WP/Nonces) +[![codecov.io](https://img.shields.io/codecov/c/github/Brain-WP/Nonces.svg?style=flat-square)](https://codecov.io/github/Brain-WP/Nonces) +[![MIT license](https://img.shields.io/packagist/l/brain/nonces.svg?style=flat-square)](http://opensource.org/licenses/MIT) + +------ + +** Nonces is an OOP package for WordPress to deal with nonces. ** + +------------- + +TOC + +- [Introduction](#Introduction) +- [How it works](#how-it-works) + - [Rethinking WordPress workflow](#rethinking-wordpress-workflow) + - [`NonceInterface` and `WpNonce`](#nonceinterface-and-wpnonce) + - [Nonce context](#nonce-context) + - [`RequestGlobalsContext`](#requestglobalscontext) + - [`Helpers`](#helpers) + - [`WpNonce` is blog-specific](#wpnonce-is-blog-specific) +- [Breaking SRP](#breaking-srp) +- [Installation](#installation) +- [Minimum Requirements](#minimum-requirements) +- [License](#license) +- [Contributing](#contributing) + +------------- + +# Introduction + +WordPress nonces functions does not really work well in an OOP context. + +They needs "keys" and "actions" to be passed around, ending up in code that hardcodes those strings +in classes code, or stores them in globally accessible place. + +Both solutions are not ideal. + +This package aims to provide a way to ease WordPress nonces usage in OOP code. + +The specific issues that are addressed are: + +- avoid dealing with somehow hardcoded nonce "keys" and "actions" +- have a way to customize nonce TTL on a per nonce basis +- have an approach more suitable for OOP, with enough flexibility to be extended with different + implementations of nonces + +# How it works + +## Rethinking WordPress workflow + +_WordPress_ nonces workflow is: + +1. For a "task" a nonce key and an nonce value are put in a request (as URL query variable or via + hidden form field). The "key" is just hardcoded, the value is generated with `wp_create_action()` + and it is an hash based on an "action" that is specific for the "task"; +2. The request handler extracts the nonce value from request data (so it needs to be aware of the + nonce "key") and validates it with `wp_verify_nonce()` that needs to be aware the "action". + +What we wanted to avoid is to have "keys" and "actions" that needs to be known where the nonce +is _created_ **and** where it is _validated_, causing the issue of tightly coupling between different +parts of the code as well as the more pragmatic issue of a place to store those values, or to have them +just hardcoded. + +_This package_ workflow is: + +1. For a "task" a nonce object is created, passing an action string to constructor. + There's no "key" and the "action" is not needed to be known anywhere else. +2. The request handler, needs to receive (as method argument or as a dependency injected to constructor) + an instance of the nonce task and use that object ot validate the request. + +So, using this package, the workflow would be something like (pseudo code): + +```php +class TaskForm { + + public function __construct(\Brain\Nonces\NonceInterface $nonce){ + $this->nonce = $nonce; + $this->url = admin_url('admin-post.php'); + } + + public function printFrom() { + $url = add_query_arg($this->nonce->action(), (string) $this->nonce, $this->url); + echo "