GithubHelp home page GithubHelp logo

ed-g / pg_schema_dataclip Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 0.0 52 KB

Minimal dataclip-like based on a postgres schema: each view in the schema is published as a web page table.

License: GNU General Public License v3.0

PHP 41.99% JavaScript 58.01%

pg_schema_dataclip's Introduction

pg_schema_dataclip

Minimal dataclip-like based on a postgres schema: each view in the schema is published as a web page table.

To test-run:

php -S localhost:8080 -t public/

Configuration

The dataclip.php program takes parameters from environment variables, to make it easy to run under such things as Docker.

Database connection

PG_SCHEMA_DATACLIP_CONNECTION_STRING connection string (run this in the shell before starting dataclip):

 export PG_SCHEMA_DATACLIP_CONNECTION_STRING="user='dataclip_user' host='pghost' dbname='pgdatabase' password='pgpassword' sslmode='require'

In-database request logging

If you would like to enable in-database logging, set the PG_SCHEMA_DATACLIP_ACCESS_LOG to any value.

$ export PG_SCHEMA_DATACLIP_ACCESS_LOG="on"

And create an access-log table with INSERT access to your dataclip_user.

 SET search_path = dataclip_schema;
 CREATE TABLE dataclip_schema."##PG_SCHEMA_DATACLIP_ACCESS_LOG##" (
     viewname text,
     request_time timestamptz default now(),
     access_allowed boolean
 );
 GRANT INSERT on dataclip_schema."##PG_SCHEMA_DATACLIP_ACCESS_LOG##" to dataclip_user;

Aside on configuration table names

Note that all configuration table include uppercase letters and # in their names, in order to help prevent them from accidentally being exposed to the web.

Dataclip views may only use lowercase letters [a-z], digits [0-9], and underscores (_) in their names.

Postgres will typically require double quotes to refer to configuration table names.

Database User

The database user (referred to as dataclip_user, but it could be any postgres user) should have as few privileges as possible.

You'll want to use a low setting for its connection limit, so it is less likely to create a denial of service against your database if it gets spammed with requests. Running through a proxy like pgbouncer might also be a good idea.

ALTER USER dataclip_user CONNECTION LIMIT 2;

USAGE on a single schema (referred to as dataclip_schema, but it could be any Postgres schema)

GRANT USAGE ON SCHEMA dataclip_schema TO dataclip_user;

Granting access to dataclip views

dataclip_user should have SELECT permissions for tables and views in the dataclip_schema only. There are at least three options for how to manage this.

Whenever new views are created, grant access normally.

    CREATE view dataclip_schema.foo AS select 'bar' AS bar;
    GRANT SELECT ON dataclip_schema.foo TO dataclip_user;

Create views, then grant access to everything in the schema.

You'll have to re-run the "GRANT SELECT ON ALL TABLES IN SCHEMA ..." command each time new views are created.

    CREATE view dataclip_schema.foo AS select 'bar'  AS bar;
    CREATE view dataclip_schema.baz AS select 'quux' AS quux;
    GRANT SELECT ON ALL TABLES IN SCHEMA dataclip_schema TO dataclip_user;

Use the handy postgres "ALTER DEFAULT PRIVILEGES" command

ALTER DEFAULT PRIVILEGES will grant access in the future whenever views are created.

privileged_user is the user you'll typically be using to CREATE the views.

dataclip_user is the user used to SELECT from the views and show them on the web.

    ALTER DEFAULT PRIVILEGES 
        FOR ROLE privileged_user
        IN SCHEMA dataclip_schema 
        GRANT SELECT ON TABLES TO dataclip_user;

Access Cookies

Views listed in ##PG_SCHEMA_DATACLIP_ACCESS_COOKIES## have mild security in the form of an access_cookie. Multiple access_cookies may be listed for a view, in which case any of the access_cookies will allow access.

If either there are no access_cookies listed for a view, then the view is default public.

Access cookies may use lowercase letters [a-z], digits [0-9], dash -, or underscore _.

Note: the access_cookie 'public' is special and allows public access to a view.

I find UUIDs to be convenient for access_cookies, but any string could be used.

Creating a table to store access_cookies

    /* Or you could use the "uuid-ossp" EXTENSION, in which case you'd want
       to use uuid_generate_v4() below, instead of gen_random_uuid() */
    CREATE EXTENSION pgcrypto; 
    
    SET search_path = dataclip_schema;

    CREATE TABLE "##PG_SCHEMA_DATACLIP_ACCESS_COOKIES##" (
        viewname      text not null, 
        access_cookie text not null default gen_random_uuid(),
        PRIMARY KEY (viewname, access_cookie)
    );

    GRANT SELECT ON "##PG_SCHEMA_DATACLIP_ACCESS_COOKIES##" to dataclip_user;

Example access_cookie entries

Public entries

Views are public by default, so inserting entries with a 'public' access-cookie is redundant, but accepted.

   INSERT INTO 
       "##PG_SCHEMA_DATACLIP_ACCESS_COOKIES##" 
       (viewname, access_cookie) values ('foo', 'public');

Private entries

Using default value of gen_random_uuid()
    INSERT INTO 
        "##PG_SCHEMA_DATACLIP_ACCESS_COOKIES##" 
        (viewname) values ('bar')
    RETURNING viewname, access_cookie;
Using an UUID-format string.
    INSERT INTO 
        "##PG_SCHEMA_DATACLIP_ACCESS_COOKIES##" 
        (viewname, access_cookie) values ('baz', '64ee7483-ae4c-4138-8a94-6fb09adefe3b');
Build an access-url using the return value from INSERT
WITH
new_cookie AS (
    INSERT INTO
        "##PG_SCHEMA_DATACLIP_ACCESS_COOKIES##" (viewname )
        VALUES ('foo')
        RETURNING viewname, access_cookie
)
SELECT format('dataclip.php?viewname=%s&access_cookie=%s', viewname, access_cookie) FROM new_cookie

/* Gives: 'dataclip.php?viewname=foo&access_cookie=0a93f68f-7e01-47d6-bb26-9bd855eaba92' */

pg_schema_dataclip's People

Contributors

ed-g avatar

Watchers

 avatar  avatar

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.