Initial skills documentation — 25 categories, all SKILL.md + references + scripts
This commit is contained in:
+103
@@ -0,0 +1,103 @@
|
||||
# UniFi MongoDB Admin Schema (v10.0.162)
|
||||
|
||||
## Database: `ace`
|
||||
|
||||
### `admin` Collection — Admin Accounts
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|---|---|---|---|
|
||||
| `_id` | ObjectId | auto | MongoDB ID |
|
||||
| `name` | string | yes | Display name |
|
||||
| `email` | string | yes | Login email (username) |
|
||||
| `x_shadow` | string | yes | SHA-512 crypt password hash (`$6$salt$hash`) |
|
||||
| `time_created` | int32 (epoch) | yes | Account creation timestamp |
|
||||
| `last_site_name` | string | no | Last site accessed (set on login) |
|
||||
| `super_site_permissions` | array | **yes** | Must be `["super"]` for super admin |
|
||||
| `super_site_role` | string | **yes** | Must be `"super"` |
|
||||
| `is_super` | bool | **yes** | Must be `true` |
|
||||
| `last_login_timestamp` | int64 (epoch ms) | auto | Set on login |
|
||||
| `last_login_ip` | string | auto | Set on login |
|
||||
| `ui_settings` | object | auto | `{"preferredLanguage":"en"}` etc. |
|
||||
| `ui_version` | string | auto | UI version string |
|
||||
| `email_alert_enabled` | bool | no | Email notifications |
|
||||
| `is_owner` | bool | auto | Set to `true` on first admin |
|
||||
|
||||
**Critical:** Without `super_site_permissions: ["super"]`, `super_site_role: "super"`, and `is_super: true`, the admin will log in but see an empty dashboard even if the database has devices and configs.
|
||||
|
||||
### `privilege` Collection — Site Access Control
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|---|---|---|---|
|
||||
| `_id` | ObjectId | auto | MongoDB ID |
|
||||
| `admin_id` | ObjectId | **yes** | References `admin._id` — MUST be ObjectId, NOT string |
|
||||
| `site_id` | ObjectId | **yes** | References `site._id` — MUST be ObjectId, NOT string |
|
||||
| `role` | string | **yes** | `"SUPER_ADMIN"` or `"ADMIN"` |
|
||||
| `permissions` | array | yes | `["ALL"]` for full access |
|
||||
| `is_super` | bool | **yes** | `true` for super admin |
|
||||
|
||||
**Critical pitfall:** Using `.str` on ObjectIds when inserting privileges (e.g., `admin._id.str` instead of `admin._id`) creates string references that don't match. The admin logs in but sees NO data — exactly the "no content on screen" symptom.
|
||||
|
||||
### `site` Collection
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `_id` | ObjectId | Site ID |
|
||||
| `name` | string | `"super"` or `"default"` |
|
||||
| `desc` | string | Description |
|
||||
| `attr_hidden_id` | string | Internal site key |
|
||||
| `attr_hidden` | bool | `true` for "super" site |
|
||||
| `attr_no_delete` | bool | `true` for both default sites |
|
||||
|
||||
A fresh `jacobalberty/unifi` deploy creates two sites automatically: `"super"` (hidden) and `"default"`.
|
||||
|
||||
### Full Admin Creation Script
|
||||
|
||||
```javascript
|
||||
db = db.getSiblingDB("ace");
|
||||
|
||||
// 1. Generate hash externally: openssl passwd -6 'password'
|
||||
var hash = "$6$salt$hash";
|
||||
var now = Math.floor(new Date().getTime() / 1000);
|
||||
|
||||
// 2. Create admin
|
||||
var result = db.admin.insertOne({
|
||||
name: "Admin Name",
|
||||
email: "admin@example.com",
|
||||
x_shadow: hash,
|
||||
time_created: now,
|
||||
last_site_name: "default",
|
||||
super_site_permissions: ["super"],
|
||||
super_site_role: "super",
|
||||
is_super: true
|
||||
});
|
||||
|
||||
// 3. Create privileges for ALL sites
|
||||
var admin = db.admin.findOne({email: "admin@example.com"});
|
||||
var sites = db.site.find({}).toArray();
|
||||
sites.forEach(function(site) {
|
||||
db.privilege.insertOne({
|
||||
admin_id: admin._id, // ObjectId, NOT .str
|
||||
site_id: site._id, // ObjectId, NOT .str
|
||||
role: "SUPER_ADMIN",
|
||||
permissions: ["ALL"],
|
||||
is_super: true
|
||||
});
|
||||
});
|
||||
|
||||
print("Admin created: " + admin._id);
|
||||
print("Privileges: " + db.privilege.count());
|
||||
```
|
||||
|
||||
### Verifying Permissions After Login
|
||||
|
||||
```bash
|
||||
# Login
|
||||
curl -sk -c /tmp/uf-cookie -X POST https://localhost:8443/api/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin@example.com","password":"password"}'
|
||||
|
||||
# Check self — should show is_super:true
|
||||
curl -sk -b /tmp/uf-cookie https://localhost:8443/api/self | python3 -m json.tool
|
||||
```
|
||||
|
||||
If `is_super` is `false` or `super_site_permissions` is `[]`, the MongoDB update didn't take — likely the admin document was overwritten by the login process or the update used the wrong query.
|
||||
Reference in New Issue
Block a user