A PHP microservice for helping know who's who

Overview

Identity service

Identity is a microservice and API (Application Programming Interface) used for handling everything to do with who's who. For now the focus is on donors and making their journey smoother by avoiding the need to re-enter details.

Bootstrapped with Slim Skeleton, this PHP app uses Slim Framework 4 along with several other PHP libraries used across the Big Give.

Run the app

You should usually use Docker to run the app locally in an easy way, with the least possible configuration and the most consistency with other runtime environments - both those used when the app is deployed 'for real' and other developers' machines.

Prerequisites

In advance of the first app run:

  • get Docker
  • copy .env.example to .env and change any values you need to.

Start the app

To start the app and its dependency (db) locally:

docker-compose up -d app

First run

To get PHP dependencies and an initial data in structure in place, you'll need to run these once:

docker-compose exec app composer install
docker-compose exec app composer doctrine:delete-and-recreate

If dependencies change you may occasionally need to re-run the composer install.

Once it's up

Check the Status endpoint works:

Run unit tests

Once you have the app running, you can test with:

docker-compose exec app composer run test

When run with a coverage driver (e.g. Xdebug enabled by using thebiggive/php:dev-8.1), this will save coverage data to ./coverage.xml.

Linting is run with

docker-compose exec app composer run lint:check

To understand how these commands are run in CI, see the CircleCI config file.

API

Actions are annotated with swagger-php-ready doc block annotations.

Generate OpenAPI documentation corresponding to your local codebase with:

docker-compose exec app composer run docs

Once the app is more complete, we will copy/paste and publish generated docs to their live home on SwaggerHub after any changes.

Typical registration flow

So that new donors may have even their first, pre-registration donation associated with a Stripe Customer, it's necessary for us to know a Stripe Customer ID as soon as we want a Payment Intent. Because we take donation amount first, this means the Customer is essentially anonymous on creation.

This means that registration when the donor decides to set a password typically has 3 calls:

  1. Person\Create (precedes all initiated donations)
  2. Person\Update with no password (alongside all completed donations)
  3. Person\Update with a password (when the donor sets one after donating)

JWT types

