Sign inSign up

berlingskemedia/bpp_api

By berlingskemedia

Updated over 3 years ago

Image
0

10K+

berlingskemedia/bpp_api repository overview

BPP API

Berlingske Permissions Processor API - is an API app that acts as a backend for the BPP admin and forwards the Gigya notifications to the AWS SQS for BPP worker to be consumed.

Via the BPP API it's possible to:

  • View and modify the access rules, that translates ARIA titleDomain and accessFeature into acces roles.
  • View and modify the scopeaccess, that defines how access roles are stored in BPC.
  • View and modify the rules for access of one ARIA account is granted to multiple Gigya accounts eg. B2B customers.
  • Recieve notifications from Gigya, to include or exclude users from a group access, and check for email changes.

Messages must be send to the BPP Worker in case:

  • A user's access roles must be re-calculated in BPC.
  • An account's email must be updated in ARIA.

overview

Terminology

Scope

Scope is a BPC concept, and is this solution it is usually berlingske, bt and weekendavisen.

Role

A role is a true/false value that will grant access to a given product. E.g. bdk_paywall will grant access to article behind the paywall on www.berlingske.dk.

A role exists in a scope.

Access rules:

Access rules are a mapping between accessFeature+titleDomain, granted by ARIA based on the account master plan, and the scope:roles, that is set in BPC.

  • There can only exist one access rule per accessFeature+titleDomain. I.e. the combination of accessFeature+titleDomain is unique for the entire collection.
  • Each access rule can have multiple scope:roles.

Each time a user's permissions are calculated, the accountFeatureList from Aria is used to find matching access rules. For each match

Scope access:

Scope access is the total list of scope:roles, that BPP will set in the access object BPC for a given user, each time permissions are calculated. This means that all roles in all scopes will be set to either true or false, depending on the access rules of the user. If a user's accountFeatureList has a matching access rule, the value will be true true. Otherwise false.

Company:

A B2B company or group that is allowed to share one access granted to ARIA account between multiple Gigya accounts.

Example of permissions calculation

Consider scope access:

[
    {
      "scope": "weekendavisen",
      "roles": [ "wea_paywall", "waa_epaper" ]
    },
    {
      "scope": "berlingske",
      "roles": [ "bdk_paywall", "bdk_apps" ]
    }
  ]

and consider access rules:

[
  {
    "accessFeature": "WEB/APP",
    "eligibleForSharing": false,
    "titleDomain": "www.weekendavisen.dk",
    "access": {
      "weekendavisen": [ "wea_paywall" ]
    }
  },
  {
    "accessFeature": "E-PAPER",
    "eligibleForSharing": false,
    "titleDomain": "www.weekendavisen.dk",
    "access": {
      "weekendavisen": [ "waa_epaper" ]
    }
  },
]

Consider a user's accountFeatureList (subscription includes access to WEA web but not E-paper nor any BER):

[
  {
    "accessFeature": "WEB/APP",
    "eligibleForSharing": false,
    "titleDomain": "www.weekendavisen.dk"
  }
]

The resulting permissions access-object for each scope will be:

# /berlingske
{
  "bdk_paywall": false,         // <-- false because the role is listed in scope access but not matched to a rule or accountFeatureList 
  "bdk_apps": false,            // <-- false because the role is listed in scope access but not matched to a rule or accountFeatureList
}


# /weekendavisen
{
  "waa_epaper": false,          // <-- false because the role is listed in scope access but not matched to a rule or accountFeatureList
  "wea_paywall": true           // <-- true because the role is listed in scope access and also matched to a rule in the user's accountFeatureList
}

Gigya notifications

For each unique UID in the events within a Gigya notifications a accounts.getAccountInfo request to Gigya is made, to retrieve the account email.

accountCreated:

  • Look in companies for matching email masks.
  • If found:
    • Add user (Gigya UID and email) to list over company users. Marks as "added by system".
    • Produce an updatePermissions message to BPP Worker.

accountUpdated:

  • Compare the email from Gigya to the email stored in MongoDB on the account (Gigya UID = ariaAccountID).

    • If they differ, produce and updateEmail message to BPP Worker.
  • Find companies where the Gigya UID is in the users-lists and "added by system".

    • If found, check if email is still valid based on the email masks:
      • If email is still valid, ignore this loop.
      • If email is no longer valid:
      • Remove the user from the company.
      • Produce an updatePermissions message to BPP Worker.
  • Execute the logic from "accountCreated" to find and create any new memberships on a company.

