FAQ | This is a LIVE service | Changelog

Skip to content
Commits on Source (16)
# This file lists source files which should be excluded from the automatically generated reference
# documentation. It is in .gitignore format.
# Any Python files shipped as part of the documentation itself.
docs/
# Django migrations
*/migrations/
# Any tests and test-related files.
*/tests/
*/test/
test_*.py
conftest.py
# Standard Django files which are not interesting enough to document.
manage.py
wsgi.py
asgi.py
# Gunicorn configuration.
gunicornconf.py
# Generated code
generated/
......@@ -28,3 +28,4 @@ max_line_length=99
[*.md]
indent_style=space
indent_size=2
max_line_length=99
include:
- local: "/.gitlab/webapp.gitlab-ci.yml"
# OpenAPI client generation templates. Destined for the common ci-templates repo.
- local: "/.gitlab/openapi-generator.gitlab-ci.yml"
# Local customisations for OpenAPI generation.
- local: "/.gitlab/openapi-generator-local.gitlab-ci.yml"
# Local customisations for documentation deneration.
- local: "/.gitlab/docs-local.gitlab-ci.yml"
# *REPOSITORY LOCAL* specialisation of the mkdocs-based documentation template.
variables:
# We ensure that the docs-related dependencies are in the docs poetry group.
MKDOCS_POETRY_GROUP: docs
# Both mkdocs:test and pages need the generated OpenAPI clients to be present in the build
# artefacts. As such, override the stage and needs config for these jobs to make sure they run at
# the right time.
#
# They also need the generated client documentation adding to the generated documentation paths
# after the fact so add a custom "after_script" to the mkdocs:test and pages jobs.
.move:client:docs:
after_script:
- rm -rf public/clients
- mv "$OPENAPI_GENERATOR_DOCS_ARTIFACT_DIR" "public/clients"
mkdocs:test:
needs: null
stage: production
after_script:
- !reference [".move:client:docs", after_script]
pages:
needs: null
stage: production
after_script:
- !reference [".move:client:docs", after_script]
......@@ -9,6 +9,19 @@ variables:
# configuration. We set these here explicitly so that we can curate the naming of the release
# assets.
OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH: openapi.yaml
OPENAPI_GENERATOR_PACKAGE_ARTIFACT_DIR: clients
# We put source artefacts in "generated" so that we don't try to include them in the
# auto-generated project documentation. The "generated" directory is present in .gitignore and so
# will be ignored by the mkdocs config which looks for code.
OPENAPI_GENERATOR_SOURCE_ARTIFACT_DIR: generated/openapi
# By default, OpenAPI generation uses the GitLab project name for the API client packages. In our
# case our project name is not very descriptive and so we override the generated package names.
OPENAPI_GENERATOR_PACKAGE_NAME: activate-account
# Python package names cannot contain "-".
OPENAPI_GENERATOR_PYTHON_URLLIB3_PACKAGE_NAME: activate_account
# We do not ship the OpenAPI schema in the repository and so the openapi:schema job needs to be
# extended to create the schema.
......
# Reusable template for generating API clients from an OpenAPI schema.
#
# See the openapi-generator.md file in this directory for detailed usage information.
#
# This template is intended to be included in the common pipeline and so follows the common pipeline
# rules:
#
# - No jobs are added unless triggered explicitly or via the presence of a special file.
# - All jobs can be disabled if incorrectly triggered.
# - All "public" CI variables are namespaced to avoid collisions.
# - All build artefacts are added to a configurable directory to allow customisation if that
# directory conflicts with one in the repository.
#
# This template requires the Auto DevOps stages.
variables:
# Location of the OpenAPI schema file within the repository.
OPENAPI_GENERATOR_SCHEMA_PATH: "openapi.yaml"
# Location of various job artefacts. These will always be relative to $CI_PROJECT_DIR.
OPENAPI_GENERATOR_ARTIFACT_DIR: "openapi"
OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH: $OPENAPI_GENERATOR_ARTIFACT_DIR/schema.yml
OPENAPI_GENERATOR_SCHEMA_VERSION_ARTIFACT: $OPENAPI_GENERATOR_ARTIFACT_DIR/schema-version
# Specify Docker images used by jobs.
OPENAPI_GENERATOR_YQ_IMAGE: mikefarah/yq:4
OPENAPI_GENERATOR_OPENAPI_GENERATOR_IMAGE: openapitools/openapi-generator-cli:v7.10.0
# Ensure that the schema is present as the $OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH artefact. The
# default behaviour is to copy the file specified by $OPENAPI_GENERATOR_SCHEMA_PATH but the job can
# be extended for more complex behaviour or dynamically generated schema.
openapi:schema:
stage: build
needs: []
before_script:
# Ensure that the directory which is to contain the schema exists.
- mkdir -p $(dirname "$OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH")
script:
# The default behaviour is to copy the schema file to the artifact directory.
- cp "$OPENAPI_GENERATOR_SCHEMA_PATH" "$OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH"
artifacts:
paths:
- $OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH
# When extending this job, rules which *disable* jobs should be included *above* these rules.
# Rules which *enable* the job should be included *below* them.
rules:
# Never run any OpenAPI generate jobs if OPENAPI_GENERATOR_DISABLED is set.
- if: $OPENAPI_GENERATOR_DISABLED
when: never
# If no API specification is provided, never run.
- if: ($OPENAPI_GENERATOR_SCHEMA_PATH == null) || ($OPENAPI_GENERATOR_SCHEMA_PATH == "")
when: never
# If an OpenAPI spec is present in the repository, use it.
- if: $OPENAPI_GENERATOR_SCHEMA_PATH
exists:
paths:
- $OPENAPI_GENERATOR_SCHEMA_PATH
# Finally, allow OpenAPI generation to be explicitly enabled if desired.
- if: $OPENAPI_GENERATOR_ENABLED
# Extract the version from the OpenAPI schema. This is required by some generator jobs as some
# generator templates do not respect the version set in the schema. The version is written to
# $OPENAPI_GENERATOR_SCHEMA_VERSION_ARTIFACT. Note that even generators which support reading the
# version from the schema should respect the artefact generated by this job since it provides a
# customisation point to override the package version if needed.
openapi:schema:version:
stage: build
needs: ["openapi:schema"]
image:
name: $OPENAPI_GENERATOR_YQ_IMAGE
entrypoint: [""]
before_script:
- mkdir -p $(dirname "$OPENAPI_GENERATOR_SCHEMA_VERSION_ARTIFACT")
script:
- yq -r ".info.version" "$OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH" >"$OPENAPI_GENERATOR_SCHEMA_VERSION_ARTIFACT"
artifacts:
paths:
- $OPENAPI_GENERATOR_SCHEMA_VERSION_ARTIFACT
rules:
- !reference ["openapi:schema", rules]
# Template CI job for running openapi-generator.
.openapi:generator-cli:
image:
name: $OPENAPI_GENERATOR_OPENAPI_GENERATOR_IMAGE
entrypoint: [""]
variables:
# Customise how openapi-generator-cli is run.
OPENAPI_GENERATOR_CMD: "/usr/local/bin/docker-entrypoint.sh"
rules:
- !reference ["openapi:schema", rules]
# Validate the OpenAPI schema.
openapi:schema:validate:
extends: ".openapi:generator-cli"
stage: test
needs: ["openapi:schema"]
script:
- |-
$OPENAPI_GENERATOR_CMD validate \
--input-spec "$OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH" \
--recommend
<!-- This file is being drafted here ahead of being merged into the guidebook. -->
# OpenAPI client generation
This document describes the use of the OpenAPI generator template. The OpenAPI generator template is
intended to be included in the "common" pipeline and so will not add any jobs to the pipeline unless
specifically triggered.
## Basic use
Add a file named `openapi.yaml` to the root of your repository with the OpenAPI schema in it. This
will trigger a run of the OpenAPI client generator. No additional CI configuration is needed.
If you schema is stored in a different file, the `OPENAPI_GENERATOR_SCHEMA_PATH` CI variable may be
set to override the schema location. The variable should be set to a path relative to the repository
root which points to the schema file.
## Generating the schema in CI
If you generate your OpenAPI schema dynamically, you need to explicitly enable OpenAPI client
generation by setting the `OPENAPI_GENERATOR_ENABLED` variable. Additionally you'll need to override
the `openapi:schema` job to generate your schema and write it to the path stored in the
`OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH` variable.
For example:
```yaml
# .gitlab-ci.yml
variables:
# We need to explicitly enable the OpenAPI generation since we don't have an openapi.yaml file in
# the root of our repository which would otherwise signal that.
OPENAPI_GENERATOR_ENABLED: "1"
# We do not ship the OpenAPI schema in the repository and so the openapi:schema job needs to be
# overridden to use our schema generation command.
openapi:schema:
script:
- my-schema-generator --output=$OPENAPI_GENERATOR_SCHEMA_ARTIFACT_PATH
```
Not that the existing `openapi:schema` job's `before_script` ensures that the directory containing
that path exists and so you do not need a `mkdir` or equivalent.
## CI variables
The following variables can be set to change the behaviour of the CI template.
|Variable|Default|Description|
|-|-|-|
|`OPENAPI_GENERATOR_ENABLED`|*unset*|Set to non-empty value to *enable* OpenAPI client generation if not otherwise automatically triggered.|
|`OPENAPI_GENERATOR_DISABLED`|*unset*|Set to non-empty value to *disable* OpenAPI client generation if automatically triggered when it shouldn't be.|
|`OPENAPI_GENERATOR_SCHEMA_PATH`|`openapi.yaml`|Location of static OpenAPI schema file within the repository.|
|`OPENAPI_GENERATOR_ARTIFACT_DIR`|`openapi`|Directory in which generated artifacts are placed.|
include:
- project: "uis/devops/continuous-delivery/ci-templates"
file: "/auto-devops/common-pipeline.yml"
ref: v5.1.0
ref: v6.3.0
- project: "uis/devops/continuous-delivery/ci-templates"
file: "/auto-devops/artifact-registry.yml"
ref: v5.1.0
ref: v6.3.0
- project: "uis/devops/continuous-delivery/ci-templates"
file: "/auto-devops/release-it.yml"
ref: v5.1.0
ref: v6.3.0
variables:
DAST_DISABLED: "1"
......
......@@ -40,7 +40,7 @@ repos:
- id: isort
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
rev: 7.1.1
hooks:
- id: flake8
......
# Changelog
## [0.10.0](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/compare/0.9.4...0.10.0) (2024-12-09)
### Features
* add generated documentation for OpanAPI clients ([ccd693d](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/ccd693d9ceb495193513f0cb42781e889cc59268))
* add some basic documentation ([17e6c7d](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/17e6c7dd47d0e17833ec7c3c42010d0fb6be42f6))
* document changes to OpenAPI generator template ([18e0123](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/18e01238d62a82d2befadaa3888d1f079e47438a))
* generate and package OpenAPI clients ([09825b1](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/09825b18a0ba988dca97e7ad9206a8cc7a334dd5))
* move to upstream OpenAPI generator template ([b1fb6ea](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/b1fb6eae582f90b0e8891ea6477b2af76adadbca)), closes [uis/devops/continuous-delivery/ci-templates#93](https://gitlab.developers.cam.ac.uk/uis/devops/continuous-delivery/ci-templates/issues/93) [#22](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/issues/22)
* only trigger API client generation if schema changes ([fa97e7f](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/fa97e7f7d0dd594bce6dc316e45c3eca4c8a363e))
* publish OpenAPI clients to GitLab's package registry ([a3ddcf2](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/a3ddcf2f6d08bc3d8738c3ba79397de85e5ce1e9))
### Bug Fixes
* add missing __init__.py files for management command module ([ff17e5c](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/ff17e5cb88825fa41455efe24635bc789e901d3a))
* correct various documentation warts ([470c48b](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/470c48b5c9b8da0c01c6f2a63046ae9333cb87a9))
* **pre-commit:** update flake8 ([f734811](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/f7348119b98ec8d975b7182111852e0433e0e629))
* **README:** add link to the GitLab pages now that it is known ([ddc634a](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/commit/ddc634a6cd37e0f4176dd431ab683df168ae0af7))
## [0.9.4](https://gitlab.developers.cam.ac.uk/uis/devops/iam/activate-account/api/compare/0.9.3...0.9.4) (2024-12-03)
### Bug Fixes
......
MIT License
Copyright (c) University of Cambridge Information Services
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
......@@ -4,10 +4,16 @@ This repository hosts the API for the Activate Account service, which manages th
processes as part of the transition away from the legacy Raven Login system. The API enables integration with a new web
application designed to streamline user registration and initial account setup.
More information is available in the [developer documentation hosted on GitLab
Pages](https://api-uis-devops-iam-activate-account-1e0d417baa8a52873ee0a121002.uniofcam.dev/).
## Documentation
The project has detailed documentation for developers, including a "getting
started" guide. See below for information on building the documentation.
started" guide.
To generate documentation locally, install dependencies via `poetry install` and run a local
documentation server via `poetry run mkdocs serve`.
## Guidebook - Quickstart and Testing
......@@ -64,72 +70,6 @@ For a fuller description of how to debug follow the
The project is configured with Gitlab AutoDevOps via Gitlab CI using the .gitlab-ci.yml file.
## Session authentication
In order to leverage existing tooling for OAuth2, it was decided that retrieving the access token
and handling authentication would follow the OAuth2 specification. This means we have an API endpoint
available on `/token/` that accepts a application/x-www-form-urlencoded encoded document POST-ed to it with the following fields:
* `grant_type` - must be `urn:devops.uis.cam.ac.uk:params:oauth:grant-type:new-user-credentials`
* `crsid` - must be the CRSid as a string
* `date_of_birth` - must be a RFC 3339 formatted date. E.g. 1996-12-19. No time-portion is accepted.
* `last_name` - must be a string
* `code` - must be a string
Either `crsid` or `last_name` must be provided, but not both.
An example request would be (line breaks added for display purposes):
```
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Adevops.uis.cam.ac.uk%3Aparams%3Aoauth%3Agrant-type
%3Anew-user-credentials&date_of_birth=1996-12-19&last_name=Smith&co
de=ABCDEF12345
```
If `grant_type` is anything other than what we expect, we respond with a 400 response as per [the spec](https://datatracker.ietf.org/doc/html/rfc6749#section-5.2) with the following content:
```
{
"error": "unsupported_grant_type"
}
```
If the user credentials are missing a required field, e.g. no `code` when it is required, we respond with a 400 response and:
```
{
"error": "invalid_request"
}
```
If the all the required user credentials are provided but they do not match a known user, we respond with a 400 response and the following document:
```
{
"error": "invalid_grant"
}
```
If all goes well, we return a [RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749) compliant JSON document response. The `access_token` field is the newly minted token, the `token_type` field must be `bearer` and the `expires_in` field gives the lifetime of the token in seconds. An example response:
```
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"abcdefg1234567",
"token_type":"bearer",
"expires_in":3600,
}
```
To authenticate to other API endpoints, we would set the following header: `Authorization: Bearer abcdefg1234567`.
## Generating the OpenAPI Specification
......@@ -143,4 +83,4 @@ This command utilises the `poe` task `generate-schema` to build and run the nece
## Copyright License
See the [LICENSE](LICENSE) file for details.
See the [LICENSE.txt](LICENSE.txt) file for details.
......@@ -15,7 +15,7 @@ class AccountSerializer(serializers.ModelSerializer):
source="account_details.terms_accepted", default=False
)
def update(self, instance, validated_data):
def update(self, instance, validated_data) -> Account:
"""
Updates the terms_accepted status of an account's related AccountDetails instance.
......
......@@ -29,7 +29,7 @@ class TokenRequestSerializer(serializers.Serializer):
date_of_birth = serializers.DateField(format="%Y-%m-%d")
code = serializers.CharField()
def validate_grant_type(self, grant_type):
def validate_grant_type(self, grant_type) -> str:
"""
Validates the grant type provided in the token request.
......@@ -51,7 +51,7 @@ class TokenRequestSerializer(serializers.Serializer):
return grant_type
def validate(self, data):
def validate(self, data) -> dict:
"""
Validates the entire data set of the token request.
......@@ -69,7 +69,7 @@ class TokenRequestSerializer(serializers.Serializer):
Raises:
serializers.ValidationError: If both or neither of the identification fields (crsid,
last name) are provided.
last name) are provided.
InvalidGrantError: If no matching account is found based on the provided credentials.
"""
......
../LICENSE.txt
\ No newline at end of file
---
title: API clients
---
# API client documentation
The following API clients are available:
- [TypeScript + Axios](./clients/typescript-axios/index.html)
- [Python + urllib3](./clients/python-urllib3/index.html)