Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 41 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,51 @@ make test-all
## Development Scripts
Helper scripts are located in the `scripts/` directory.

### Create Development User
Seeds a user into the DB and generates a valid JWT for testing.
### Create User
Seeds or updates a user in the database and prints a JWT for that user. `--email` is required; the other fields have defaults.
```bash
go run scripts/create_dev_user/main.go
go run scripts/create_user/main.go --email dev@example.com --role dev
```

### Generate Token
Manually generates a JWT for an existing user (by email).
### Create Bot Token
Creates a bot token in the database and prints the full `token_id.secret` value once for use with the `X-Bot-Token` header. `--name` and `--created-by` are required; `--hours 0` means the token does not expire.
```bash
go run scripts/generate_token/main.go
go run scripts/create_bot_token/main.go --name my-bot --created-by 00000000-0000-0000-0000-000000000001 --hours 24
```

### Run DB-Connected Scripts Without Go in the API Image
If you are running the API and Postgres with Docker Compose, the API container does not include the Go toolchain. To run local Go scripts that need database access, start a one-off Go container on the same Compose network and mount the repository into it.

Current local network:
```bash
api_default
```

Example:
```bash
docker run --rm \
--network api_default \
-v "$PWD":/app \
-w /app \
--env-file .env \
golang:1.25 \
go run scripts/create_user/main.go --email dev@example.com --role dev
```

Bot token example:
```bash
docker run --rm \
--network api_default \
-v "$PWD":/app \
-w /app \
--env-file .env \
golang:1.25 \
go run scripts/create_bot_token/main.go --name my-bot --created-by 00000000-0000-0000-0000-000000000001 --hours 24
```

If your Compose project name is different, the network name will usually be `<project>_default`. You can check it with:
```bash
docker network ls
```

