Skip to content

Commit

Permalink
Nonce verification.
Browse files Browse the repository at this point in the history
  • Loading branch information
samwilson committed Feb 15, 2016
1 parent 3b73b64 commit 88437ba
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ before_script:
# Run the actual tests.
script:
- phpunit
- vendor/bin/phpcs --standard=phpcs.xml $TRAVIS_BUILD_DIR/tests $TRAVIS_BUILD_DIR/src
- vendor/bin/phpcs --standard=phpcs.xml tests src
96 changes: 69 additions & 27 deletions src/Controllers/ControllerBase.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,69 @@
<?php

namespace WordPress\Tabulate\Controllers;

abstract class ControllerBase {

/** @var \wpdb */
protected $wpdb;

/** @var string[] The injected $_GET query string. */
protected $get;

public function __construct( $wpdb, $get = array() ) {
$this->wpdb = $wpdb;
$this->get = $get;
}

protected function send_file( $ext, $mime, $content, $download_name = false ) {
$download_name = ($download_name ?: date( 'Y-m-d' ) ) . '.' . $ext;
header( 'Content-Encoding: UTF-8' );
header( 'Content-type: ' . $mime . '; charset=UTF-8' );
header( 'Content-Disposition: attachment; filename="' . $download_name . '"' );
echo $content;
exit;
}

}
<?php
/**
* This file contains only a single class.
*
* @package Tabulate
* @file
*/

namespace WordPress\Tabulate\Controllers;

/**
* All controllers must inherit from this class.
*/
abstract class ControllerBase {

/**
* The global database object.
*
* @var \wpdb
*/
protected $wpdb;

/**
* The injected $_GET query string.
*
* @var string[]
*/
protected $get;

/**
* Create the controller, with the global database and query string.
*
* @param wpdb $wpdb The global wpdb object.
* @param string[] $get The $_GET array.
*/
public function __construct( $wpdb, $get = array() ) {
$this->wpdb = $wpdb;
$this->get = $get;
}

/**
* Send specified content to the client as a downloadable file.
*
* @param string $ext The file extension.
* @param string $mime The mime-type of the file.
* @param type $content The file's content.
* @param string $download_name The name of the file, for the user to download.
*/
protected function send_file( $ext, $mime, $content, $download_name = false ) {
$download_name = ($download_name ?: date( 'Y-m-d' ) ) . '.' . $ext;
header( 'Content-Encoding: UTF-8' );
header( 'Content-type: ' . $mime . '; charset=UTF-8' );
header( 'Content-Disposition: attachment; filename="' . $download_name . '"' );
echo $content;
exit;
}

/**
* Verify the _wpnonce request value.
*
* @param string $action The action name.
*/
public function verify_nonce( $action ) {
$nonce = wp_verify_nonce( $_REQUEST['_wpnonce'], $action );
if ( ! $nonce ) {
wp_die();
}
}
}
59 changes: 45 additions & 14 deletions src/Controllers/RecordController.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
<?php
/**
* This file contains only a single class.
*
* @package Tabulate
* @file
*/

namespace WordPress\Tabulate\Controllers;

use WordPress\Tabulate\DB\Grants;

