fiber-backend

command module
v0.0.0-...-9bca149 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 6, 2022 License: MIT Imports: 9 Imported by: 0

README

Backend for a mini selfmade headless CMS using Fiber

Content


Usage

You can run this package on its own by setting the .env accordingly, for exapmle with a Atlas hosted MongoDB Cluster (the .env file variables are used by both the docker-compose and the fiber-backend), but using the docker-compose.yaml is the easiest way to deploy all dependencies on a server.

Follow these steps:

  1. Install docker and docker-compose
  2. Download .env file
    $ sudo wget -O .env https://raw.githubusercontent.com/D-Bald/fiber-backend/main/.env.sample
    
  3. Set the DB_HOST variable in the .env file to the name of the docker service (in this docker-compose.yaml the service is named mongodb). If you use a Atlas hosted MongoDB database, set this variable to ATLAS. Also check environment variables like ports, database name, user and passwor and PLEASE change SECRET and ADMIN_PASSWORD.
  4. Download docker-compose.yaml file
    $ sudo wget -O docker-compose.yaml https://raw.githubusercontent.com/D-Bald/fiber-backend/main/docker-compose.yaml
    
  5. Execute the following commands in the root directory of docker-compose.yaml:
    • To get the containers up and running execute:
      $ docker-compose up -d
      
    • To stop the containers execute:
      $ docker-compose down -v
      

This setup will create and start three docker containers:

The data is persistent over multiple up and down cycles using docker volumes.
Check the database setup with mongo-express on http://localhost:8081.

API

Endpoint Method Authentification required Response Fields* Description
/api GET Health-Check
/api/auth/login POST token, user Sign in with username or email (identity) and password. On success returns token and user.
/api/role GET role Returns all existing roles.
POST ✓ (admin) role Creates a new Role.
/api/role/:id PATCH ✓ (admin) result Updates role with id id.
DELETE ✓ (admin) result Deletes role with id id. Also removes references to this role in user and content type documents.
/api/user GET user Return users present in the users collection.
POST token, user Creates a new user.
Specify the following attributes in the request body: username, email, password, names. On success returns token and user.
/api/user/:id PATCH result Updates user with id id.
If you want to update role, you have to be authenticated with a admin-user.
DELETE result Deletes user with id id.
Specify user´s password in the request body.
/api/contenttypes GET contenttype Returns all content types present in the contenttypes collection.
POST ✓ (admin) contenttype Creates a new content type.
Specify the following attributes in the request body: typename, collection, field_schema.
/api/contenttypes/:id GET contenttype Returns content type with id :id.
PATCH ✓ (admin) result Updates content type with id :id.
DELETE ✓ (admin) result Deletes content type with id :id. Watch out: Also deletes all content entries with this content type.
/api/:content GET content Returns content entries of the content type, where content is the corresponding collection. By convention this should be plural of the typename.
For the previous example: content has to be set to events.
POST ✓ (depends on content type permissions) content Creates a new content entry of the content type, where content is the corresponding collection.
Specify the following attributes in the request body: title (string), published(bool), fields(key-value pairs: field name - field value).
/api/:content/:id PATCH ✓ (depends on content type permissions) result Updates content entry with id id of the content type, where content is the corresponding collection.
DELETE ✓ (depends on content type permissions) result Deletes content entry with id id of the content type, where content is the corresponding collection.

* status and message are returned on every request.

Workflows

Roles

Two roles are initiated out of the box:

{
    "tag":"default",
    "name":"User"
}
{
    "tag":"admin",
    "name":"Administrator"
}

The default role is given any new user. The admin role is used as general access role and on start a new adminUser is created, if no other user with role tag admin is found. By changing the name you can decide how an admin is called and which default role is given any new user.
Warning: Removing these roles or changing the tag causes trouble because user creation will fail due to missing default role and you can loose your last admin access user. On the next start a new admin role and adminUser is created, but this leads to a redundant adminUser and you can not reliably login with real a admin access. This issue can be solved by deleting the adminUser that has not the admin role, but it can be hard to debug.

Just one GET endpoint exists, which returns all roles. There is no use for the data of a singe role.
Example JSON request body:

// POST or PATCH
{
    "tag":"moderator",
    "Name":"Moderator"
}
Create content and content types

