Sign inSign up

berlingskemedia/bpp_api

By berlingskemedia

•Updated almost 4 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

almost 4 years ago

docker pull berlingskemedia/bpp_api