## Project Structure
Expand Down
10 changes: 5 additions & 5 deletions docs/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -71699,8 +71699,8 @@
"insert_into_table": null
},
{
"text": "\nSELECT token_id, token_hash, name, created_by, created_at, last_used_at, expires_at, is_active FROM bot_tokens WHERE token_hash = $1 AND is_active = true",
"name": "GetBotTokenByHash",
"text": "\nSELECT token_id, token_hash, name, created_by, created_at, last_used_at, expires_at, is_active FROM bot_tokens WHERE token_id = $1",
"name": "GetBotTokenByID",
"cmd": ":one",
"columns": [
{
Expand Down Expand Up @@ -71916,7 +71916,7 @@
{
"number": 1,
"column": {
"name": "token_hash",
"name": "token_id",
"not_null": true,
"is_array": false,
"comment": "",
Expand All @@ -71933,11 +71933,11 @@
"type": {
"catalog": "",
"schema": "",
"name": "text"
"name": "uuid"
},
"is_sqlc_slice": false,
"embed_table": null,
"original_name": "token_hash",
"original_name": "token_id",
"unsigned": false,
"array_dims": 0
}
Expand Down
25 changes: 21 additions & 4 deletions docs/swagger/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ const docTemplate = `{
"BotToken": []
}
],
"description": "Returns information about the current bot token",
"description": "Returns information about the current bot token. Authenticate with X-Bot-Token: <token_id>.<secret>, for example: curl -H 'X-Bot-Token: <token>' http://localhost:8080/api/v1/bot/me",
"consumes": [
"application/json"
],
Expand All @@ -233,7 +233,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handler.BotTokenResponse"
"$ref": "#/definitions/handler.BotMeResponse"
}
},
"401": {
Expand Down Expand Up @@ -287,7 +287,7 @@ const docTemplate = `{
"CookieAuth": []
}
],
"description": "Creates a new bot token (requires faculty role)",
"description": "Creates a new bot token (requires faculty role). The raw token is returned only once and must be stored by the caller.",
"consumes": [
"application/json"
],
Expand Down Expand Up @@ -1821,7 +1821,24 @@ const docTemplate = `{
"type": "string"
},
"token": {
"description": "Only on creation",
"description": "Only on creation. Store it immediately; it is not returned again.",
"type": "string"
},
"token_id": {
"type": "string"
}
}
},
"handler.BotMeResponse": {
"type": "object",
"properties": {
"auth_type": {
"type": "string"
},
"expires_at": {
"type": "string"
},
"name": {
"type": "string"
},
"token_id": {
Expand Down
27 changes: 22 additions & 5 deletions docs/swagger/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@
"BotToken": []
}
],
"description": "Returns information about the current bot token",
"description": "Returns information about the current bot token. Authenticate with X-Bot-Token: <token_id>.<secret>, for example: curl -H 'X-Bot-Token: <token>' http://localhost:8080/api/v1/bot/me",
"consumes": [
"application/json"
],
Expand All @@ -227,7 +227,7 @@
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handler.BotTokenResponse"
"$ref": "#/definitions/handler.BotMeResponse"
}
},
"401": {
Expand Down Expand Up @@ -281,7 +281,7 @@
"CookieAuth": []
}
],
"description": "Creates a new bot token (requires faculty role)",
"description": "Creates a new bot token (requires faculty role). The raw token is returned only once and must be stored by the caller.",
"consumes": [
"application/json"
],
Expand Down Expand Up @@ -1815,7 +1815,24 @@
"type": "string"
},
"token": {
"description": "Only on creation",
"description": "Only on creation. Store it immediately; it is not returned again.",
"type": "string"
},
"token_id": {
"type": "string"
}
}
},
"handler.BotMeResponse": {
"type": "object",
"properties": {
"auth_type": {
"type": "string"
},
"expires_at": {
"type": "string"
},
"name": {
"type": "string"
},
"token_id": {
Expand Down Expand Up @@ -1883,4 +1900,4 @@
"in": "cookie"
}
}
}
}
20 changes: 16 additions & 4 deletions docs/swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,18 @@ definitions:
name:
type: string
token:
description: Only on creation
description: Only on creation. Store it immediately; it is not returned again.
type: string
token_id:
type: string
type: object
handler.BotMeResponse:
properties:
auth_type:
type: string
expires_at:
type: string
name:
type: string
token_id:
type: string
Expand Down Expand Up @@ -360,14 +371,15 @@ paths:
get:
consumes:
- application/json
description: Returns information about the current bot token
description: 'Returns information about the current bot token. Authenticate with X-Bot-Token:
<token_id>.<secret>, for example: curl -H ''X-Bot-Token: <token>'' http://localhost:8080/api/v1/bot/me'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handler.BotTokenResponse'
$ref: '#/definitions/handler.BotMeResponse'
"401":
description: Unauthorized
schema:
Expand Down Expand Up @@ -403,7 +415,7 @@ paths:
post:
consumes:
- application/json
description: Creates a new bot token (requires faculty role)
description: Creates a new bot token (requires faculty role). The raw token is returned only once and must be stored by the caller.
parameters:
- description: Token data
in: body
Expand Down
20 changes: 10 additions & 10 deletions internal/database/mocks/Querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions internal/database/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion internal/database/querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 17 additions & 3 deletions internal/database/queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,21 @@ ON CONFLICT (uid, eid) DO UPDATE SET is_attending = $3;
DELETE FROM event_registrations WHERE uid = $1 AND eid = $2;

-- name: IsEventAdmin :one
SELECT is_admin FROM event_registrations WHERE uid = $1 AND eid = $2;
SELECT EXISTS (
SELECT 1
FROM event_registrations er
WHERE er.uid = $1
AND er.eid = $2
AND er.is_admin = TRUE
)
OR EXISTS (
SELECT 1
FROM event_hosting eh
JOIN org_members om ON om.oid = eh.oid
WHERE eh.eid = $2
AND om.uid = $1
AND om.is_admin = TRUE
);

-- name: GetUserEvents :many
SELECT e.*, er.is_attending, er.is_admin, er.date_registered
Expand All @@ -134,8 +148,8 @@ ORDER BY e.event_time DESC;

-- Bot Token Queries

-- name: GetBotTokenByHash :one
SELECT * FROM bot_tokens WHERE token_hash = $1 AND is_active = true;
-- name: GetBotTokenByID :one
SELECT * FROM bot_tokens WHERE token_id = $1;

-- name: CreateBotToken :one
INSERT INTO bot_tokens (token_hash, name, created_by, expires_at)
Expand Down
24 changes: 19 additions & 5 deletions internal/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading