Coder Social home page Coder Social logo

grav-plugin-api's People

Contributors

regaez avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

grav-plugin-api's Issues

refactor: use new Resource abstracts for Page type

Change PageResource and PageCollectionResource to extend the new Resource and CollectionResource abstract classes, respectively.

This should result in less code duplication since all the resources currently share functions that behave similarly.

docs: add all possible PageResource attributes to spec

At the moment, only the attributes which are included by default (api.yaml specifies limited fields) are shown in the API specification file. The specification should be updated to include all possible attributes.

This way, people will know which values are valid to add to the fields array within the /pages configuration object.

docs: add development procedures

Document development procedures, such as:

  • commit naming conventions, zappr config
  • issue/PR process/requirements, and project board
  • documentation, e.g. specification, postman collection
  • testing framework/setup
  • how to debug with vscode/xdebug
  • adding to project's Grav site user folder
  • how to update grav version in development environment
    • adjust dockerfile
    • bump composer dependency

This should assist with knowledge transfer for anyone looking to contribute to the plugin's development.

fix: config returns non-standard response

The GET /config endpoint should change to GET /configs to match the other endpoints format.

It currently returns a non-standard response when compared to the /users or /pages endpoint.

It should be changed to return:

{
  "items": [], // an array containing ConfigResource objects
  "meta": {
    "count": 4
  }
}

And a ConfigResource should also be shaped in such a way:

