Created API token system for programmatic access: - API tokens table with organization scoping - ApiTokens context for token management - ApiAuth plug for Bearer token authentication - Tokens shown once on creation, then hashed for security Implemented RESTful API v1 endpoints: - SitesController: CRUD operations for sites - DevicesController: CRUD operations for devices - All operations scoped to authenticated organization - Proper authorization checks via site ownership Technical details: - Tokens prefixed with "towerops_" for easy identification - SHA-256 hashing for token storage - Last used timestamp tracking (async update) - Optional token expiration support - Standard JSON error responses (40x status codes) Routes: - /api/v1/sites (GET, POST, PATCH, DELETE) - /api/v1/devices (GET, POST, PATCH, DELETE) Authentication: - Authorization: Bearer towerops_xxxxx header required - Returns 401 for invalid/expired tokens - Returns 403 for unauthorized resource access
22 lines
628 B
Elixir
22 lines
628 B
Elixir
defmodule Towerops.Repo.Migrations.CreateApiTokens do
|
|
use Ecto.Migration
|
|
|
|
def change do
|
|
create table(:api_tokens, primary_key: false) do
|
|
add :id, :binary_id, primary_key: true
|
|
|
|
add :organization_id, references(:organizations, type: :binary_id, on_delete: :delete_all),
|
|
null: false
|
|
|
|
add :name, :string, null: false
|
|
add :token_hash, :string, null: false
|
|
add :last_used_at, :utc_datetime
|
|
add :expires_at, :utc_datetime
|
|
|
|
timestamps(type: :utc_datetime)
|
|
end
|
|
|
|
create index(:api_tokens, [:organization_id])
|
|
create unique_index(:api_tokens, [:token_hash])
|
|
end
|
|
end
|