Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: CI

on:
push:
pull_request:
workflow_dispatch:

jobs:
ci:
name: CI
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1
with:
phplinting: false
simple_matrix: true
phpcoverage_force_off: true
endtoend: false
extra_jobs: |
- php: '8.0'
db: mysql80
phpunit: true
phpunit_suite: 'all'
15 changes: 0 additions & 15 deletions .travis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# SilverStripe RESTful API

[![Build Status](https://travis-ci.org/colymba/silverstripe-restfulapi.png?branch=master)](https://travis-ci.org/colymba/silverstripe-restfulapi)
[![Build Status](https://github.com/colymba/silverstripe-restfulapi/actions/workflows/ci.yml/badge.svg)](https://github.com/colymba/silverstripe-restfulapi/actions/workflows/ci.yml)

This module implements a RESTful API for read/write access to your SilverStripe Models. It comes bundled with a default Token Authenticator, Query Handler and JSON Serializers, and can be extended to your need and to return XML or other content type via custom components.

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"silverstripe/framework": "~4.1"
},
"require-dev": {
"phpunit/phpunit": "~5.7@stable"
"phpunit/phpunit": "^9.5"
},
"autoload": {
"psr-4": {
Expand Down
8 changes: 5 additions & 3 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
- http://doc.silverstripe.org/framework/en/topics/testing/#configuration
-->
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
<testsuite name="Default">
<directory>tests</directory>
</testsuite>
<testsuites>
<testsuite name="Default">
<directory>tests</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>CORSPreflight</group>
Expand Down
2 changes: 1 addition & 1 deletion src/PermissionManagers/DefaultPermissionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class DefaultPermissionManager implements PermissionManager
* @param string $httpMethod API request HTTP method
* @return Boolean true or false if permission was given or not
*/
public function checkPermission($model, $member = null, $httpMethod)
public function checkPermission($model, $member = null, $httpMethod = 'GET')
{
if (is_string($model)) {
$model = singleton($model);
Expand Down
2 changes: 1 addition & 1 deletion src/PermissionManagers/PermissionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ interface PermissionManager
* @param string $httpMethod API request HTTP method
* @return Boolean true or false if permission was given or not
*/
public function checkPermission($model, $member = null, $httpMethod);
public function checkPermission($model, $member = null, $httpMethod = 'GET');
}
2 changes: 1 addition & 1 deletion src/QueryHandlers/DefaultQueryHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ public function parseQueryParameters(array $params)
* @param HTTPRequest $request The original HTTP request
* @return DataObject|DataList Result of the search (note: DataList can be empty)
*/
public function findModel($model, $id = false, $queryParams, HTTPRequest $request)
public function findModel($model, $id = false, $queryParams = [], HTTPRequest $request = null)
{
if ($id) {
$return = DataObject::get_by_id($model, $id);
Expand Down
2 changes: 1 addition & 1 deletion src/RESTfulAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ private function setAnswerCORS(HTTPResponse $answer)
//allowed headers
$allowedHeaders = '';
$requestHeaders = $this->request->getHeader('Access-Control-Request-Headers');
if ($cors['Allow-Headers'] === '*') {
if ($cors['Allow-Headers'] === '*' && $requestHeaders != null) {
$allowedHeaders = $requestHeaders;
} else {
$allowedHeaders = $cors['Allow-Headers'];
Expand Down
2 changes: 1 addition & 1 deletion src/ThirdParty/Inflector/Inflector.php
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ protected static function _cache($type, $key, $value = false)
public static function reset()
{
if (empty(self::$_initialState)) {
self::$_initialState = get_class_vars('Inflector');
self::$_initialState = get_class_vars(Inflector::class);
return;
}
foreach (self::$_initialState as $key => $val) {
Expand Down
2 changes: 1 addition & 1 deletion tests/Authenticators/TokenAuthenticatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ protected function getAuthenticator()
return $auth;
}

public static function setUpBeforeClass()
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();

Expand Down
36 changes: 21 additions & 15 deletions tests/PermissionManagers/DefaultPermissionManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class DefaultPermissionManagerTest extends RESTfulAPITester
ApiTestLibrary::class,
);

public static function setUpBeforeClass()
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();

Expand Down Expand Up @@ -83,25 +83,27 @@ public function testReadPermissions()
'Enabled' => false,
));

$id = ApiTestLibrary::get()->first()->ID;

// GET with permission = OK
$requestHeaders = $this->getRequestHeaders();
$requestHeaders['X-Silverstripe-Apitoken'] = $this->getAdminToken();
$response = Director::test('api/apitestlibrary/1', null, null, 'GET', null, $requestHeaders);
$response = Director::test('api/apitestlibrary/' . $id, null, null, 'GET', null, $requestHeaders);

$this->assertEquals(
$response->getStatusCode(),
200,
$response->getStatusCode(),
"Member of 'restfulapi-administrators' Group should be able to READ records."
);

// GET with NO Permission = BAD
$requestHeaders = $this->getRequestHeaders();
$requestHeaders['X-Silverstripe-Apitoken'] = $this->getStrangerToken();
$response = Director::test('api/apitestlibrary/1', null, null, 'GET', null, $requestHeaders);
$response = Director::test('api/apitestlibrary/' . $id, null, null, 'GET', null, $requestHeaders);

$this->assertEquals(
$response->getStatusCode(),
403,
$response->getStatusCode(),
"Member without permission should NOT be able to READ records."
);
}
Expand All @@ -116,25 +118,27 @@ public function testEditPermissions()
'Enabled' => false,
));

$id = ApiTestLibrary::get()->first()->ID;

// PUT with permission = OK
$requestHeaders = $this->getRequestHeaders();
$requestHeaders['X-Silverstripe-Apitoken'] = $this->getAdminToken();
$response = Director::test('api/apitestlibrary/1', null, null, 'PUT', '{"Name":"Api"}', $requestHeaders);
$response = Director::test('api/apitestlibrary/' . $id, null, null, 'PUT', '{"Name":"Api"}', $requestHeaders);

$this->assertEquals(
$response->getStatusCode(),
200,
$response->getStatusCode(),
"Member of 'restfulapi-administrators' Group should be able to EDIT records."
);

// PUT with NO Permission = BAD
$requestHeaders = $this->getRequestHeaders();
$requestHeaders['X-Silverstripe-Apitoken'] = $this->getStrangerToken();
$response = Director::test('api/apitestlibrary/1', null, null, 'PUT', '{"Name":"Api"}', $requestHeaders);
$response = Director::test('api/apitestlibrary/' . $id, null, null, 'PUT', '{"Name":"Api"}', $requestHeaders);

$this->assertEquals(
$response->getStatusCode(),
403,
$response->getStatusCode(),
"Member without permission should NOT be able to EDIT records."
);
}
Expand All @@ -155,8 +159,8 @@ public function testCreatePermissions()
$response = Director::test('api/apitestlibrary', null, null, 'POST', '{"Name":"Api"}', $requestHeaders);

$this->assertEquals(
$response->getStatusCode(),
200,
$response->getStatusCode(),
"Member of 'restfulapi-administrators' Group should be able to CREATE records."
);

Expand All @@ -166,8 +170,8 @@ public function testCreatePermissions()
$response = Director::test('api/apitestlibrary', null, null, 'POST', '{"Name":"Api"}', $requestHeaders);

$this->assertEquals(
$response->getStatusCode(),
403,
$response->getStatusCode(),
"Member without permission should NOT be able to CREATE records."
);
}
Expand All @@ -182,25 +186,27 @@ public function testDeletePermissions()
'Enabled' => false,
));

$id = ApiTestLibrary::get()->first()->ID;

// DELETE with permission = OK
$requestHeaders = $this->getRequestHeaders();
$requestHeaders['X-Silverstripe-Apitoken'] = $this->getAdminToken();
$response = Director::test('api/apitestlibrary/1', null, null, 'DELETE', null, $requestHeaders);
$response = Director::test('api/apitestlibrary/' . $id, null, null, 'DELETE', null, $requestHeaders);

$this->assertEquals(
$response->getStatusCode(),
200,
$response->getStatusCode(),
"Member of 'restfulapi-administrators' Group should be able to DELETE records."
);

// DELETE with NO Permission = BAD
$requestHeaders = $this->getRequestHeaders();
$requestHeaders['X-Silverstripe-Apitoken'] = $this->getStrangerToken();
$response = Director::test('api/apitestlibrary/1', null, null, 'DELETE', null, $requestHeaders);
$response = Director::test('api/apitestlibrary/' . $id, null, null, 'DELETE', null, $requestHeaders);

$this->assertEquals(
$response->getStatusCode(),
403,
$response->getStatusCode(),
"Member without permission should NOT be able to DELETE records."
);
}
Expand Down
11 changes: 7 additions & 4 deletions tests/QueryHandlers/DefaultQueryHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class DefaultQueryHandlerTest extends RESTfulAPITester
/**
* Turn on API access for the book and widget fixtures by default
*/
public function setUp()
public function setUp(): void
{
parent::setUp();

Expand Down Expand Up @@ -81,7 +81,7 @@ protected function getQueryHandler()
return $qh;
}

public static function setUpBeforeClass()
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();

Expand Down Expand Up @@ -147,7 +147,10 @@ public function testAPIDisabled()
public function testFindSingleModel()
{
$qh = $this->getQueryHandler();
$request = $this->getHTTPRequest('GET', ApiTestBook::class, '1');

$id = ApiTestBook::get()->first()->ID;

$request = $this->getHTTPRequest('GET', ApiTestBook::class, $id);
$result = $qh->handleQuery($request);

$this->assertContainsOnlyInstancesOf(
Expand All @@ -156,7 +159,7 @@ public function testFindSingleModel()
'Single model request should return a DataObject of class model'
);
$this->assertEquals(
1,
$id,
$result->ID,
'IDs mismatch. DataObject is not the record requested'
);
Expand Down
4 changes: 2 additions & 2 deletions tests/RESTfulAPITester.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public function getRequestHeaders($site = null)
);
}

public static function setUpBeforeClass()
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();

Expand All @@ -159,7 +159,7 @@ public static function setUpBeforeClass()
}
}

public function setUp()
public function setUp(): void
{
parent::setUp();

Expand Down