add documentation (#22)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Add OpenAPI spec and man pages Co-authored-by: Max Erenberg <> Co-authored-by: Rio Liu <rio.liu@r26.me> Co-authored-by: Andrew Wang <a268wang@csclub.uwaterloo.ca> Reviewed-on: #22 Co-authored-by: Max Erenberg <merenber@csclub.uwaterloo.ca> Co-committed-by: Max Erenberg <merenber@csclub.uwaterloo.ca>
This commit is contained in:
parent
3e1131c4e4
commit
1fcc49ef12
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,3 +5,5 @@ __pycache__/
|
||||
*.o
|
||||
*.so
|
||||
.idea/
|
||||
/docs/*.1
|
||||
/docs/*.5
|
||||
|
23
docs/README.md
Normal file
23
docs/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Documentation
|
||||
## OpenAPI
|
||||
We are using [OpenAPI 3.0](https://swagger.io/docs/specification/about/) to
|
||||
document the REST API for ceod, and [Redoc](https://github.com/Redocly/redoc)
|
||||
to generate HTML documentation from the OpenAPI file.
|
||||
|
||||
First, make sure you have Node.js and npm installed. Then, install the Redoc CLI:
|
||||
```sh
|
||||
npm install -g redoc-cli
|
||||
```
|
||||
After you make changes to the openapi.yaml file, make sure to regenerate the HTML:
|
||||
```sh
|
||||
redoc-cli bundle openapi.yaml
|
||||
```
|
||||
You can now view the [redoc-static.html](./redoc-static.html) file from your browser.
|
||||
|
||||
## Man pages
|
||||
We are using [scdoc](https://git.sr.ht/~sircmpwn/scdoc) to generate our man pages.
|
||||
You can view the pages from your terminal like so:
|
||||
```sh
|
||||
scdoc < ceo.1.scd > ceo.1
|
||||
man ./ceo.1
|
||||
```
|
29
docs/ceo.1.scd
Normal file
29
docs/ceo.1.scd
Normal file
@ -0,0 +1,29 @@
|
||||
ceo(1)
|
||||
|
||||
# NAME
|
||||
|
||||
ceo - CSC Electronic Office
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
*Text User Interface*
|
||||
*ceo*
|
||||
|
||||
*Command Line Interface*
|
||||
*ceo* [OPTIONS] COMMAND [ARGS]...
|
||||
|
||||
# DESCRIPTION
|
||||
CSC Electronic Office is used to manage membership registration and user accounts for the Computer Science Club.
|
||||
|
||||
To use the TUI, type *ceo* with no arguments.
|
||||
To use the CLI, run *ceo --help*.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
*ceo.ini*(5), *ceod.ini*(5)
|
||||
|
||||
# AUTHORS
|
||||
|
||||
Max Erenberg <merenber@csclub.uwaterloo.ca>++
|
||||
Andrew Wang <a268wang@csclub.uwaterloo.ca>++
|
||||
Rio Liu <r345liu@csclub.uwaterloo.ca>
|
57
docs/ceo.ini.5.scd
Normal file
57
docs/ceo.ini.5.scd
Normal file
@ -0,0 +1,57 @@
|
||||
ceo.ini(5)
|
||||
|
||||
# NAME
|
||||
|
||||
ceo.ini - configuration file for ceo
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
/etc/csc/ceo.ini
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
ceo.ini is an INI file with various sections which control the behaviour of *ceo*(1).
|
||||
|
||||
# DEFAULTS SECTION
|
||||
_base_domain_++
|
||||
The domain name of CSC. Should be set to 'csclub.uwaterloo.ca'.
|
||||
|
||||
_uw_domain_++
|
||||
The domain of UW. Should be set to 'uwaterloo.ca'.
|
||||
|
||||
# CEOD SECTION
|
||||
_admin_host_++
|
||||
The host with the ceod/admin Kerberos key.
|
||||
|
||||
_database_host_++
|
||||
The host with the root password for MySQL and PostgreSQL.
|
||||
|
||||
_mailman_host_++
|
||||
The host running Mailman.
|
||||
|
||||
_use_https_++
|
||||
Whether to use HTTPS when connecting to ceod. Should be set to 'true'.
|
||||
|
||||
_port_++
|
||||
The port on which ceod is listening.
|
||||
|
||||
# POSITIONS SECTION
|
||||
_required_++
|
||||
A comma-separated list of executive positions which must be fulfilled.
|
||||
|
||||
_available_++
|
||||
A comma-separated list of available executive positions.
|
||||
|
||||
# MYSQL SECTION
|
||||
_host_++
|
||||
The host where MySQL is running.
|
||||
|
||||
# POSTGRESQL SECTION
|
||||
_host_++
|
||||
The host where PostgreSQL is running.
|
||||
|
||||
# SEE ALSO
|
||||
*ceo*(1)
|
||||
|
||||
# AUTHORS
|
||||
Max Erenberg <merenber@csclub.uwaterloo.ca>
|
159
docs/ceod.ini.5.scd
Normal file
159
docs/ceod.ini.5.scd
Normal file
@ -0,0 +1,159 @@
|
||||
ceod.ini(5)
|
||||
|
||||
# NAME
|
||||
|
||||
ceod.ini - configuration file for ceod
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
/etc/csc/ceod.ini
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
ceod.ini is an INI file with various sections which control the behaviour of ceod.
|
||||
|
||||
# DEFAULTS SECTION
|
||||
_base_domain_++
|
||||
The domain name of CSC. Should be set to 'csclub.uwaterloo.ca'.
|
||||
|
||||
# CEOD SECTION
|
||||
_admin_host_++
|
||||
The host with the ceod/admin Kerberos key.
|
||||
|
||||
_fs_root_host_++
|
||||
The host without NFS root squashing.
|
||||
|
||||
_database_host_++
|
||||
The host with the root password for MySQL and PostgreSQL.
|
||||
|
||||
_mailman_host_++
|
||||
The host running Mailman.
|
||||
|
||||
_use_https_++
|
||||
Whether to use HTTPS when connecting to ceod. Should be set to 'true'.
|
||||
|
||||
_port_++
|
||||
The port on which ceod is listening.
|
||||
|
||||
# LDAP SECTION
|
||||
_admin_principal_++
|
||||
The Kerberos principal which ceod should use for *kadmin*(1).
|
||||
|
||||
_server_url_++
|
||||
The primary CSC LDAP server URL.
|
||||
|
||||
_sasl_realm_++
|
||||
The CSC SASL realm for LDAP. Should be 'CSCLUB.UWATERLOO.CA'.
|
||||
|
||||
_users_base_++
|
||||
The LDAP OU where users are stored.
|
||||
|
||||
_groups_base_++
|
||||
The LDAP OU where groups are stored.
|
||||
|
||||
_sudo_base_++
|
||||
The LDAP OU where *sudo*(8) roles are stored.
|
||||
|
||||
# UWLDAP SECTION
|
||||
_server_url_++
|
||||
The UW LDAP server URL.
|
||||
|
||||
_base_++
|
||||
The LDAP OU where users are stored in the UW LDAP.
|
||||
|
||||
# MEMBERS SECTION
|
||||
_min_id_++
|
||||
The minimum UID number for members.
|
||||
|
||||
_max_id_++
|
||||
The maximum UID number for members.
|
||||
|
||||
_home_++
|
||||
The directory in which new members' home directories should be created.
|
||||
|
||||
_skel_++
|
||||
The skeleton directory for new members.
|
||||
|
||||
# CLUBS SECTION
|
||||
_min_id_++
|
||||
The minimum UID number for club accounts.
|
||||
|
||||
_max_id_++
|
||||
The maximum UID number for club accounts.
|
||||
|
||||
_home_++
|
||||
The directory in which new club accounts' home directories should be created.
|
||||
|
||||
_skel_++
|
||||
The skeleton directory for new club accounts.
|
||||
|
||||
# MAIL SECTION
|
||||
_smtp_url_++
|
||||
The SMTP URL where ceod should send emails.
|
||||
|
||||
_smtp_starttls_++
|
||||
Whether ceod should use STARTTLS with the SMTP server or not.
|
||||
|
||||
# MAILMAN3 SECTION
|
||||
_api_base_url_++
|
||||
The base URL of the Mailman 3 API.
|
||||
|
||||
_api_username_++
|
||||
The username to use when authenticating to the Mailman 3 API via HTTP Basic Auth.
|
||||
|
||||
_api_password_++
|
||||
The password to use when authenticating to the Mailman 3 API via HTTP Basic Auth.
|
||||
|
||||
_new_member_list_++
|
||||
The mailing list to which new members should be subscribed.
|
||||
|
||||
# AUXILIARY GROUPS SECTION
|
||||
Each key in this section contains a comma-separated list of auxiliary groups to
|
||||
which members should be added when joining the primary group. For example,
|
||||
|
||||
syscom = office,staff
|
||||
|
||||
means that when someone joins the syscom group, they will also be added to the
|
||||
office and staff groups.
|
||||
|
||||
# AUXILIARY MAILING LISTS SECTION
|
||||
Each key in this section contains a comma-separated list of auxiliary mailing lists to
|
||||
which members should be subscribed when joining the primary group. For example,
|
||||
|
||||
syscom = syscom,syscom-alerts
|
||||
|
||||
means that when someone joins the syscom group, they will also be subscribed to the
|
||||
syscom and syscom-alerts mailing lists.
|
||||
|
||||
# POSITIONS SECTION
|
||||
_required_++
|
||||
A comma-separated list of executive positions which must be fulfilled.
|
||||
|
||||
_available_++
|
||||
A comma-separated list of available executive positions.
|
||||
|
||||
# MYSQL SECTION
|
||||
_host_++
|
||||
The host where MySQL is running.
|
||||
|
||||
_username_++
|
||||
The username to use when connecting to MySQL.
|
||||
|
||||
_password_++
|
||||
The password to use when connecting to MySQL.
|
||||
|
||||
# POSTGRESQL SECTION
|
||||
_host_++
|
||||
The host where PostgreSQL is running.
|
||||
|
||||
_username_++
|
||||
The username to use when connecting to PostgreSQL.
|
||||
|
||||
_password_++
|
||||
The password to use when connecting to PostgreSQL.
|
||||
|
||||
# SEE ALSO
|
||||
*ceo.ini*(5)
|
||||
|
||||
# AUTHORS
|
||||
Max Erenberg <merenber@csclub.uwaterloo.ca>
|
861
docs/openapi.yaml
Normal file
861
docs/openapi.yaml
Normal file
@ -0,0 +1,861 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: ceod - OpenAPI 3.0
|
||||
description: |
|
||||
This is an OpenAPI specification of ceod, the CSC Electronic Office daemon.
|
||||
Visit the [git repository](https://git.csclub.uwaterloo.ca/public/pyceo) for
|
||||
more details.
|
||||
## Streaming Responses
|
||||
Many endpoints return a "streaming response", which consists of a series of JSON
|
||||
objects, one per line (the mimetype is text/plain). For example:
|
||||
```
|
||||
{"status": "in progress", "operation": "replace_login_shell"}
|
||||
{"status": "in progress", "operation": "replace_forwarding_addresses"}
|
||||
{"status": "completed", "result": "OK"}
|
||||
```
|
||||
Whenever an operation is completed, a corresponding JSON object will be streamed
|
||||
from the server to the client. This allows the client to track the server's progress
|
||||
in real time.
|
||||
contact:
|
||||
email: syscom@csclub.uwaterloo.ca
|
||||
version: 1.0.0
|
||||
servers:
|
||||
- url: https://phosphoric-acid.csclub.uwaterloo.ca:9987/api
|
||||
tags:
|
||||
- name: members
|
||||
description: Operations on members and club reps
|
||||
- name: groups
|
||||
description: Operations on groups and clubs
|
||||
- name: mailman
|
||||
description: Operations on mailing list subscriptions
|
||||
- name: uwldap
|
||||
description: Operations related to the UW LDAP directory
|
||||
- name: database
|
||||
description: Operations related to databases
|
||||
security:
|
||||
- GSSAPIAuth: []
|
||||
paths:
|
||||
/members:
|
||||
post:
|
||||
tags: ['members']
|
||||
summary: Create a new user
|
||||
description: >-
|
||||
Creates a new member or club rep. If `terms` is specified, a member is created;
|
||||
if `non_member_terms` is specified, a club rep is created.
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
uid:
|
||||
$ref: "#/components/schemas/UID"
|
||||
cn:
|
||||
$ref: "#/components/schemas/UserCN"
|
||||
program:
|
||||
$ref: "#/components/schemas/Program"
|
||||
terms:
|
||||
$ref: "#/components/schemas/Terms"
|
||||
non_member_terms:
|
||||
$ref: "#/components/schemas/NonMemberTerms"
|
||||
forwarding_addresses:
|
||||
$ref: "#/components/schemas/ForwardingAddresses"
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Streaming response
|
||||
example: |
|
||||
{"status": "in progress", "operation": "add_user_to_ldap"}
|
||||
{"status": "in progress", "operation": "add_group_to_ldap"}
|
||||
{"status": "in progress", "operation": "add_user_to_kerberos"}
|
||||
{"status": "in progress", "operation": "create_home_dir"}
|
||||
{"status": "in progress", "operation": "send_welcome_message"}
|
||||
{"status": "in progress", "operation": "subscribe_to_mailing_list"}
|
||||
{"status": "in progress", "operation": "announce_new_user"}
|
||||
{"status": "completed", "result": {"cn": "Calum Dalek", "uid": "ctdalek", "uid_number": 20001, "gid_number": 20001, "login_shell": "/bin/bash", "home_directory": "/users/ctdalek", "is_club": false, "program": "MAT/Mathematics Computer Science", "terms": ["f2021"], "forwarding_addresses": ["ctdalek@uwaterloo.ca"], "password": "Wlw1wOTofERTEBlXWzR6/MZL"}}
|
||||
/members/{username}:
|
||||
get:
|
||||
tags: ['members']
|
||||
summary: Get information about a user
|
||||
description: >-
|
||||
Returns information about a member or club rep. The `forwarding_addresses` field
|
||||
will only be present if the client is an authenticated syscom member.
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: username of the user to return
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/User"
|
||||
"404":
|
||||
$ref: "#/components/responses/UserNotFoundErrorResponse"
|
||||
patch:
|
||||
tags: ['members']
|
||||
summary: Modify a user
|
||||
description: Replace the login shell and/or forwarding addresses of a user
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: username of the user to modify
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
login_shell:
|
||||
$ref: "#/components/schemas/LoginShell"
|
||||
forwarding_addresses:
|
||||
$ref: "#/components/schemas/ForwardingAddresses"
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Streaming response
|
||||
example: |
|
||||
{"status": "in progress", "operation": "replace_login_shell"}
|
||||
{"status": "in progress", "operation": "replace_forwarding_addresses"}
|
||||
{"status": "completed", "result": "OK"}
|
||||
"404":
|
||||
$ref: "#/components/responses/UserNotFoundErrorResponse"
|
||||
/members/{username}/renew:
|
||||
post:
|
||||
tags: ['members']
|
||||
summary: Renew a user
|
||||
description: Add member **or** non-member terms to a user
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: username of the user to renew
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
terms:
|
||||
type: array
|
||||
description: Terms for which this user will be a member
|
||||
items:
|
||||
$ref: "#/components/schemas/Term"
|
||||
- type: object
|
||||
properties:
|
||||
non_member_terms:
|
||||
type: array
|
||||
description: Terms for which this user will be a club rep
|
||||
items:
|
||||
$ref: "#/components/schemas/Term"
|
||||
example: {"terms": ["f2021"]}
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
terms_added:
|
||||
type: array
|
||||
description: Member terms which were added to this user
|
||||
items:
|
||||
$ref: "#/components/schemas/Term"
|
||||
- type: object
|
||||
properties:
|
||||
non_member_terms_added:
|
||||
type: array
|
||||
description: Non-member terms which were added to this user
|
||||
items:
|
||||
$ref: "#/components/schemas/Term"
|
||||
example: {"terms_added": ["f2021"]}
|
||||
"404":
|
||||
$ref: "#/components/responses/UserNotFoundErrorResponse"
|
||||
/members/{username}/pwreset:
|
||||
post:
|
||||
tags: ['members']
|
||||
summary: Reset a user's password
|
||||
description: >-
|
||||
Sets a user's password to a randomly generated string, and returns it. The user will be
|
||||
prompted to set a new password on their next login.
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: username of the user whose password will be reset
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
password:
|
||||
type: string
|
||||
description: The user's new password
|
||||
example: "EPGbJwLl1pmiWz8Wvu/MSs+v"
|
||||
"404":
|
||||
$ref: "#/components/responses/UserNotFoundErrorResponse"
|
||||
/groups:
|
||||
post:
|
||||
tags: ['groups']
|
||||
summary: Create a new group
|
||||
description: >-
|
||||
Creates a new Unix group for a club. A new Unix user account with the same name will also be created.
|
||||
A sudo role will be created allowing members of the group to become this user.
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
cn:
|
||||
$ref: "#/components/schemas/GroupCN"
|
||||
description:
|
||||
$ref: "#/components/schemas/GroupDescription"
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Streaming response
|
||||
example: |
|
||||
{"status": "in progress", "operation": "add_user_to_ldap"}
|
||||
{"status": "in progress", "operation": "add_group_to_ldap"}
|
||||
{"status": "in progress", "operation": "add_sudo_role"}
|
||||
{"status": "in progress", "operation": "create_home_dir"}
|
||||
{"status": "completed", "result": {"cn": "uwclub1", "gid_number": 30001, "description": "Club One", "members": []}}
|
||||
/groups/{group_name}:
|
||||
get:
|
||||
tags: ['groups']
|
||||
summary: Get information about a group
|
||||
description: Returns information about a group
|
||||
security: []
|
||||
parameters:
|
||||
- name: group_name
|
||||
in: path
|
||||
description: name of the group to return
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
cn:
|
||||
$ref: "#/components/schemas/GroupCN"
|
||||
description:
|
||||
$ref: "#/components/schemas/GroupDescription"
|
||||
gid_number:
|
||||
$ref: "#/components/schemas/GIDNumber"
|
||||
members:
|
||||
type: array
|
||||
description: Members of the group
|
||||
items:
|
||||
$ref: "#/components/schemas/UID"
|
||||
"404":
|
||||
$ref: "#/components/responses/GroupNotFoundErrorResponse"
|
||||
/groups/{group_name}/members/{username}:
|
||||
post:
|
||||
tags: ['groups']
|
||||
summary: Add a member to a group
|
||||
description: >-
|
||||
Adds a member to a group. The member will also be added to any auxiliary groups
|
||||
specified in ceod.conf. The member may also be added to auxiliary mailing lists.
|
||||
parameters:
|
||||
- name: group_name
|
||||
in: path
|
||||
description: name of the group to which the member will be added
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: username
|
||||
in: path
|
||||
description: username of the member who will be added to the group
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: subscribe_to_lists
|
||||
in: query
|
||||
description: whether the member should be subscribed to auxiliary mailing lists
|
||||
schema:
|
||||
type: boolean
|
||||
default: true
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
example: |
|
||||
{"status": "in progress", "operation": "add_user_to_group"}
|
||||
{"status": "in progress", "operation": "add_user_to_auxiliary_groups"}
|
||||
{"status": "in progress", "operation": "subscribe_user_to_auxiliary_mailing_lists"}
|
||||
{"status": "completed", "result": {"added_to_groups": ["group2","group3"], "subscribed_to_lists": ["list1","list2"]}}
|
||||
"404":
|
||||
$ref: "#/components/responses/GroupNotFoundErrorResponse"
|
||||
delete:
|
||||
tags: ['groups']
|
||||
summary: Remove a member from a group
|
||||
description: >-
|
||||
Removes a member from a group. The member will also be removed from any auxiliary groups
|
||||
specified in ceod.conf. The member may also be removed from auxiliary mailing lists.
|
||||
parameters:
|
||||
- name: group_name
|
||||
in: path
|
||||
description: name of the group from which the member will be removed
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: username
|
||||
in: path
|
||||
description: username of the member who will be removed from the group
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: unsubscribe_from_lists
|
||||
in: query
|
||||
description: whether the member should be unsubscribed from auxiliary mailing lists
|
||||
schema:
|
||||
type: boolean
|
||||
default: true
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
example: |
|
||||
{"status": "in progress", "operation": "remove_user_from_group"}
|
||||
{"status": "in progress", "operation": "remove_user_from_auxiliary_groups"}
|
||||
{"status": "in progress", "operation": "unsubscribe_user_from_auxiliary_mailing_lists"}
|
||||
{"status": "completed", "result": {"removed_from_groups": ["group2","group3"], "unsubscribed_from_lists": ["list1","list2"]}}
|
||||
"404":
|
||||
$ref: "#/components/responses/GroupNotFoundErrorResponse"
|
||||
/positions:
|
||||
get:
|
||||
tags: ['positions']
|
||||
summary: Show current positions
|
||||
description: >-
|
||||
Shows the list of positions and members holding them.
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
example:
|
||||
president: user0
|
||||
vice-president: user1
|
||||
sysadmin: user2
|
||||
treasurer:
|
||||
post:
|
||||
tags: ['positions']
|
||||
summary: Update positions
|
||||
description: >-
|
||||
Update members for each positions. Members not specified in the parameters will be removed
|
||||
from the position and unsubscribed from the exec's mailing list. New position holders will
|
||||
be subscribed to the mailing list.
|
||||
requestBody:
|
||||
description: New position holders
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
example:
|
||||
president: user0
|
||||
vice-president: user1
|
||||
sysadmin: user2
|
||||
treasurer:
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: Streaming response
|
||||
example: |
|
||||
{"status": "in progress", "operation": "update_positions_ldap"}
|
||||
{"status": "in progress", "operation": "update_exec_group_ldap"}
|
||||
{"status": "in progress", "operation": "subscribe_to_mailing_list"}
|
||||
{"status": "completed", "result": "OK"}
|
||||
"400":
|
||||
description: Failed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
/mailman/{mailing_list}/{username}:
|
||||
post:
|
||||
tags: ['mailman']
|
||||
servers:
|
||||
- url: "https://mail.csclub.uwaterloo.ca:9987/api"
|
||||
summary: subscribe a user to a mailing list
|
||||
description: Subscribes a user to a mailing list.
|
||||
parameters:
|
||||
- name: mailing_list
|
||||
in: path
|
||||
description: >-
|
||||
The name of the list to which the user will be subscribed. If there is no '@' symbol,
|
||||
then '@csclub.uwaterloo.ca' will be appended to the list name.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: username
|
||||
in: path
|
||||
required: true
|
||||
description: >-
|
||||
The user who will be subscribed to the list. If there is no '@' symbol, then '@csclub.uwaterloo.ca'
|
||||
will be appended to he username; otherwise, the given email address will be subscribed.
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
result:
|
||||
type: string
|
||||
example: OK
|
||||
"404":
|
||||
$ref: "#/components/responses/NoSuchListErrorResponse"
|
||||
"409":
|
||||
$ref: "#/components/responses/UserAlreadySubscribedErrorResponse"
|
||||
delete:
|
||||
tags: ['mailman']
|
||||
servers:
|
||||
- url: "https://mail.csclub.uwaterloo.ca:9987/api"
|
||||
summary: unsubscribe a user from a mailing list
|
||||
description: Unsubscribes a user from a mailing list.
|
||||
parameters:
|
||||
- name: mailing_list
|
||||
in: path
|
||||
description: >-
|
||||
The name of the list from which the user will be unsubscribed. If there is no '@' symbol,
|
||||
then '@csclub.uwaterloo.ca' will be appended to the list name.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: username
|
||||
in: path
|
||||
required: true
|
||||
description: >-
|
||||
The user who will be unsubscribed from the list. If there is no '@' symbol, then '@csclub.uwaterloo.ca'
|
||||
will be appended to he username; otherwise, the given email address will be unsubscribed.
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
result:
|
||||
type: string
|
||||
example: OK
|
||||
"404":
|
||||
$ref: "#/components/responses/UserAlreadySubscribedOrNoSuchListErrorResponse"
|
||||
/uwldap/{username}:
|
||||
get:
|
||||
tags: ['uwldap']
|
||||
security: []
|
||||
summary: get UWLDAP information for a user
|
||||
description: Returns information about a user from the UW LDAP directory.
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: username of the user to return
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UWLDAPUser"
|
||||
"404":
|
||||
$ref: "#/components/responses/UserNotFoundErrorResponse"
|
||||
/uwldap/updateprograms:
|
||||
post:
|
||||
tags: ['uwldap']
|
||||
summary: update CSC programs from UWLDAP
|
||||
description: |
|
||||
Sync the 'program' attribute in the CSC LDAP with the UW LDAP.
|
||||
The JSON request body may be omitted.
|
||||
parameters:
|
||||
- name: dry_run
|
||||
in: query
|
||||
description: >-
|
||||
Whether to perform a dry run or not. If true, a list of members who *would* have been
|
||||
changed is returned.
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
members:
|
||||
type: array
|
||||
description: If non-empty, only these members will be synced with UWLDAP
|
||||
default: []
|
||||
items:
|
||||
$ref: "#/components/schemas/UID"
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
description: >-
|
||||
A list of members whose programs were (or who would have been) changed.
|
||||
Each item of the list is a 3-tuple of the form (username, old_program, new_program).
|
||||
items:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: [['ctdalek', 'old_program', 'new_program']]
|
||||
/db/mysql/{username}:
|
||||
post:
|
||||
tags: ['database']
|
||||
servers:
|
||||
- url: https://caffeine.csclub.uwaterloo.ca:9987/api
|
||||
summary: Create a MySQL database
|
||||
description: Create a MySQL database for the user
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: name of the user to create MySQL database for
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
password:
|
||||
type: string
|
||||
description: The password to the database
|
||||
example: {"password": "7fUi5rQr/lcpeEj4M86ZBbwM"}
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidUsernameErrorResponse"
|
||||
"404":
|
||||
$ref: "#/components/responses/UserNotFoundErrorResponse"
|
||||
"409":
|
||||
$ref: "#/components/responses/DBAlreadyCreatedErrorResponse"
|
||||
"500":
|
||||
$ref: "#/components/responses/DBConnectionOrPermissionErrorResponse"
|
||||
/db/mysql/{username}/pwreset:
|
||||
post:
|
||||
tags: ['database']
|
||||
servers:
|
||||
- url: https://caffeine.csclub.uwaterloo.ca:9987/api
|
||||
summary: Reset MySQL database password
|
||||
description: Reset the password for a user's MySQL database
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: name of the user to reset the MySQL database password for
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
password:
|
||||
type: string
|
||||
description: The new password to the database
|
||||
example: {"password": "kM90d3G/eofIUxr9O3CQHTlP"}
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidUsernameErrorResponse"
|
||||
"404":
|
||||
$ref: "#/components/responses/UserNotFoundErrorResponse"
|
||||
"500":
|
||||
$ref: "#/components/responses/DBConnectionOrPermissionErrorResponse"
|
||||
/db/postgresql/{username}:
|
||||
post:
|
||||
tags: ['database']
|
||||
servers:
|
||||
- url: https://caffeine.csclub.uwaterloo.ca:9987/api
|
||||
summary: Create a PostgreSQL database
|
||||
description: Create a PostgreSQL database for the user
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: name of the user to create PostgreSQL database for
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
password:
|
||||
type: string
|
||||
description: The password to the database
|
||||
example: {"password": "iHxd62DC7Qt1HyYRj18P6ujS"}
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidUsernameErrorResponse"
|
||||
"404":
|
||||
$ref: "#/components/responses/UserNotFoundErrorResponse"
|
||||
"409":
|
||||
$ref: "#/components/responses/DBAlreadyCreatedErrorResponse"
|
||||
"500":
|
||||
$ref: "#/components/responses/DBConnectionOrPermissionErrorResponse"
|
||||
/db/postgresql/{username}/pwreset:
|
||||
post:
|
||||
tags: ['database']
|
||||
servers:
|
||||
- url: https://caffeine.csclub.uwaterloo.ca:9987/api
|
||||
summary: Reset PostgreSQL database password
|
||||
description: Reset the password for a user's PostgreSQL database
|
||||
parameters:
|
||||
- name: username
|
||||
in: path
|
||||
description: name of the user to reset the PostgreSQL database password for
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
password:
|
||||
type: string
|
||||
description: The new password to the database
|
||||
example: {"password": "CdPHT49iYAWzzKuhKTt2dNeu"}
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidUsernameErrorResponse"
|
||||
"404":
|
||||
$ref: "#/components/responses/UserNotFoundErrorResponse"
|
||||
"500":
|
||||
$ref: "#/components/responses/DBConnectionOrPermissionErrorResponse"
|
||||
components:
|
||||
securitySchemes:
|
||||
GSSAPIAuth:
|
||||
type: http
|
||||
scheme: negotiate
|
||||
description: |
|
||||
ceod uses SPNEGO-based authentication over HTTP, as specified in [RFC 4559](https://datatracker.ietf.org/doc/html/rfc4559).
|
||||
It is basically a base64-encoded Kerberos ticket wrapped in a HTTP header. For endpoints which make modifications
|
||||
to LDAP, the Delegate flag must also be set.
|
||||
|
||||
For example, with cURL:
|
||||
```sh
|
||||
kinit
|
||||
curl --negotiate -u : --service-name ceod --delegation always -X POST -d '{"terms":["w2022"]}' https://phosphoric-acid.csclub.uwaterloo.ca/api/members/ctdalek/renew
|
||||
```
|
||||
schemas:
|
||||
UserCN:
|
||||
type: string
|
||||
description: Full name
|
||||
example: Calum Dalek
|
||||
UID:
|
||||
type: string
|
||||
description: Username
|
||||
example: ctdalek
|
||||
Program:
|
||||
type: string
|
||||
description: Academic program
|
||||
example: MAT/Mathematics Computer Science
|
||||
Terms:
|
||||
type: array
|
||||
description: Terms for which this user was a member
|
||||
items:
|
||||
$ref: "#/components/schemas/Term"
|
||||
NonMemberTerms:
|
||||
type: array
|
||||
description: Terms for which this user was a club rep
|
||||
items:
|
||||
$ref: "#/components/schemas/Term"
|
||||
LoginShell:
|
||||
type: string
|
||||
description: Login shell
|
||||
example: /bin/bash
|
||||
UIDNumber:
|
||||
type: integer
|
||||
description: UID number
|
||||
example: 20001
|
||||
GIDNumber:
|
||||
type: integer
|
||||
description: GID number
|
||||
example: 20001
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
cn:
|
||||
$ref: "#/components/schemas/UserCN"
|
||||
uid:
|
||||
$ref: "#/components/schemas/UID"
|
||||
uid_number:
|
||||
$ref: "#/components/schemas/UIDNumber"
|
||||
gid_number:
|
||||
$ref: "#/components/schemas/GIDNumber"
|
||||
home_directory:
|
||||
type: string
|
||||
description: Home directory
|
||||
example: /users/ctdalek
|
||||
is_club:
|
||||
type: boolean
|
||||
description: Whether this user is a club account or not
|
||||
example: false
|
||||
login_shell:
|
||||
$ref: "#/components/schemas/LoginShell"
|
||||
program:
|
||||
$ref: "#/components/schemas/Program"
|
||||
positions:
|
||||
type: array
|
||||
description: Positions held by this member
|
||||
items:
|
||||
type: string
|
||||
example: president
|
||||
terms:
|
||||
$ref: "#/components/schemas/Terms"
|
||||
non_member_terms:
|
||||
$ref: "#/components/schemas/NonMemberTerms"
|
||||
forwarding_addresses:
|
||||
$ref: "#/components/schemas/ForwardingAddresses"
|
||||
UWLDAPUser:
|
||||
type: object
|
||||
properties:
|
||||
uid:
|
||||
$ref: "#/components/schemas/UID"
|
||||
cn:
|
||||
$ref: "#/components/schemas/UserCN"
|
||||
given_name:
|
||||
type: string
|
||||
description: Given name
|
||||
example: Calum
|
||||
sn:
|
||||
type: string
|
||||
description: Surname
|
||||
example: Dalek
|
||||
mail_local_addresses:
|
||||
type: array
|
||||
description: UW email addresses for this user
|
||||
items:
|
||||
type: string
|
||||
format: email
|
||||
example: ctdalek@uwaterloo.ca
|
||||
ForwardingAddresses:
|
||||
type: array
|
||||
description: Forwarding addresses in ~/.forward
|
||||
items:
|
||||
type: string
|
||||
format: email
|
||||
example: ctdalek@uwaterloo.ca
|
||||
Term:
|
||||
type: string
|
||||
description: Academic term
|
||||
example: f2021
|
||||
GroupCN:
|
||||
type: string
|
||||
description: the name of the group
|
||||
example: uwclub1
|
||||
GroupDescription:
|
||||
type: string
|
||||
description: a description of the group
|
||||
example: Club One
|
||||
responses:
|
||||
ErrorResponse: &ErrorResponse
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
UserNotFoundErrorResponse:
|
||||
<<: *ErrorResponse
|
||||
description: User not found
|
||||
GroupNotFoundErrorResponse:
|
||||
<<: *ErrorResponse
|
||||
description: Group not found
|
||||
UserAlreadySubscribedErrorResponse:
|
||||
<<: *ErrorResponse
|
||||
description: User is already subscribed
|
||||
NoSuchListErrorResponse:
|
||||
<<: *ErrorResponse
|
||||
description: Mailing list does not exist
|
||||
UserAlreadySubscribedOrNoSuchListErrorResponse:
|
||||
<<: *ErrorResponse
|
||||
description: User is already subscribed or mailing list does not exist
|
||||
DBAlreadyCreatedErrorResponse:
|
||||
<<: *ErrorResponse
|
||||
description: User already has a database
|
||||
InvalidUsernameErrorResponse:
|
||||
<<: *ErrorResponse
|
||||
description: Username contains invalid characters
|
||||
DBConnectionOrPermissionErrorResponse:
|
||||
<<: *ErrorResponse
|
||||
description: Unable to connect to database or action failed due to permissions
|
||||
|
608
docs/redoc-static.html
Normal file
608
docs/redoc-static.html
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user