104 Commits

Author SHA1 Message Date
grossmj
e0260f27c7
fix(rbac): annotate query variables with Select type for better type checking 2026-10-08 18:39:20 +02:00
Mark Paronyan
852dc5be0f
feat(api): add exact-match name filter to list endpoints 2026-10-07 13:40:34 +03:00
Cristi
207db770c6 feat(image-manager): Add support for nested image folders and appliance compatibility checks 2026-10-05 18:49:21 +03:00
Mark Paronyan
306d8fbde4
refactor: remove unused imports 2026-10-03 19:43:58 +03:00
Mark Paronyan
b78672a8ca style: sort imports in the new image management modules 2026-10-02 12:43:26 +03:00
Mark Paronyan
b9cdac487c style: sort imports in compute, db and services modules 2026-10-02 12:43:26 +03:00
Mark Paronyan
a77e06b907
Merge branch '3.1' into ruff/trivia-fixups 2026-10-01 19:58:02 +03:00
Mark Paronyan
06899c92fc
refactor: use iterable unpacking instead of concatenation 2026-10-01 19:57:46 +03:00
grossmj
1456d36bf0
chore(tests): fix mypy errors 2026-10-01 15:22:17 +02:00
Jeremy Grossmann
a2cdc14a25
Merge branch '3.1' into image-manager-out-of-sync 2026-10-01 14:44:24 +02:00
Jeremy Grossmann
e90be1ebac
Merge pull request #2930 from markparonyan/mypy-db-templates-images
fix(typing): resolve the remaining mypy errors (18 modules)
2026-09-29 21:37:14 +02:00
Mark Paronyan
36945daa83
fix(typing): resolve mypy errors in db.repositories.computes 2026-09-29 22:02:22 +03:00
Mark Paronyan
2fe4e39715
fix(typing): resolve mypy errors in db.repositories.api_keys 2026-09-29 22:02:22 +03:00
Mark Paronyan
8f7b895cf4
fix(typing): resolve mypy errors in db.repositories.pools 2026-09-29 22:02:21 +03:00
Mark Paronyan
fa9d1cde80
fix(typing): resolve mypy errors in db.repositories.rbac 2026-09-29 22:02:20 +03:00
Mark Paronyan
323055c486
fix(typing): resolve mypy errors in api.routes.controller.templates 2026-09-29 22:02:20 +03:00
Mark Paronyan
81474b4651
fix(typing): resolve mypy errors in db.repositories.images 2026-09-29 22:02:19 +03:00
Mark Paronyan
c048124c21
fix(typing): resolve mypy errors in db.repositories.llm_model_configs 2026-09-29 22:02:19 +03:00
Mark Paronyan
b1d13edd2d
fix(typing): resolve mypy errors in api.routes.controller.users 2026-09-29 22:02:18 +03:00
Mark Paronyan
8e96f18429
fix(typing): resolve mypy errors in db.repositories.users 2026-09-29 22:02:18 +03:00
Mark Paronyan
dfea615248
fix(typing): resolve mypy errors in services.templates 2026-09-29 21:48:32 +03:00
Mark Paronyan
e6053dd0a8
fix(typing): resolve mypy errors in services.computes 2026-09-29 09:23:14 +03:00
Cristi
42d30651da Merge origin/3.1 into image-manager-out-of-sync
Preserve image reconciliation, locking, and regression coverage while integrating upstream release, dependency, typing, and formatting updates. Align feature code with the new Ruff checks.
2026-09-28 23:16:24 +03:00
Cristi
046dff4d08 fix(images): reconcile the image inventory with filesystem changes 2026-09-28 16:01:36 +03:00
Mark Paronyan
a0450b6bce
refactor: ruff autofixes 2026-09-27 15:55:10 +03:00
YueGuobin
8a8314ab29
fix: dedupe and report automatic template creation from images
install_appliances_from_image relied on the name+version pair check in
TemplatesService, so the same appliance reached through a second image
(the CSR1000v case) created a second template sharing the name. The auto
path now skips when any template with the same name exists, whatever the
version, and returns a manifest of created and skipped candidates;
POST /images/install replies 200 with that manifest instead of an empty
204, and the image_install MCP tool surfaces it.
2026-08-26 00:04:57 +08:00
Jeremy Grossmann
909ccf8fcd
Merge branch '3.1' into base-configs-3.0 2026-08-08 22:11:39 +02:00
YueGuobin
8ecc35193d
feat: API key lifecycle — revoke/restore/delete
- POST /{id}/revoke: 吊销, revoked=True, 立即失效
- POST /{id}/restore: 恢复, revoked=False, 重新生效
- DELETE /{id}:       永久删除, 不可逆
- 列表接口显示所有 key 包括已吊销的
- 认证时过滤 revoked=False
2026-06-11 23:32:19 +08:00
YueGuobin
062e8dfbc4
chore: Remove unused revoke_api_key from repository 2026-06-11 23:28:43 +08:00
YueGuobin
a79bc7dd20
feat: Add API Key support for MCP authentication
- New db model: api_keys table with bcrypt-hashed keys
- New API: POST/GET/DELETE /v3/access/api-keys endpoints
- MCP _resolve_token: validates API keys, resolves to 5-min JWT
- API keys inherit the creating user's RBAC permissions
- MCP auth supports both JWT (24h) and API key (permanent) tokens
2026-06-11 22:54:03 +08:00
Cristi
03b3078271 fix: revert duplicate image check to fix failing tests 2026-06-06 15:04:06 +03:00
Cristi
1e40fa1b70 fix (templates): Add ordering to handle the duplicate cases gracefully 2026-06-06 14:46:27 +03:00
Cristi
da3a34144b fix(templates): Database error detected when saving a template with a disk image change 2026-06-06 14:21:15 +03:00
Jeremy Grossmann
12347b24aa
Merge branch '3.1' into base-configs-3.0 2026-06-01 11:39:40 +02:00
YueGuobin
f3aaa902c6
Fix double deletion issue in remove_resource_from_pool
Remove duplicate delete_resource call from remove_resource_from_pool since
the API layer already handles resource deletion. This prevents conflicts
where the API layer tries to delete a resource that was already deleted by
the repository layer.

