Initial Commit
This commit is contained in:
commit
b736be95e1
23
API/.envrc
Normal file
23
API/.envrc
Normal file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
layout_poetry() {
|
||||
PYPROJECT_TOML="${PYPROJECT_TOML:-pyproject.toml}"
|
||||
if [[ ! -f "$PYPROJECT_TOML" ]]; then
|
||||
log_status "No pyproject.toml found. Executing \`poetry init\` to create a \`$PYPROJECT_TOML\` first."
|
||||
poetry init
|
||||
fi
|
||||
|
||||
VIRTUAL_ENV=$(poetry env info --path 2>/dev/null ; true)
|
||||
|
||||
if [[ -z $VIRTUAL_ENV || ! -d $VIRTUAL_ENV ]]; then
|
||||
log_status "No virtual environment exists. Executing \`poetry install\` to create one."
|
||||
poetry install
|
||||
VIRTUAL_ENV=$(poetry env info --path)
|
||||
fi
|
||||
|
||||
PATH_add "$VIRTUAL_ENV/bin"
|
||||
export POETRY_ACTIVE=1
|
||||
export VIRTUAL_ENV
|
||||
}
|
||||
|
||||
layout_poetry
|
2
API/.gitignore
vendored
Normal file
2
API/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
__pycache__/
|
||||
*.ignore
|
18
API/api/__main__.py
Normal file
18
API/api/__main__.py
Normal file
@ -0,0 +1,18 @@
|
||||
from litestar.response.redirect import Redirect
|
||||
import uvicorn
|
||||
from litestar import Litestar, get
|
||||
|
||||
|
||||
@get("/")
|
||||
async def index() -> Redirect:
|
||||
return Redirect("/schema/swagger")
|
||||
|
||||
|
||||
@get("/books/{book_id:int}")
|
||||
async def get_book(book_id: int) -> dict[str, int]:
|
||||
return {"book_id": book_id}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = Litestar([index, get_book])
|
||||
uvicorn.run(__name__ + ":app", port=5000, log_level="info")
|
13
API/docker-compose.yml
Normal file
13
API/docker-compose.yml
Normal file
@ -0,0 +1,13 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres
|
||||
restart: always
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
POSTGRES_PASSWORD: example
|
||||
volumes:
|
||||
- ./docker-entrypoint-sql:/docker-entrypoint-initdb.d
|
||||
- ./postgres-data:/var/lib/postgresql/data
|
17
API/docker-entrypoint-sql/init-user-db.sql
Executable file
17
API/docker-entrypoint-sql/init-user-db.sql
Executable file
@ -0,0 +1,17 @@
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
CREATE USER api WITH LOGIN PASSWORD 'api';
|
||||
CREATE DATABASE api OWNER api;
|
||||
GRANT ALL PRIVILEGES ON DATABASE api TO api;
|
||||
\connect api api;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
id PRIMARY KEY DEFAULT uuid_generate_v4()
|
||||
title varchar(40),
|
||||
summary varchar(160),
|
||||
content text,
|
||||
published date,
|
||||
updated date,
|
||||
tags varchar(10)[],
|
||||
UNIQUE(title)
|
||||
);
|
1515
API/poetry.lock
generated
Normal file
1515
API/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
API/pyproject.toml
Normal file
16
API/pyproject.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[tool.poetry]
|
||||
name = "whitelist-api"
|
||||
version = "0.1.0"
|
||||
description = "A whitelist API for the Asgard Eternal Squad Server"
|
||||
authors = ["Price Hiller <price@orion-technologies.io>"]
|
||||
license = "GPLv3"
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.11"
|
||||
psycopg = {extras = ["binary"], version = "^3.1.12"}
|
||||
litestar = {extras = ["jwt", "opentelemetry", "standard"], version = "^2.2.1"}
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
209
SPEC.md
Normal file
209
SPEC.md
Normal file
@ -0,0 +1,209 @@
|
||||
# Squad Whitelist Management
|
||||
|
||||
|
||||
## Discord Bot
|
||||
|
||||
### Commands
|
||||
|
||||
- **/link**
|
||||
- Example: `/link 7312312312395`
|
||||
- Links user's discord ID with their provided steam64
|
||||
- If linked to another discord id, reject
|
||||
- Use the user's discord username for their username in the API
|
||||
|
||||
- **/group-link**
|
||||
- Example: `/group-link @Odin {group-uuid}`
|
||||
- Links a Group on the API with a given discord ID for the role
|
||||
- If the Discord ID already exists, inform about it but allow
|
||||
|
||||
- **/list-groups**
|
||||
- Example: `/list-groups`
|
||||
- Outputs:
|
||||
- Groups with Associated Discord Role
|
||||
- Example: `@Odin | https://my-api.com/org/asgard/group-uuid`
|
||||
### Events
|
||||
|
||||
- `on-member-update`
|
||||
- For each member, look at the change in discord roles
|
||||
- If they had a role added to them that's a linked group, add them to the Group
|
||||
- If they don't have a linked Steam64, ping them in a channel to do so
|
||||
|
||||
- `on-startup`
|
||||
- Hit up API for all members of linked roles
|
||||
- Check if the members are in those roles and modify as needed
|
||||
|
||||
## API
|
||||
|
||||
|
||||
### Functionality
|
||||
|
||||
|
||||
#### Generate Remote Admin List
|
||||
|
||||
- Capability to export as remote admin list
|
||||
- Can be applied to an entire Org
|
||||
- Example: `https://api-url.com/org/asgard?reserved`
|
||||
- Example: https://api-url.com/group/group-uuid?startvote&changemap&pause
|
||||
- Query params
|
||||
- startvote
|
||||
- changemap
|
||||
- pause
|
||||
- cheat
|
||||
- private
|
||||
- balance
|
||||
- chat
|
||||
- kick
|
||||
- ban
|
||||
- config
|
||||
- cameraman
|
||||
- immune
|
||||
- manageserver
|
||||
- featuretest
|
||||
- reserve
|
||||
- demos
|
||||
- clientdemos
|
||||
- debug
|
||||
- teamchange
|
||||
- forceteamchange
|
||||
- canseeadminchat
|
||||
|
||||
- Example:
|
||||
- Query: `https://api-url.com/org/{org-name}/{group-uuid}`
|
||||
- Output: `Group={group-uuid}:{query-params} // {group-name}`
|
||||
|
||||
## Data
|
||||
|
||||
### Users
|
||||
|
||||
- Table Name: `USERS`
|
||||
| Key | Type | Constraints | Description |
|
||||
| - | - | - | - |
|
||||
| id | Primary Key | | Steam64 |
|
||||
| username | String | | |
|
||||
| password | String? | | Salted Hash, don't allow login if null. Owning tenant can set Password. |
|
||||
| discord_id | Int? | | |
|
||||
| superuser | bool | | |
|
||||
|
||||
### Organizations
|
||||
|
||||
- Table Name: `ORGS`
|
||||
| Key | Type | Constraints | Description |
|
||||
| - | - | - | - |
|
||||
| id | UUID4 | | |
|
||||
| name | String | Unique | |
|
||||
| owner_id | `USERS.ID` | | |
|
||||
| discord_server_id | Int? | | |
|
||||
|
||||
### Organization Members
|
||||
|
||||
- Table Name: `ORG_MEMBERS`
|
||||
| Key | Type | Constraints | Description |
|
||||
| - | - | - | - |
|
||||
| org_id | `ORGS.ID` | | |
|
||||
| user_id | `USERS.ID` | | |
|
||||
| discord_server_id | Int? | | |
|
||||
|
||||
Primary key is composite key of `org_id` + `user_id`
|
||||
|
||||
### Groups
|
||||
|
||||
- Table Name: `GROUPS`
|
||||
| Key | Type | Constraints | Description |
|
||||
| - | - | - | - |
|
||||
| id | UUID4 | Primary Key | |
|
||||
| name | String | | Group Name |
|
||||
| remote_import_url | String? | | The remote url to a remote admin list hosted elsewhere |
|
||||
| owner_id | `USERS.ID` | | |
|
||||
| max_members | Int? | | Max number of members allowed as part of this group. If null, unlimited members |
|
||||
| org_id | `ORGS.ID` | | |
|
||||
| discord_role_id | Int? | | |
|
||||
|
||||
### Group Members
|
||||
|
||||
- Table Name: `GROUP_MEMBERS`
|
||||
| Key | Type | Constraints | Description |
|
||||
| - | - | - | - |
|
||||
| user | `ORG_MEMBERS.user_id` | | |
|
||||
| org_id | `ORGS.ID` | | |
|
||||
| group | `GROUPS.ID` | | |
|
||||
| nick_name | String | | |
|
||||
| member | bool | | |
|
||||
| owner | bool | | |
|
||||
| perm_manage_mods | bool | | |
|
||||
| perm_manage_perms | bool | | |
|
||||
| perm_manage_users | bool | | |
|
||||
| perm_manage_tags | bool | | |
|
||||
| perm_manage_import | bool | | Allow user to specify a remote admin list to use for the Group |
|
||||
|
||||
### Group Squad Perms
|
||||
|
||||
- Table Name: `GROUP_SQUAD_PERMS`
|
||||
| Key | Type | Constraints | Description |
|
||||
| - | - | - | - |
|
||||
| group_id | `GROUP.ID` | Primary Key | |
|
||||
| perm_changemap | bool | | Allowed to change the current map |
|
||||
| perm_pause | bool | | Allowed to pause server gameplay |
|
||||
| perm_cheat | bool | | Allowed to use server cheat commands |
|
||||
| perm_private | bool | | Allowed to password protect the server |
|
||||
| perm_balance | bool | | Allowed to ignore team balance |
|
||||
| perm_chat | bool | | Allowed to access admin chat and make server broadcasts |
|
||||
| perm_kick | bool | | Allowed to kick players |
|
||||
| perm_ban | bool | | Allowed to ban players |
|
||||
| perm_config | bool | | Allowed to change server config |
|
||||
| perm_cameraman | bool | | Allowed to admin spectate mode |
|
||||
| perm_immune | bool | | Allowed to cannot be kicked / banned |
|
||||
| perm_manageserver | bool | | Allowed to shutdown server |
|
||||
| perm_featuretest | bool | | Allowed to any features added for testing by dev team |
|
||||
| perm_reserve | bool | | Allowed to reserve slot |
|
||||
| perm_demos | bool | | Allowed to record Demos on the server side via admin commands |
|
||||
| perm_clientdemos | bool | | Allowed to record Demos on the client side via commands or the replay UI |
|
||||
| perm_debug | bool | | Allowed to Show admin stats command and other debugging info |
|
||||
| perm_teamchange | bool | | Allowed to no timer limits on team change |
|
||||
| perm_forceteamchange | bool | | Allowed to can issue the ForceTeamChange command |
|
||||
| perm_canseeadminchat | bool | | Allowed to this group can see the admin chat and teamkill/admin-join notifications |
|
||||
|
||||
### TAGS
|
||||
|
||||
- Table Name: `TAGS`
|
||||
| Key | Type | Constraints | Description |
|
||||
| - | - | - | - |
|
||||
| name | String | Must be unique when combined with `org_id` | |
|
||||
| org_id | `ORG.ID` | Must be unique when combined with `name` | |
|
||||
|
||||
- Both `Org` & `Name` together must be unique, the combo of them is unique
|
||||
|
||||
### Group Tags
|
||||
|
||||
- Table Name: `GROUP_TAGS`
|
||||
| Key | Type | Constraints | Description |
|
||||
| - | - | - | - |
|
||||
| id | UUID4 | Primary Key | |
|
||||
| group_id | `GROUP.ID` | Must be unique when combined with `tag` | |
|
||||
| tag_id | `TAGS.ID` | Must be unique when combined with `group` | |
|
||||
|
||||
- Together both `GROUP` & `TAG` create primary key
|
||||
- `SELECT * FROM GROUP_TAGS WHERE GROUP = "GROUP.ID" AND TAG = "TAG.ID"`
|
||||
|
||||
- Org
|
||||
- Single Owner
|
||||
- Groups
|
||||
- Group: whitelist-{group-id}
|
||||
- Tags: vanilla
|
||||
- Single Owner
|
||||
- Perms
|
||||
- Group
|
||||
- Manage Users (Add or Remove Users)
|
||||
- Manage Moderators (Allow other users to manage the group)
|
||||
- Manage Remote Import (Allowed to set a remote import)
|
||||
- Manage Tags (Allowed to manage tags)
|
||||
- Squad
|
||||
- Reserve
|
||||
- Demos
|
||||
- Kick
|
||||
- Ban
|
||||
- Etc.
|
||||
|
||||
`https://api-url.com/export/squad-admin-list/org/asgard/groups/group-uuid`
|
||||
`https://api-url.com/export/squad-admin-list/org/asgard`
|
||||
`https://api-url.com/export/squad-admin-list/org/asgard?tag=tactical`
|
||||
`https://api-url.com/export/squad-admin-list/org/asgard?tag=tactical&tag=vanilla`
|
Loading…
Reference in New Issue
Block a user