Tokens can currently be issued with the following subject ("sub") claims:

  1. Some "person_id" and "complete" false: short-term (1 day) token permitting only updating a person's core details. Issued upon creation of a placeholder Person and permits setting identifying information and a password for them.
  2. Some "person_id" and "complete" true: – 8-day token issued upon password authentication, allowing read + write access to everything for a complete Person record including saved payment methods. (This doesn't include full card numbers or data that would allow card use outside Big Give.)

Service dependencies

It's expected that the a MySQL database will be a dependency. In live environments, MatchBot's RDS database will be used (with a distinct schema) but this is not configured yet.

Scripts and Docker

Scripts are defined in composer.json. It's not currently anticipated that any will be designed for Production use for this app, but there are scripts for testing and linting, and many that may help with shortcuts to common Doctrine and database migration developer tasks.

Code structure

The Identity service's code is bootstrapped based on Slim Skeleton, and elements like the error & shutdown handlers and much of the project structure follow its conventions.

Generally this structure follows normal conventions for a modern PHP app:

  • Dependencies are defined (only) in composer.json, including PHP version and extensions
  • Source code lives in src
  • PHPUnit tests live in tests, at a path matching that of the class they cover in src
  • Slim configuration logic and routing live in app

Configuration in app

  • dependencies.php: this sets up dependency injection (DI) for the whole app. This determines how every class gets most stuff it needs to run. DI is super powerful because of its flexibility (a class can say I want a logger and not worry about which one), and typically avoids objects being created that aren't actually needed, or being created more times than needed. Both of these files work the same way - they are only separate for cleaner organisation.

    We use Slim's PSR-11 compliant Container with PHP-DI. There's an overview here of what this means in the context of Slim v4.

    With PHP-DI, we can also reduce some of our explicit depenendency definitions using autowiring.

  • `repositories.php: this sets up entity repositories that the app will use.

  • routes.php: this small file defines every route exposed on the web, and every authentication rule that applies to them. The latter is controlled by PSR-15 middleware and is very important to keep in the right place!

    Slim uses methods like get(...) and put(...) to hook up specific HTTP methods to classes that should be invoked. Our Actions' boilerplate is set up so that when the class is invoked, its action(...) method does the heavy lifting to serve the request.

    add(...) is responsible for adding middleware. It can apply to a single route or a whole group of them. Again, this is how we make routes authenticated. Modify with caution!

  • settings.php: you won't normally need to do much with this directly because it mostly just re-structures environment variables found in .env (locally) or env vars loaded from a secrets file (on ECS), into formats expected by classes we feed config arrays.

Important code

The most important areas to explore in src are:

  • Application\Actions: all classes exposing APIs to the world. Anything invoked directly by a Route should be here.

Deployment

Deploys are rolled out by CirlceCI, as configured here, to an ECS cluster, where instances run the app live inside Docker containers.

As you can see in the configuration file,

  • develop commits trigger deploys to staging and regression environments; and
  • main commits trigger deploys to production

These branches are protected on GitHub and you should have a good reason for skipping any checks before merging to them!

ECS runtime containers

ECS builds have two additional steps compared to a local run:

  • during build, the Dockerfile adds the AWS CLI for S3 secrets access, pulls in the app files, tweaks temporary directory permissions and runs composer install. These things don't happen automatically with the base PHP image as they don't usually make sense for local runs;
  • during startup, the entrypoint scripts load in runtime secrets securely from S3 and ensure some cache directories have appropriate permissions. This is handled in the two .sh scripts in deploy - one for web instances and one for tasks.

Phased deploys

Other AWS infrastructure includes a load balancer, and ECS rolls out new app versions gradually to try and keep a working version live even if a broken release is ever deployed. Because of this, new code may not reach all users until about 30 minutes after CircleCI reports that a deploy is done. You can monitor this in the AWS Console.

When things are working correctly, any environment with at least two tasks in its ECS Service should get new app versions with no downtime.

Comments
  • Id 31 - static analysis

    Id 31 - static analysis

    Add static analysis with Psalm to the build.

    We'll only really feel the impact of this and be able to assess how it helps & hinders us as part of whatever other work we do in this codebase with Psalm in place.

    opened by bdsl 3
  • Supress log output and deprecations in PhpUnit tests

    Supress log output and deprecations in PhpUnit tests

    Now successful test output fits easily on the screen for easy reading:

    barney@barney-l-xps:~/projects/identity$ vendor/bin/phpunit
    PHPUnit 9.5.25 #StandWithUkraine
    
    Warning:       No code coverage driver available
    
    ................................................................. 65 / 73 ( 89%)
    ........                                                          73 / 73 (100%)
    
    Time: 00:00.739, Memory: 30.00 MB
    
    OK (73 tests, 325 assertions)
    
    opened by bdsl 2
  • ID-29 – fix pre-persist check

    ID-29 – fix pre-persist check

    When an existing Person has a password but the new Person to patch doesn't.

    Also fix a runtime crash typo when the LogicException is correctly thrown.

    opened by NoelLH 1
  • ID-11 – Update registration emails

    ID-11 – Update registration emails

    • Move the object-related mailing support to the PersonRepository
    • Call the new helper when an Update leads to a password being set for the first time
    • Tighten up Person\Update tests to more realistically reflect the newly-set password scenario so we can effectively test the new logic there
    opened by NoelLH 1
  • ID-7 – first steps adding saved card metadata

    ID-7 – first steps adding saved card metadata

    This is almost certainly redundant now and I've closed the linked Jira issue. Just wanted to push this somewhere in case we change plans before I delete the file locally!

    Making a draft PR to keep track of this and remember to delete the branch later, assuming we don't hit snags with the new approach.

    opened by NoelLH 1
  • ID-18 – split registration into (anonymous) Person create and completion steps

    ID-18 – split registration into (anonymous) Person create and completion steps

    • Make registration multi-step and document how it works in the readme
    • Update models + actions accordingly
    • Add Stripe Customer create + updates
    • Make Person validation and update auth context-sensitive

    This approach now uses validation groups to conditionally require fields as we build up the Person data.

    More at https://symfony.com/doc/current/validation/groups.html

    opened by NoelLH 1
Owner
The Big Give
The Big Give
A DDD microservice did in laravel, to test infrastructure

A DDD microservice did in laravel, to test infrastructure

pegons 3 Jul 8, 2022
Mailing Microservice - My solution for Moroccan PHPers's February 2022 Challenge

Mailing Microservice Solution for Moroccan PHPers's February 2022 Challenge by Rabyâ Raghib ([email protected]). It mainly consists of: a php app th

Rabyâ Raghib 1 Aug 11, 2022
The Current US Version of PHP-Nuke Evolution Xtreme v3.0.1b-beta often known as Nuke-Evolution Xtreme. This is a hardened version of PHP-Nuke and is secure and safe. We are currently porting Xtreme over to PHP 8.0.3

2021 Nightly Builds Repository PHP-Nuke Evolution Xtreme Developers TheGhost - Ernest Allen Buffington (Lead Developer) SeaBeast08 - Sebastian Scott B

Ernest Buffington 7 Aug 28, 2022
A sampling profiler for PHP written in PHP, which reads information about running PHP VM from outside of the process.

Reli Reli is a sampling profiler (or a VM state inspector) written in PHP. It can read information about running PHP script from outside of the proces

null 272 Dec 22, 2022
PHP Meminfo is a PHP extension that gives you insights on the PHP memory content

MEMINFO PHP Meminfo is a PHP extension that gives you insights on the PHP memory content. Its main goal is to help you understand memory leaks: by loo

Benoit Jacquemont 994 Dec 29, 2022
A sampling profiler for PHP written in PHP, which reads information about running PHP VM from outside of the process.

Reli Reli is a sampling profiler (or a VM state inspector) written in PHP. It can read information about running PHP script from outside of the proces

null 258 Sep 15, 2022
A multithreaded application server for PHP, written in PHP.

appserver.io, a PHP application server This is the main repository for the appserver.io project. What is appserver.io appserver.io is a multithreaded

appserver.io 951 Dec 25, 2022
Easy to use utility functions for everyday PHP projects. This is a port of the Lodash JS library to PHP

Lodash-PHP Lodash-PHP is a port of the Lodash JS library to PHP. It is a set of easy to use utility functions for everyday PHP projects. Lodash-PHP tr

Lodash PHP 474 Dec 31, 2022
A PHP 5.3+ and PHP 7.3 framework for OpenGraph Protocol

Opengraph Test with Atoum cd Opengraph/ curl -s https://getcomposer.org/installer | php php composer.phar install --dev ./vendor/atoum/atoum/bin/atoum

Axel Etcheverry 89 Dec 27, 2022
A status monitor for Elite Dangerous, written in PHP. Designed for 1080p screens in the four-panel-view in panel.php, and for 7 inch screens with a resolution of 1024x600 connected to a Raspberry Pi.

EDStatusPanel A status monitor for Elite Dangerous, written in PHP. Designed for 1080p screens in the four-panel-view in panel.php, and for 7 inch scr

marcus-s 24 Oct 4, 2022
🐘 A probe program for PHP environment (一款精美的 PHP 探針, 又名X探針、劉海探針)

Simplified Chinese | 简体中文 Traditional Chinese(Taiwan) | 正體中文(臺灣) Traditional Chinese(Hong Kong) | 正體中文(香港) Japanese | 日本語 ?? X Prober This is a probe

Km.Van 1.2k Dec 28, 2022
PHP Text Analysis is a library for performing Information Retrieval (IR) and Natural Language Processing (NLP) tasks using the PHP language

php-text-analysis PHP Text Analysis is a library for performing Information Retrieval (IR) and Natural Language Processing (NLP) tasks using the PHP l

null 464 Dec 28, 2022
PHP generics written in PHP

PHP generics written in PHP Require PHP >= 7.4 Composer (PSR-4 Autoload) Table of contents How it works Quick start Example Features Tests How it work

Anton Sukhachev 173 Dec 30, 2022
PHP exercises from my course at ETEC and some of my own play-around with PHP

etec-php-exercises PHP exercises from my course at ETEC and some of my own play-around with PHP Translations: Português (BR) Projects Project Descript

Luis Felipe Santos do Nascimento 6 May 3, 2022
GitHub action to set up PHP with extensions, php.ini configuration, coverage drivers, and various tools.

GitHub action to set up PHP with extensions, php.ini configuration, coverage drivers, and various tools.

Shivam Mathur 2.4k Jan 6, 2023
php-echarts is a php library for the echarts 5.0.

php-echarts 一款支持Apache EChart5.0+图表的php开发库 优先ThinkPHP5/6的开发及测试。 Apache EChart5.0已经最新发布,在视觉效果、动画效果和大数据展示方面已经远超之前的版本; 故不考虑EChart5.0之前版本的兼容问题;建议直接尝试5.0+

youyiio 5 Aug 15, 2022
Minimalist PHP frame for Core-Library, for Developing PHP application that gives you the full control of your application.

LazyPHP lightweight Pre-Made Frame for Core-library Install Run the below command in your terminal $ composer create-project ryzen/lazyphp my-first-pr

Ry-Zen 7 Aug 21, 2022
Zilliqa PHP is a typed PHP-7.1+ interface to Zilliqa JSON-RPC API.

Zilliqa PHP is a typed PHP-7.1+ interface to Zilliqa JSON-RPC API. Check out the latest API documentation. Add library in a composer.json file.

Patrick Falize 6 Oct 7, 2021
churn-php is a package that helps you identify php files in your project that could be good candidates for refactoring

churn-php Helps discover good candidates for refactoring. Table of Contents What Is it? Compatibility How to Install? How to Use? How to Configure? Si

Bill Mitchell 1.3k Dec 22, 2022