accountLoggedIn

  • Execute the logic from "accountCreated" to find and create any new memberships on a company.

accountDeleted

  • Remove the user, if Gigya UID is found on any company.

API

The authorization header must be a Hawk header generated using a BPC Ticket.

[GET /api/accessrules]

Query:

  • accessFeature
  • titleDomain

Authorization:

  • entity: 'user'
  • scope : 'role:{app}:accessrules:reader', 'role:{app}:accessrules:admin'
[POST /api/accessrules]

Payload:

  • accessFeature
  • titleDomain
  • access ({ scope: [ "role_a", "role_b" ] })

Authorization:

  • entity: 'user'
  • scope : 'role:{app}:accessrules:admin'
[DELETE /api/accessrules/{_id}]

Authorization:

  • entity: 'user'
  • scope : 'role:{app}:accessrules:admin'

Deletes the accessrules.

[GET /api/scopeaccess]

Query:

  • scope
  • role

Authorization:

  • entity: 'user'
  • scope : 'role:{app}:accessrules:admin'
[POST /api/scopeaccess]

Payload:

  • scope
  • role: ([ "role_a", "role_b" ])

Authorization:

  • entity: 'user'
  • scope : 'role:{app}:accessrules:admin'
[DELETE /api/scopeaccess/{_id}]

Authorization:

  • entity: 'user'
  • scope : 'role:{app}:accessrules:admin'

Deletes the scope access if it's not in use in any access rule.

[GET /api/companies/access-rules]
[GET /api/companies/access-rules/www.berlingske.dk]

example return: [ { cid: '5e5e18e75f1cac21d79eec35', title: 'Company 6', ip_filter: [ "119.184.136.196" ], roles: [ 'bdk_paywall', 'biz_paywall', 'bdk_apps', 'bma_epaper' ] } ]

[POST /api/companies]

TODO

[GET /api/companies]

TODO

[GET /api/companies/{id}]

TODO

[PUT /api/companies/{id}]

TODO

[POST /api/companies/{id}/users]

TODO

[GET /api/planinstances

TODO

[GET /api/planinstances/{id}

TODO

[PUT /api/planinstances/{id}

TODO

Development

Install

Just simply use

npm install

Environment variables

The worker uses these env vars:

Database connection
  • MONGODB_HOST
  • MONGODB_PORT
  • MONGODB_USER
  • MONGODB_PASSWORD
  • MONGODB_NAME
  • MONGODB_SSL
  • MONGODB_REPLICA_SET
BPC
  • BPC_APP_ID - BPC application name/id
  • BPC_APP_KEY - BPC application key
  • BPC_URL
AWS SQS
CORS SETTINGS

You can put the vars into .sh file and run . config.sh && npm start ``

GIGYA

// Gigya configuration. GIGYA_DC=eu1 GIGYA_HOSTNAMEgigya.com GIGYA_PROTOCOL=https:// GIGYA_API_KEY || GIGYA_APP_KEY GIGYA_USER_KEY GIGYA_SECRET_KEY GIGYA_REQUEST_TIMEOUT_MS=2000;

MongoDB Indexes

See BPP Worker README Indexes

Start

npm start     // Starts the worker
npm run dev   // Starts the worker and restarts on source changes

Test

npm test                                      // Runs the tests
node node_modules/@hapi/lab/bin/lab -vd       // Shows test ids
node node_modules/@hapi/lab/bin/lab -i <id>   // Runs single test with id

Alternative, install package $hapi/lab globally, and the lab commands can be shortened to lab -i <id>.

Set up locally

make run

to stop containers
make stop

Development with docker

Prepare .env file

cp ./.env.dev ./.env

Run db:
docker-compose up --build mongo1 mongo2 mongo3
Config db:
make config
Run app:
docker-compose up --build bpp_api
Fill mongo db
docker exec --env MONGODB_HOST=mongo1 -it bpp_api node -e "const helpers = require('./test/helpers'); helpers.MongoDB.fill()"
Connect to db
docker exec -it mongo1 mongo
Run tests in docker
docker exec --env MONGODB_HOST=mongo1 --env MONGODB_NAME=bpp_testing -it bpp_api npm test

Tag summary

Content type

Image

Digest

sha256:19d857b0e

Size

107.3 MB

Last updated

over 3 years ago

docker pull berlingskemedia/bpp_api