The content types event and blogpost are preset and you can start adding entries on those routes (/api/events or /api/blogposts). Events have custom fields description and date whereas blogposts come with description and text. By convention the collection should be plural of the typename. If you want to create a custom content type, first use the /api/contenttypes endpoint, because the /api/:content route is validated by a lookup in the contenttypes collection. The mongoDB collections for new types are created automatically on first content insertion.

The GET Endpoint is not protected by any middleware. POST, PATCH and DELETE endoints for any content are protected and you have to specify the roles that users have to have to perform each method (see example below) in the content types Permissions object. Users with admin role tag can perform any method on any content. Both default contenttypes (event and blogpost) set all method permissions to the default role.

The last attribute for a new content type, field_schema, is a list of key-value pairs specifying name and type of fields, that an content entry of this content type should have.
Exapmle JSON request body:

{
    "typename": "protected-admin-test",
    "collection": "protected-admin-test-entries",
    "permissions": {
        "POST": [
            "Moderator"
        ],
        "PATCH": [
            "Moderator"
        ],
        "DELETE": [
            "Moderator"
        ]
    },
    "field_schema": {
        "text_field": "string"
    }
}

The last attribute for a new content entry, fields is a list of key-value pairs specifying name and value of fields, that should match the field_schema of the corresponding content type. A schema validation is not yet implemented.
Example JSON request body:

{
    "title": "Blogpost Test",
    "published": false,
    "tags": [
        "foo",
        "bar"
    ],
    "fields": {
        "description": "Hello world",
        "date": "2021-04-08T12:00:00+02:00"
    }
}
Update content and content types

To update an array, like tags of content entries or permissions of content types, the whole array has to be sent. On this structure the update behaves more like a PUT method.

To update custom fields of content entries you have to specify it as an object in the request body.
Example JSON request body:

{ "fields": {"description": "foo bar"} }

Preset fields can be reached directly. Example JSON request body:

{
    "tags": ["foo", "bar"],
    "published": true
}
Create users

The admin user adminUser is preset with the password ADMIN_PASSWORD from the .env file in the root direcory of the executable. Anybody can create a new user. The role is automatically set to user.
Example JSON request body:

{
    "username": "TestUser",
    "email": "unique@mail.com",
    "password":"123",
    "names":"names",
}
Update users

A user can edit the own data i.e. username, email, password, names. Every user with role admin can edit any other user and particularly can edit the field role of any user. Roles must be updated as array containing all roles as single strings.
Example JSON request body:

{
    "username": "John Doe",
    "roles": ["User","Moderator"]
}
Query users and content entries by route parameters

To get all Users or all content entries of one content type, just use the bare API GET endpoint (example 1). To search for Users and content entries with certain properties, a query string can be added to the API endpoint. The query string begins with ?. Each search parameter has the structure key=value and is case sensitive. Each document has a unique ID, that can be used to query for a single result (example 2). Multiple parameters are seperated by & (example 3). Custom fields of content entries can be queried directly so don't use dot-notation or similar (example 4). Only the whole field value is matched, so submatches are not supported. Queries for single elements of array fields like 'tags' are possible (example 5). In queries with multiple array elements, the query values currently have to have the same order as in the database and can not be a subset of the stored ones(example 6). Therefore queries with single values are recommended.
Examples:

# 1
/api/events
# 2
/api/user?_id=609273e9f17aa49bcd126418
# 3.
/api/blogposts?title=Title&published=false
# 4.
/api/events?place=home
# 5.
/api/blogposts?tags=foo
# 6.
/api/events?tags=foo,bar

Example 6 currently only returns documents with a full match on tags like:

{ "tags": ["foo", "bar"] }

TODO

  • Fix Issue: Dates cannot be queried, because the + sign in a query string is treated as empty space. Maybe by escaping + if the parameter value is send in ""
  • Add idiomatic Endpoints for common getters and setters like: Set title, set username set names, set password...
  • Implement permission control over user, roles and content types endpoints
  • Issue: standard_init_linux.go:219: exec user process caused: no such file or directory on docker-compose up when using the :latest image created by workflow CI on GitHub Actions => workflow currently disabled and a locally on an ubuntu server built image is used in the docker-compose.yaml.
  • Implement file upload
  • Validate field_schema on content entry creation (https://docs.mongodb.com/manual/core/schema-validation/)

Thanks to...

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL