FAQ | This is a LIVE service | Changelog

Skip to content
Commits on Source (13)
......@@ -102,7 +102,11 @@ venv.bak/
# Ignore any local files generated from the openapi specification:
**/card_client/*
**/hr_client/*
**/lookup_client/*
**/photo_client/*
**/student_client/*
**/inst_identifier_client/*
**/.openapi-generator/*
card_client_README.md
photo_client_README.md
......
......@@ -25,6 +25,9 @@ test:
coverage_report:
coverage_format: cobertura
path: ./artefacts/coverage.xml
variables:
TOX_ENVLIST: "black,flake8,py3"
pypi-release:
image: "${CI_REGISTRY_IMAGE}/${CI_COMMIT_BRANCH}:${CI_COMMIT_SHA}"
......
......@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.0.0] - 2023-06-14
### Added
- Add `repair` operation to Photo API `/photo-identifiers` endpoint
- Add `repair` operation to Card API `/card-identifiers` endpoint
- Add `originating_card_request`, `originating_card_request__isnull`, `created_at`, \
`issued_at`, `expires_at__isnull`, `issued_at__isnull` filters to `./cards` endpoint
- Add `created_at` to `/cards/{id}` endpoint
- Add new endpoint `/cards/update`
- Lowercase CRSID identifiers when calling Identifier.from_string()
### Changed
- Photo API `set_retention` operation replaced by `repair` operation.
- Card API `set_retention` operation replaced by `repair` operation.
- Photo API OpenAPI spec refactor causing breaking changes in identitylib.
## [1.6.0] - 2023-04-21
### Added
......
......@@ -325,6 +325,9 @@ class Identifier(namedtuple("Identifier", ["value", "scheme"])):
raise ValueError(f"Invalid identifier {value}")
parsed_value = scheme.value_parser(parsed_value) if scheme.value_parser else parsed_value
if str(scheme).lower() == str(IdentifierSchemes.CRSID).lower():
return Identifier(parsed_value.lower(), scheme)
return Identifier(parsed_value, scheme)
def __str__(self):
......
......@@ -8,7 +8,7 @@ PACKAGE_DESCRIPTION = (
"A module containing helpers and shared code related to identity systems within UIS, "
"University of Cambridge."
)
PACKAGE_VERSION = "1.6.0"
PACKAGE_VERSION = "2.0.0"
PACKAGE_URL = "https://gitlab.developers.cam.ac.uk/uis/devops/iam/identity-lib"
......
2b6b019c57a3af9bc60850db2be800b2a6b84ddc
\ No newline at end of file
c9c7f7479ca7af3d18949c2a76f61ddbf6b6063e
\ No newline at end of file
......@@ -56,6 +56,13 @@ definitions:
- MIFARE_TEMPORARY
title: Card type
type: string
createdAt:
description: When this record was created
format: date-time
readOnly: true
title: Created at
type: string
x-nullable: true
expiresAt:
description: If non-NULL, when the card expires
format: date-time
......@@ -674,6 +681,13 @@ definitions:
- MIFARE_TEMPORARY
title: Card type
type: string
createdAt:
description: When this record was created
format: date-time
readOnly: true
title: Created at
type: string
x-nullable: true
expiresAt:
description: If non-NULL, when the card expires
format: date-time
......@@ -1292,14 +1306,14 @@ paths:
action:
description: The action to apply to this card identifier.
enum:
- set_retention
- restore
- repair
- soft_delete
- hard_delete
title: CardIdentifierUpdateRequesstActionEnum
title: CardIdentifierUpdateRequestActionEnum
type: string
id:
description: id of the card identifier
description: UUID of the card identifier
type: string
type: object
type: array
......@@ -1429,7 +1443,7 @@ paths:
## Update the card identifier
This method allows a client to submit an action in the request body for a given card identifier. The allowed actions are `set_retention`, `restore`, `soft_delete` and `hard_delete`.
This method allows a client to submit an action in the request body for a given card identifier. The allowed actions are `repair`, `restore`, `soft_delete` and `hard_delete`.
### Permissions
......@@ -1446,11 +1460,11 @@ paths:
action:
description: The action to apply to this card identifier.
enum:
- set_retention
- restore
- repair
- soft_delete
- hard_delete
title: CardIdentifierUpdateRequesstActionEnum
title: CardIdentifierUpdateRequestActionEnum
type: string
title: CardIdentifierUpdateRequestType
type: object
......@@ -2160,7 +2174,7 @@ paths:
type: string
type: object
id:
description: id of the card request
description: UUID of the card request
type: string
identifiers:
items:
......@@ -2548,26 +2562,56 @@ paths:
name: search
required: false
type: string
- description: ""
- description: Filter updatedAt by IsoDateTime less than
format: date-time
in: query
name: updated_at__lte
required: false
type: string
- description: ""
- description: Filter updatedAt by IsoDateTime greater than
format: date-time
in: query
name: updated_at__gte
required: false
type: string
- description: ""
- description: Filter expiresAt by IsoDateTime less than
format: date-time
in: query
name: expires_at__lte
required: false
type: string
- description: ""
- description: Filter expiresAt by IsoDateTime greater than
format: date-time
in: query
name: expires_at__gte
required: false
type: string
- description: Filter expiresAt by IsoDateTime is Null
format: boolean
in: query
name: expires_at__isnull
type: boolean
- description: Filter createdAt by IsoDateTime less than
format: date-time
in: query
name: created_at__lte
type: string
- description: Filter createdAt by IsoDateTime greater than
format: date-time
in: query
name: created_at__gte
type: string
- description: Filter issuedAt by IsoDateTime less than
format: date-time
in: query
name: issued_at__lte
type: string
- description: Filter issuedAt by IsoDateTime greater than
format: date-time
in: query
name: issued_at__gte
type: string
- description: Filter issuedAt by IsoDateTime is Null
format: boolean
in: query
name: issued_at__isnull
type: boolean
- description: Filter cards by an identifier in the format {value}@{scheme}
in: query
name: identifier
......@@ -2593,6 +2637,15 @@ paths:
in: query
name: institution
type: string
- description: Filter originating_card_request by CardRequest UUID isNull
format: boolean
in: query
name: originating_card_request__isnull
type: boolean
- description: Filter originating_card_request by CardRequest UUID
in: query
name: originating_card_request
type: string
- description: The pagination cursor value.
in: query
name: cursor
......@@ -2784,6 +2837,74 @@ paths:
summary: Filter cards by identifiers
tags:
- v1beta1
/v1beta1/cards/update:
parameters: []
put:
description: |2+
## Update multiple cards
Allows multiple cards to be updated in one call. For large number of cards, this endpoint will be faster than PUT-ing each update.
Updates are processed in the order they are received. The response includes the detail of the operation, the UUID of the card that was updated, and HTTP status code which would have been returned from separate PUTs. If the status code is 404, the `id` property is omitted.
### Permissions
Principals with the `CARD_UPDATER` permission will be able to affect this endpoint.
operationId: v1beta1_cards_bulk_update
parameters:
- in: body
name: data
required: true
schema:
properties:
updates:
items:
properties:
action:
description: The action to apply to this card identifier.
enum:
- cancel
- refresh
title: CardUpdateRequestActionEnum
type: string
id:
description: UUID of the card
type: string
type: object
type: array
title: CardBulkUpdateRequestType
type: object
responses:
"200":
description: ""
schema:
properties:
details:
items:
properties:
detail:
type: string
id:
type: string
status:
type: number
type: object
type: array
title: CardBulkUpdateResponseType
type: object
"400":
description: Invalid input.
schema:
$ref: '#/definitions/ValidationError'
"401":
description: Authentication credentials are invalid or absent.
"500":
description: An error has occurred - retry the request after a pause.
summary: Update multiple cards
tags:
- v1beta1
/v1beta1/cards/{id}:
get:
description: |2+
......
e4c29bebf4b593b42f97b2e06ea7d5ae16c7f031
\ No newline at end of file
7a4555e7bf37f356a7a3c766afec3ff717600d15
\ No newline at end of file
......@@ -12,12 +12,12 @@ components:
type: object
ActionEnum:
description: |-
* `set_retention` - Retention
* `repair` - Repair
* `restore` - Restore
* `soft_delete` - Soft Delete
* `hard_delete` - Hard Delete
enum:
- set_retention
- repair
- restore
- soft_delete
- hard_delete
......@@ -186,6 +186,7 @@ components:
readOnly: true
type: integer
url:
description: Get the image url.
readOnly: true
type: string
required:
......@@ -320,26 +321,6 @@ components:
- scheme
- value
type: object
V1Beta1PhotoIdentifierSummaryRequest:
properties:
scheme:
allOf:
- $ref: '#/components/schemas/SchemeEnum'
description: |-
The identifier's scheme
* `v1.person.identifiers.cam.ac.uk` - CRSID of the person identified by this Photo
* `person.v1.student-records.university.identifiers.cam.ac.uk` - CamSIS Identifier of the person identified by this Photo
* `person.v1.human-resources.university.identifiers.cam.ac.uk` - CHRIS Identifier of the person identified by this Photo
* `photo.v1.legacy-card.university.identifiers.cam.ac.uk` - Legacy Card DB Photo Identifier
value:
description: The identifier's value
minLength: 1
type: string
required:
- scheme
- value
type: object
securitySchemes:
apiGatewayAuthorizationCodeSecurityScheme:
description: API Gateway authorization code security scheme
......@@ -602,7 +583,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: List all photos
tags:
- All Photos
- v1beta1
/v1beta1/approved-photos:
get:
description: |2+
......@@ -707,7 +688,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: List approved photos
tags:
- Approved Photos
- v1beta1
/v1beta1/approved-photos/{identifier}:
get:
description: |2+
......@@ -811,7 +792,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: Get an approved photo of a person using a person identifier
tags:
- Approved Photos
- v1beta1
/v1beta1/approved-photos/{identifier}/content:
get:
description: |2+
......@@ -921,7 +902,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: Get the image content of an approved photo using a person identifier
tags:
- Approved Photos
- v1beta1
/v1beta1/approved-photos/{identifier}/content/transient-url:
get:
description: |2+
......@@ -1029,7 +1010,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: Get the transient url of the content of this approved photo
tags:
- Approved Photos
- v1beta1
/v1beta1/approved-photos/{identifier}/thumbnail:
get:
description: |2+
......@@ -1126,7 +1107,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: Get the thumbnail of an approved photo using a person identifier
tags:
- Approved Photos
- v1beta1
/v1beta1/approved-photos/{identifier}/thumbnail/transient-url:
get:
description: |2+
......@@ -1217,7 +1198,7 @@ paths:
- {}
summary: Get the transient url of an the thumbnail of an approved photo using a person identifier
tags:
- Approved Photos
- v1beta1
/v1beta1/photo-identifiers:
get:
description: |2+
......@@ -1262,6 +1243,11 @@ paths:
name: identifier
schema:
type: string
- description: Filter isDeleted
in: query
name: is_deleted
schema:
type: boolean
- description: Filter is_highest_primary_identifier
in: query
name: is_highest_primary_identifier
......@@ -1355,14 +1341,14 @@ paths:
- apiGatewayClientCredentialsSecurityScheme: []
summary: List photo identifiers
tags:
- Photo Identifiers
- v1beta1
/v1beta1/photo-identifiers/update:
put:
description: |2+
## Bulk update the photo identifier
This method allows a client to submit a list of photo identifiers and corresponding action to apply to the photo identifier. The allowed actions are `set_retention`, `restore`, `soft_delete` and `hard_delete`.
This method allows a client to submit a list of photo identifiers and corresponding action to apply to the photo identifier. The allowed actions are `repair`, `restore`, `soft_delete` and `hard_delete`.
### Permissions
......@@ -1447,7 +1433,7 @@ paths:
- apiGatewayClientCredentialsSecurityScheme: []
summary: Bulk update photo identifiers by photo identifier UUID.
tags:
- Photo Identifiers
- v1beta1
/v1beta1/photo-identifiers/{id}:
delete:
description: |2+
......@@ -1534,7 +1520,7 @@ paths:
- apiGatewayClientCredentialsSecurityScheme: []
summary: Remove a photo identifier and associated photos by photo identifier UUID.
tags:
- Photo Identifiers (including Photos)
- v1beta1
get:
description: |2+
......@@ -1624,13 +1610,13 @@ paths:
- apiGatewayClientCredentialsSecurityScheme: []
summary: Get a photo identifier by identifier UUID.
tags:
- Photo Identifier
- v1beta1
put:
description: |2+
## Update the photo identifier
This method allows a client to submit an action in the request query for a given photo identifier. The allowed actions are `set_retention`, `restore`, `soft_delete` and `hard_delete`.
This method allows a client to submit an action in the request query for a given photo identifier. The allowed actions are `repair`, `restore`, `soft_delete` and `hard_delete`.
### Permissions
......@@ -1644,8 +1630,8 @@ paths:
schema:
enum:
- hard_delete
- repair
- restore
- set_retention
- soft_delete
type: string
- description: A UUID string identifying this photo identifier.
......@@ -1654,18 +1640,6 @@ paths:
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/V1Beta1PhotoIdentifierSummaryRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/V1Beta1PhotoIdentifierSummaryRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/V1Beta1PhotoIdentifierSummaryRequest'
required: true
responses:
"200":
description: No response body
......@@ -1732,7 +1706,7 @@ paths:
- apiGatewayClientCredentialsSecurityScheme: []
summary: Update a photo identifier by photo identifier UUID.
tags:
- Photo Identifiers
- v1beta1
/v1beta1/photos:
get:
description: |2+
......@@ -1836,7 +1810,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: Get the photos related to a given photo identifier
tags:
- Photos (including unapproved photos)
- v1beta1
post:
description: |2+
......@@ -1970,7 +1944,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos
summary: Create a new photo with a set of identifiers
tags:
- Photos (including unapproved photos)
- v1beta1
/v1beta1/photos/no-primary-identifier:
get:
description: |2+
......@@ -2059,7 +2033,7 @@ paths:
- {}
summary: Get list of all photos missing a primary identifier
tags:
- Photos (including unapproved photos)
- v1beta1
/v1beta1/photos/{id}:
delete:
description: |2+
......@@ -2153,7 +2127,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos
summary: Remove a photo
tags:
- Photos (including unapproved photos)
- v1beta1
get:
description: |2+
......@@ -2247,7 +2221,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: Get a photo by photo UUID
tags:
- Photos (including unapproved photos)
- v1beta1
patch:
description: |2+
......@@ -2358,7 +2332,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos
summary: Update a photo
tags:
- Photos (including unapproved photos)
- v1beta1
/v1beta1/photos/{id}/content:
get:
description: |2+
......@@ -2464,7 +2438,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: Get the image content of a photo by photo UUID
tags:
- Photos (including unapproved photos)
- v1beta1
/v1beta1/photos/{id}/original:
get:
description: |2+
......@@ -2562,7 +2536,7 @@ paths:
- {}
summary: Get the original (uncropped) image uploaded when this photo was created
tags:
- Photos (including unapproved photos)
- v1beta1
/v1beta1/photos/{id}/thumbnail:
get:
description: |2+
......@@ -2658,7 +2632,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: Get the thumbnail of a photo by photo UUID
tags:
- Photos (including unapproved photos)
- v1beta1
/v1beta1/unapproved-photos:
get:
description: |2+
......@@ -2753,7 +2727,7 @@ paths:
- https://api.apps.cam.ac.uk/photo/photos.readonly
summary: List unapproved photos
tags:
- Unapproved Photos
- v1beta1
servers:
- description: Production instance of the University Photo API
url: https://api.apps.cam.ac.uk/photo
# This compose configuration is just used for running tox within Docker
version: '3.2'
services:
tox:
build:
context: .
dockerfile: ./Dockerfile
entrypoint: []
command: ["tox"]
volumes:
- tox-data:/tmp/tox-data
environment:
TOXINI_WORK_DIR: /tmp/tox-data/work
TOXINI_ARTEFACT_DIR: /tmp/tox-data/artefacts
TOXINI_SITEPACKAGES: 'True'
COVERAGE_FILE: /tmp/tox-data/coverage
volumes:
# A persistent volume for tox to store its stuff. This allows caching of
# virtualenvs between runs.
tox-data:
......@@ -9,4 +9,11 @@ cd "$( dirname "${BASH_SOURCE[0]}")"
# Execute tox runner, logging command used
set -x
exec docker-compose --file ./test-compose.yml run --rm tox tox $@
docker build -t identitylib .
docker run \
--rm \
-v $(pwd)/htmlcov:/usr/src/app/build/py3/htmlcov:rw \
-it \
-e TOXINI_SITEPACKAGES=True \
--entrypoint /bin/sh identitylib -c "tox $*"
......@@ -13,6 +13,12 @@ class IdentifiersTestCase(TestCase):
Identifier("abc123", IdentifierSchemes.USN),
)
# parsing CRSid cast to lower case
self.assertEqual(
Identifier.from_string("ABC123@v1.person.identifiers.cam.ac.uk"),
Identifier("abc123", IdentifierSchemes.CRSID),
)
# fallback scheme given - actual scheme in identifier is used
self.assertEqual(
Identifier.from_string(
......
......@@ -68,7 +68,9 @@ deps=
flake8=={env:TOXINI_FLAKE8_VERSION:3.8.0}
commands=
flake8 --version
flake8 .
# flake8 pycodestyle is not PEP8 compliant wrt E203
# https://github.com/PyCQA/pycodestyle/issues/373
flake8 --extend-ignore=E203 .
[testenv:black]
basepython=python3
......@@ -79,4 +81,15 @@ deps=
black=={env:TOXINI_BLACK_VERSION:23.1.0}
commands=
black --version
black --check --diff --line-length 99 identitylib setup.py
black --check --diff --line-length=99 \
identitylib/api_client_mixin.py \
identitylib/card_client_configuration.py \
identitylib/identifiers.py \
identitylib/inst_identifier_configuration.py \
identitylib/lookup_client_configuration.py \
identitylib/photo_client_configuration.py \
identitylib/university_hr_configuration.py \
identitylib/university_student_configuration.py \
tests \
scripts \
setup.py