/**
* This controller handles viewing, saving, and deleting of individual Records.
*/
class RecordController extends ControllerBase {

/**
* Get the record-editing template for the given table.
*
* @param \WordPress\Tabulate\DB\Table $table The table.
* @return \WordPress\Tabulate\Template
*/
private function get_template( $table ) {
Expand All @@ -16,21 +28,27 @@ private function get_template( $table ) {
return $template;
}

/**
* Show the record-editing form.
*
* @param string $args The request arguments.
* @return string
*/
public function index( $args ) {
// Get database and table.
$db = new \WordPress\Tabulate\DB\Database( $this->wpdb );
$table = $db->get_table( $args[ 'table' ] );
$table = $db->get_table( $args['table'] );

// Give it all to the template.
$template = $this->get_template( $table );
if ( isset( $args[ 'ident' ] ) ) {
$template->record = $table->get_record( $args[ 'ident' ] );
if ( isset( $args['ident'] ) ) {
$template->record = $table->get_record( $args['ident'] );
// Check permission.
if ( ! Grants::current_user_can( Grants::UPDATE, $table->get_name() ) ) {
$template->add_notice( 'error', 'You do not have permission to update data in this table.' );
}
}
if ( ! isset( $template->record ) || $template->record === false ) {
if ( ! isset( $template->record ) || false === $template->record ) {
$template->record = $table->get_default_record();
// Check permission.
if ( ! Grants::current_user_can( Grants::CREATE, $table->get_name() ) ) {
Expand All @@ -57,23 +75,30 @@ public function index( $args ) {
return $template->render();
}

/**
* Save a record.
*
* @param string[] $args The request arguments.
* @return boolean
*/
public function save( $args ) {
$db = new \WordPress\Tabulate\DB\Database( $this->wpdb );
$table = $db->get_table( $args[ 'table' ] );
$table = $db->get_table( $args['table'] );
if ( ! $table ) {
// It shouldn't be possible to get here via the UI, so no message.
return false;
}

// Guard against non-post requests. c.f. wp-comments-post.php
if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' != $_SERVER['REQUEST_METHOD'] ) {
header('Allow: POST');
header('HTTP/1.1 405 Method Not Allowed');
header('Content-Type: text/plain');
// Guard against non-post requests. c.f. wp-comments-post.php.
if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
header( 'Allow: POST' );
header( 'HTTP/1.1 405 Method Not Allowed' );
header( 'Content-Type: text/plain' );
return false;
}

$record_ident = isset( $args[ 'ident' ] ) ? $args[ 'ident' ] : false;
$record_ident = isset( $args['ident'] ) ? $args['ident'] : false;
$this->verify_nonce( 'tabulate-record-' . $record_ident );
$template = $this->get_template( $table );

// Make sure we're not saving over an already-existing record.
Expand Down Expand Up @@ -102,14 +127,21 @@ public function save( $args ) {
exit;
}

/**
* Delete (or ask for confirmation of deleting) a single record.
*
* @param string[] $args The request arguments.
* @return type
*/
public function delete( $args ) {
$db = new \WordPress\Tabulate\DB\Database( $this->wpdb );
$table = $db->get_table( $args[ 'table' ] );
$record_ident = isset( $args[ 'ident' ] ) ? $args[ 'ident' ] : false;
$table = $db->get_table( $args['table'] );
$record_ident = isset( $args['ident'] ) ? $args['ident'] : false;
if ( ! $record_ident ) {
wp_redirect( $table->get_url() );
exit;
}
check_admin_referer( 'tabulate-record-' . $record_ident );

// Ask for confirmation.
if ( ! isset( $_POST['confirm_deletion'] ) ) {
Expand All @@ -134,5 +166,4 @@ public function delete( $args ) {
wp_redirect( $table->get_url() );
exit;
}

}
2 changes: 1 addition & 1 deletion src/Template.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public function render() {
$twig = new \Twig_Environment( $loader );

// Add some useful functions to Twig.
$funcs = array( 'admin_url', '__', '_e', 'wp_nonce_field' );
$funcs = array( 'admin_url', '__', '_e', 'wp_nonce_field', 'wp_create_nonce' );
foreach ( $funcs as $f ) {
$twig->addFunction( $f, new \Twig_SimpleFunction( $f, $f ) );
}
Expand Down
1 change: 1 addition & 0 deletions templates/record/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{% block content %}

<form method="post" action="{{record.get_url('save')}}" class="tabulate-record">
<input type="hidden" name="_wpnonce" value="{{wp_create_nonce('tabulate-record-'~record.id)}}" />
<table>

{% for column in table.get_columns %}
Expand Down
1 change: 1 addition & 0 deletions templates/record/shortcode.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{% include 'notices.html' %}

<form method="post" action="{{record.get_url('save')}}" class="tabulate tabulate-record">
<input type="hidden" name="_wpnonce" value="{{wp_create_nonce('tabulate-record-'~record.id)}}" />

{% for column in table.get_columns %}
<div class="form-group">
Expand Down

0 comments on commit 88437ba

Please sign in to comment.