The complete fix is now:
- remove_resource_from_pool: Only removes resource from pool (API handles deletion)
- delete_resource_pool: Deletes all resource records before deleting pool
2026-06-01 12:46:15 +08:00
YueGuobin
d2848a600e
Complete fix: delete resource records when deleting resource pool
This completes the fix from PR #2315 by ensuring that when a resource
pool is deleted, all associated resource records are also deleted from
the resources table, preventing orphaned resource records.

Changes:
- Modified delete_resource_pool() to first delete all resource records
  in the pool before deleting the pool itself
- This complements the existing fix in remove_resource_from_pool() which
  handles single resource removal
2026-06-01 12:43:56 +08:00
YueGuobin
fcb76a4b01
Apply fix from PR #2315: delete resource from resource table when removing from pool 2026-06-01 12:30:03 +08:00
YueGuobin
2efcc619b1
perf: batch RBAC permission checking for GET /projects
Replace per-project check_user_has_privilege calls with a single
batch method that performs 3 fixed DB queries regardless of project
count. Reduces GET /projects response time for 10000 projects from
~12s to ~290ms (40x improvement).
2026-05-27 13:27:35 +08:00
YueGuobin
ca5db7567c
fix: check both regular ACEs and resource pool ACEs for proper access control
This fix addresses a critical issue in the RBAC permission checking logic
introduced in PR #2750. When a project is shared through a resource pool,
both the project creator (with regular ACEs like "All endpoints") and the
shared user (with resource pool ACEs) should be able to see the project.

Changes:
- Modified `check_user_has_privilege` in `gns3server/db/repositories/rbac.py`
- Changed from if-elif (exclusive) to sequential (inclusive) checking
- Now checks regular ACEs first, then resource pool ACEs
- Both types of ACEs can grant access (OR logic instead of XOR)

This fixes the scenario where:
1. user100 has "All endpoints" ACE and creates a project
2. user100 shares the project via resource pool with user200
3. Both users should see the project (user100 via regular ACE, user200 via pool ACE)