{
  "type": "config",
  "id": "api",
  "attributes": {
    // actual config settings
  },
  "links": {
    "related": {
      "self": "http://localhost:8080/api/config/site"
    }
}

fix: plugins return non-standard response

The GET /plugins endpoint currently returns a non-standard response when compared to the /users or /pages endpoint.

It should be changed to return:

{
  "items": [], // an array containing PluginResource objects
  "meta": {
    "count": 7
  }
}

And a PluginResource should also be shaped in such a way:

{
  "type": "plugin",
  "id": "api",
  "attributes": {
    "enabled": true,
    // other plugin config settings
  },
  "links": {
    "related": {
      "self": "http://localhost:8080/api/plugins/api"
    }
}

feat: improve PageResource hypermedia linking

The children property should be moved out of the PageResource attributes and added to the links hypermedia.

For example:

"links": {
    "self": "http://localhost:8080/parent-page",
    "children": [
        "http://localhost:8080/parent-page/child-1",
        "http://localhost:8080/parent-page/child-2"
    ],
    "related": {
        "self": "http://localhost:8080/api/pages/parent-page",
        "children": [
            "http://localhost:8080/api/pages/parent-page/child-1",
            "http://localhost:8080/api/pages/parent-page/child-2"
        ],
        "resource": "http://localhost:8080/api/pages/"
    }
}

Similarly, a child page should have a parent link:

"links": {
    "self": "http://localhost:8080/parent-page/child-1",
    "parent": "http://localhost:8080/parent-page",
    "related": {
        "self": "http://localhost:8080/api/pages/parent-page/child-1",
        "parent": "http://localhost:8080/api/pages/parent-page",
        "resource": "http://localhost:8080/api/pages/"
    }
}

Similarly, a child page should have a siblings field for pages at the same level:

"links": {
    "self": "http://localhost:8080/parent-page/child-1",
    "parent": "http://localhost:8080/parent-page",
    "siblings": [
        "http://localhost:8080/parent-page/child-2"
    ],
    "related": {
        "self": "http://localhost:8080/api/pages/parent-page/child-1",
        "parent": "http://localhost:8080/api/pages/parent-page",
        "siblings": [
            "http://localhost:8080/api/pages/parent-page/child-2"
        ],
        "resource": "http://localhost:8080/api/pages/"
    }
}

fix: only show enabled endpoints on /api route

Currently, the /api route will show links to all endpoints. This should be changed so it only returns enabled endpoints.

Current

{
  "page": "http://localhost:8080/api/pages/",
  "user": "http://localhost:8080/api/users/",
  "plugin": "http://localhost:8080/api/plugins/",
  "config": "http://localhost:8080/api/configs/"
}

Expected

If you only have the page resource type enabled:

{
  "page": "http://localhost:8080/api/pages/"
}

docs: explain authentication

We should create a docs/AUTHENTICATION.md file which explains the following:

  • explain authorisation using Grav Sessions
  • how to authenticate API requests using Basic auth
  • roles and their related permissions
  • how to define API roles on user accounts
  • how to create groups, and inherit group permissions as a user
  • explain taxonomy-based permissions
  • make a note about PHP-CGI and .htaccess workaround

chore: remove some unused imports

I noticed that in some of the file there are use statements importing classes which are not actually used. These should be removed.

Fix `/users` endpoint

When calling GET /api/users there is an error:

Message: array_merge(): Argument #2 is not an array
From src/Handlers/UsersHandler.php on line 41

fix: prevent pages using an invalid template

At the moment, you can make a PATCH or POST request and set a page to use a non-existent page template. This would cause a twig rendering error and break the page.

We should validate that the template can be used (based on the currently active theme?) when attempting to change this, and throw a 400 Bad Request if the new template is invalid.

refactor: use new Resource abstracts for User type

Change UserResource and UserCollectionResource to extend the new Resource and CollectionResource abstract classes, respectively.

This should result in less code duplication since all the resources currently share functions that behave similarly.

feat: update plugin config

Create a PATCH /plugins/{id} authenticated endpoint that allows an admin to change a plugin's settings.

fix: processing plugin config file

The GravApi\Config\Config class is instantiated in a non-sensical way: the api.php class passes $settings to the GravApi\Api class, which then passes this to create a new Config::instance($settings).

This is entirely unnecessary since we could just use Grav::instance() in the Config constructor to get the required plugin config information, thereby removing the need to pass $settings.

Also, Config is currently causing problems with the AuthMiddleware because it has a mix of array and stdClass for some reason. Therefore, in the middleware, the $this->config–>auth check is not reliable due to not handling these different types. Creating some Settings classes to standardise the structure and some functions to access could simplify the AuthMiddleware and greatly improve the reliability of the configuration info.

Not to mention that this config file is able to be manipulated by users, so could be imported with an invalid format!

Note: issue #34 could be resolved as part of this one, too.

feat: consider "public" and "private" user fields

Perhaps the UserResource object should not expose fields such as access or state... unless the request is authenticated for that user, or an admin?

We currently always filter out hashed_password so that it is not exposed publicly.

feat: create a 404 response for API

The API should return a 404 response for any paths requests with the /api route that don't exist, rather than displaying Grav's HTML 404 page.

For example, https://www.mysite.com/api/some-undefined-endpoint should return something like:

HTTP Status: 404
Content-Type: application/json

{
  "message": "API endpoint not found",
  "documentation": "https://github.com/regaez/grav-plugin-api/tree/master/docs"
}

fix: no way to define page order

When you create a new page "test", there is currently no way to define its folder prefix/page order, e.g. pages/03.test. It will only create pages/test.

This means that a new page doesn't automatically show up in navigation for themes relying on page ordering.

fix: create/Update page doesn't render HTML correctly

Twig variables/functions are not rendered correctly when updating or creating a new page.

{
    "route": "/test",
    "template": "default",
    "header": {
    	"custom_field": "WORLD"
    },
    "content": "HELLO {{page.header.custom_field}}!"
}

Outputs:

"content": "<p>HELLO {{page.header.custom_field}}!</p>"

Expected output:

"content": "<p>HELLO WORLD!</p>"

Use latest version of Grav

  • Use the latest version of Grav (v1.6.11) for development environment.
  • Define own Dockerfile to control development enviroment more easily

feat: managing site media

How should the API manage site media? Should there be another endpoint that will allow uploading/deleting images etc?

Need to investigate how Grav internally handles media.

docs: explain plugin config file

There should be some documentation written on the various fields in the plugin's api.yaml file, explaining what each one does and how you can configure the plugin.

This should be explained in a docs/CONFIGURATION.md file.

feat: authentication using OAuth

Currently, we only have Basic authentication type available to secure the API. There is an OAuth login plugin which allows authentication with several different providers.

It could be valuable to investigate whether or not we can integrate with this plugin to allow authentication of API request using Bearer type and an OAuth access token.

feat: support custom fields in user account

It is possible to define custom fields in a user account in Grav. If you add a custom field to the fields filter list in api.yaml config, then you can return the values of the custom fields in the UserResource response. They will be null if not set.

However, we only allow to set/update specific fields, such as title, fullname, state, access, email, groups, etc.

The UsersHandler class should be extended to allow these custom fields to be set on the UserResource.

feat: install new plugin

Expose an authenticated endpoint, POST /plugins which allows an admin to install a new plugin on the site.

Request Body:

Required fields:

  • id: the "plugin name" as per GPM

They also have the option of providing an attributes field which will be applied after the installation of the plugin. If not provided, then the plugin will use its default configuration.

{
  "id": "{{plugin_name}}",
  "attributes": { 
    // some initial configuration settings 
    "enabled": false
  }
}

feat: add custom API events

The API could trigger custom events, such as:

  • onApiPageGet
  • onApiPageCreate
  • onApiPageUpdate
  • onApiPageDelete
  • onApiUserCreate
  • onApiUnauthorisedRequest

... etc

These could be very useful to allow easy communication back to Grav\Plugin\GravApi, in order to trigger some specific plugin actions after an Api event. Perhaps even for external plugins to hook into, such as the Admin plugin exposes, to allow 3rd party extensions over the API.

For example, onApiPageGet might be a useful hook if you wanted to add a tracking plugin to monitor API traffic, or maybe onApiPageUpdate if you want to bust the cache when a page is updated.

At the moment, the API handles the request and then the plugin immediately calls exit, stopping any further execution by Grav. This would probably need to change, to allow any other plugins to tap into the custom events.

chore: set up continuous integration tooling

Investigate into setting up something like CircleCI or Travis CI to build and validate each PR against the test suite before allowing to merge, in order to help prevent any broken master branch state.

Need to write more tests first though!

docs: add postman collection to docs

Add a postman collection json export file to the docs section, in order to easily be able to share/load all the possible API endpoint requests and their respective configurations.

refactor: move setFilter to Resource class

Perhaps the setFilter function could be moved into the abstract Resource class and made to be generic, so it's not repeatedly defined in all the different resource types, e.g.

protected function setFilter()
{
    $filter = Config::instance()->{$this->getResourceType()}->get->fields;
    
    if (!empty($filter)) {
        $this->filter = $filter;
    }
}

Then would need to adjust mapping so that getResourceType() returns the correct value for the config... currently would return user not users etc

feat: permissions for users and groups by taxonomy

Hi, now if auth: true all users with access can post, patch and delete pages. Is it complicated to provide different permissions for users and groups for page taxonomies? For example, the blogger group can add/edit/delete only pages with {'@taxonomy':{'category': 'blog'}.
Thanks

feat: allow for uploading of media data

Currently, there is no way to upload media such as images/pdfs etc to a page. A separate resource could be useful to separate the media from the page's data. Perhaps an endpoint such as:

  • POST /api/media, or
  • POST /api/images, or
  • POST /api/data

refactor: should config support nested endpoints

The current config setup doesn't easily allow for configuring nested endpoints. For example, if we have POST /api/pages/searches, currently there are only config exposed for the methods for /api/pages. But we don't want to use the POST config, because that gives permissions to allow a user to create a new resource, when a search action is actually reading existing pages data, so it's actually more suitable to be a GET request.

Using a GET config in the code for a POST request is potentially confusing. Perhaps it would be better to rename the endpoint config to be use case (read/create/update/delete) rather than method (get/post/patch/delete).

Or perhaps the config should support nested endpoints within an endpoint config, e.g.

endpoints:
  /pages:
    get: 
      enabled: true
      auth: false
    endpoints:
      /searches:
        post:
          enabled: false 
          auth: false

docs: update project readme

The readme file is currently the default template for a Grav plugin. It needs to be updated with more relevant information.

  • Configuration and setup of plugin
  • Granting user permissions for API usage
  • Roadmap/ desired features
  • More details regarding development environment
  • Warning about using API on your site. Potential security vulnerability etc.
  • Supported version of Grav
  • ... etc.

fix: PageResource test throws exception

The following error message is output when trying to run the PageResourceTest::testGetResourceAttributesReturnsPageData() function:

[UnexpectedValueException] RecursiveDirectoryIterator::__construct(): 
Unable to find the wrapper "theme" - did you forget to enable it when you configured PHP?

refactor: improve validation of Resource filter input

The app pulls a string array from the plugin config, which is editable by the user. This could therefore be malformed and not what is expected. This should be validated first and any unsuitable values should be discarded.

Should the whole filter be discarded, or just the "incorrect" values? Leaning towards retaining a partial filter, rather than returning all Resource attributes if only one filter field is incorrect.

chore: add Zappr config

Add a Zappr config to add extra checks for PRs. This should help standardise contributions' format, if any ever happen.

feat: access role permissions per endpoint/method

It could be nice to allow the ability to specify roles for the API endpoints from within the plugin config.

For example, a user might require the admin.super role in order to be able to use DELETE /pages, but does not require any role to use GET /pages

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.