Related to PR #2750 - RBAC user isolation implementation.
2026-05-27 00:17:52 +08:00
YueGuobin
5e4d9e057e
refactor: add efficient get_aces_for_path method for resource pool checks
Add a new repository method get_aces_for_path() that:
- Queries ACEs for a specific path at database level (more efficient)
- Preloads related user, group, and role objects to prevent 500 errors
- Keeps original get_aces() method unchanged to avoid performance impact

This improves both performance and code clarity for resource pool
deletion safety checks.
2026-05-26 12:59:37 +08:00
Volobue
b74ebafb8f api endpoint implemented 2026-05-25 20:07:05 +03:00
YueGuobin
a6dcab8110
fix: avoid AttributeError when password is not provided in compute update
When updating a compute without providing a password field,
compute_update.password is None and calling .get_secret_value()
on it causes a 500 Internal Server Error. Only set the password
in update_values when a password is actually provided.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-02 15:37:46 +08:00
UmmmAGoodName
4cf8b79692 Fix addressing issue #2005 including tests 2026-04-05 21:51:52 +02:00
YueGuobin
bbe57f34b9 feat(llm): hide api_key from all API responses and document max_tokens as reserved
Security Enhancement:
   - API keys are now always filtered to null in all LLM config API responses
   - Created LLMModelConfigDataWithoutSecret schema for response validation
   - Added _filter_api_key_from_config() helper in API routes
   - Modified repository to always hide api_key in get_user_effective_configs()
   - Update/create operations still accept and store api_key securely

   Documentation Updates:
   - Updated API key visibility section to reflect new security policy
   - Updated all response examples to show api_key as null
   - Marked max_tokens field as reserved for future use
   - Added "Reserved Fields" section explaining unused fields

   This defense-in-depth approach prevents API keys from being leaked through
   logs, browser devtools, or network monitoring.
2026-03-14 13:12:22 +08:00
YueGuobin
5e9ec23a45 style: remove unused imports and fix E712 comparisons in llm_model_configs.py
Remove 5 unused imports flagged by ruff F401:
- sqlalchemy.func, sqlalchemy.or_
- sqlalchemy.ext.asyncio.AsyncSession
- sqlalchemy.orm.selectinload
- json

Fix 4 E712 errors - avoid equality comparisons to True:
- Use models.LLMModelConfig.is_default instead of == True

Co-Authored-By: Yue Guobin <yueguobin@outlook.com>
2026-03-10 01:10:19 +08:00
Guobin Yue
87f8f22524
Merge branch '3.0' into feature/ai-copilot-bridge 2026-03-06 01:42:47 +08:00
grossmj
4606613673
Fix image handling 2026-03-05 12:38:28 +08:00
YueGuobin
7a2d15cb64 feat: clarify default LLM model config selection logic
Updated documentation and implementation to clearly define the priority order for selecting default LLM model configurations. The logic now explicitly states:
1. User's config marked with `is_default: true` (highest priority)
2. Group's config marked with `is_default: true`
3. First config in the list (user configs come before group configs)

This ensures consistent behavior between the API documentation and the actual implementation in the repository code.
2026-03-03 22:56:21 +08:00
YueGuobin
f4723cd083 docs: restructure LLM model configs API documentation for nested config object
Update API documentation to reflect new nested `config` object structure in LLM model configurations endpoints. The response format now encapsulates provider-specific fields (provider, base_url, model, temperature, api_key, max_tokens) within a `config` object, while moving ownership metadata (user_id, group_id, is_default, version, created_at, updated_at) to the top level. This aligns the user-facing endpoints with the group configuration structure and improves API consistency.
2026-03-03 22:47:36 +08:00
YueGuobin
2e4c42fadc feat(api): clarify default LLM model config selection logic
- Update API documentation to explicitly describe default configuration selection logic
- Add fallback behavior in repository to use first config when no default is marked
- Clarify difference between `/default` endpoint and `default_config` field
- Document that `default_config` is never null when configs list is not empty
2026-03-03 22:27:28 +08:00