mirror of
https://github.com/portainer/portainer.git
synced 2025-07-25 08:19:40 +02:00
feat(api-key/backend): introducing support for api-key based auth EE-978 (#6079)
* feat(access-token): Multi-auth middleware support EE-1891 (#5936) * AnyAuth middleware initial implementation with tests * using mux.MiddlewareFunc instead of custom definition * removed redundant comments * - ExtractBearerToken bouncer func made private - changed helm token handling functionality to use jwt service to convert token to jwt string - updated tests - fixed helm list broken test due to missing token in request context * rename mwCheckAuthentication -> mwCheckJWTAuthentication * - introduce initial api-key auth support using X-API-KEY header - added tests to validate x-api-key request header presence * updated core mwAuthenticatedUser middleware to support multiple auth paradigms * - simplified anyAuth middleware - enforcing authmiddleware to implement verificationFunc interface - created tests for middleware * simplify bouncer Co-authored-by: Dmitry Salakhov <to@dimasalakhov.com> * feat(api-key): user-access-token generation endpoint EE-1889 EE-1888 EE-1895 (#6012) * user-access-token generation endpoint * fix comment * - introduction of apikey service - seperation of repository from service logic - called in handler * fixed tests * - fixed api key prefix - added tests * added another test for digest matching * updated swagger spec for access token creation * api key response returns raw key and struct - easing testability * test for api key prefix length * added another TODO to middleware * - api-key prefix rune -> string (rune does not auto-encode when response sent back to client) - digest -> pointer as we want to allow nil values and omit digest in responses (when nil) * - updated apikey struct - updated apikey service to support all common operations - updated apikey repo - integration of apikey service into bouncer - added test for all apikey service functions - boilerplate code for apikey service integration * - user access token generation tests - apiKeyLookup updated to support query params - added api-key tests for query params - added api-key tests for apiKeyLookup * get and remove access token handlers * get and remove access token handler tests * - delete user deletes all associated api keys - tests for this functionality * removed redundant []byte cast * automatic api-key eviction set within cache for 1 hour * fixed bug with loop var using final value * fixed service comment * ignore bolt error responses * case-insensitive query param check * simplified query var assignment * - added GetAPIKey func to get by unique id - updated DeleteAPIKey func to not require user ID - updated tests * GenerateRandomKey helper func from github.com/gorilla/securecookie moved to codebase * json response casing for api-keys fixed * updating api-key will update the cache * updated golang LRU cache * using hashicorps golang-LRU cache for api keys * simplified jwt check in create user access token * fixed api-key update logic on cache miss * Prefix generated api-keys with `ptr_` (#6067) * prefix api-keys with 'ptr_' * updated apikey description * refactor Co-authored-by: Dmitry Salakhov <to@dimasalakhov.com> * helm list test refactor * fixed user delete test * reduce test nil pointer errors * using correct http 201 created status code for token creation; updated tests * fixed swagger doc user id path param for user access token based endpoints * added api-key security openapi spec to existing jwt secured endpoints (#6091) * fixed flaky test * apikey datecreated and lastused attrs converted to unix timestamp * feat(user): added access token datatable. (#6124) * feat(user): added access token datatable. * feat(tokens): only display lastUsed time when it is not the default date * Update app/portainer/views/account/accountController.js Co-authored-by: zees-dev <63374656+zees-dev@users.noreply.github.com> * Update app/portainer/views/account/accountController.js Co-authored-by: zees-dev <63374656+zees-dev@users.noreply.github.com> * Update app/portainer/views/account/accountController.js Co-authored-by: zees-dev <63374656+zees-dev@users.noreply.github.com> * Update app/portainer/components/datatables/access-tokens-datatable/accessTokensDatatableController.js Co-authored-by: zees-dev <63374656+zees-dev@users.noreply.github.com> * Update app/portainer/services/api/userService.js Co-authored-by: zees-dev <63374656+zees-dev@users.noreply.github.com> * feat(improvements): proposed datatable improvements to speed up dev time (#6138) * modal code update * updated datatable filenames, updated controller to be default class export * fix(access-token): code improvement. Co-authored-by: zees-dev <63374656+zees-dev@users.noreply.github.com> * feat(apikeys): create access token view initial implementation EE-1886 (#6129) * CopyButton implementation * Code component implementation * ToolTip component migration to another folder * TextTip component implementation - continued * form Heading component * Button component updated to be more dynamic * copybutton - small size * form control pass tip error * texttip small text * CreateAccessToken react feature initial implementation * create user access token angularjs view implementation * registration of CreateAccessToken component in AngularJS * user token generation API request moved to angular service, method passed down instead * consistent naming of access token operations; clustered similar code together * any user can add access token * create access token page routing * moved code component to the correct location * removed isadmin check as all functionality applicable to all users * create access token angular view moved up a level * fixed PR issues, updated PR * addressed PR issues/improvements * explicit hr for horizontal line * fixed merge conflict storybook build breaking * - apikey test - cache test * addressed testing issues: - description validations - remove token description link on table * fix(api-keys): user role change evicts user keys in cache EE-2113 (#6168) * user role change evicts user api keys in cache * EvictUserKeyCache -> InvalidateUserKeyCache * godoc for InvalidateUserKeyCache func * additional test line * disable add access token button after adding token to prevent spam Co-authored-by: Dmitry Salakhov <to@dimasalakhov.com> Co-authored-by: fhanportainer <79428273+fhanportainer@users.noreply.github.com>
This commit is contained in:
parent
120584909c
commit
69c17986d9
197 changed files with 3137 additions and 91 deletions
|
@ -11,6 +11,7 @@ import (
|
|||
// @id Logout
|
||||
// @summary Logout
|
||||
// @description **Access policy**: authenticated
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @tags auth
|
||||
// @success 204 "Success"
|
||||
|
|
|
@ -26,6 +26,7 @@ func (p *backupPayload) Validate(r *http.Request) error {
|
|||
// @description Creates an archive with a system data snapshot that could be used to restore the system.
|
||||
// @description **Access policy**: admin
|
||||
// @tags backup
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce octet-stream
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
// @description Create a custom template.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json,multipart/form-data
|
||||
// @produce json
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
// @description Remove a template.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Template identifier"
|
||||
// @success 204 "Success"
|
||||
|
|
|
@ -19,6 +19,7 @@ type fileResponse struct {
|
|||
// @description Retrieve the content of the Stack file for the specified custom template
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Template identifier"
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
// @description Retrieve details about a template.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Template identifier"
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
// @description List available custom templates.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param type query []int true "Template types" Enums(1,2,3)
|
||||
|
|
|
@ -62,6 +62,7 @@ func (payload *customTemplateUpdatePayload) Validate(r *http.Request) error {
|
|||
// @description Update a template.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -36,6 +36,7 @@ func (payload *edgeGroupCreatePayload) Validate(r *http.Request) error {
|
|||
// @summary Create an EdgeGroup
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @summary Deletes an EdgeGroup
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "EdgeGroup Id"
|
||||
// @success 204
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
// @summary Inspects an EdgeGroup
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "EdgeGroup Id"
|
||||
|
|
|
@ -19,6 +19,7 @@ type decoratedEdgeGroup struct {
|
|||
// @summary list EdgeGroups
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {array} decoratedEdgeGroup "EdgeGroups"
|
||||
|
|
|
@ -38,6 +38,7 @@ func (payload *edgeGroupUpdatePayload) Validate(r *http.Request) error {
|
|||
// @summary Updates an EdgeGroup
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
// @summary Create an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param method query string true "Creation Method" Enums(file, string)
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @summary Delete an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path string true "EdgeJob Id"
|
||||
// @success 204
|
||||
|
|
|
@ -18,6 +18,7 @@ type edgeJobFileResponse struct {
|
|||
// @summary Fetch a file of an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
|
|
|
@ -19,6 +19,7 @@ type edgeJobInspectResponse struct {
|
|||
// @summary Inspect an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
// @summary Fetch EdgeJobs list
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.EdgeJob
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @summary Clear the log for a specifc task on an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
// @summary Collect the log for a specifc task on an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
|
|
|
@ -17,6 +17,7 @@ type fileResponse struct {
|
|||
// @summary Fetch the log for a specifc task on an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
|
|
|
@ -21,6 +21,7 @@ type taskContainer struct {
|
|||
// @summary Fetch the list of tasks on an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
|
|
|
@ -32,6 +32,7 @@ func (payload *edgeJobUpdatePayload) Validate(r *http.Request) error {
|
|||
// @summary Update an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
// @summary Create an EdgeStack
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param method query string true "Creation Method" Enums(file,string,repository)
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @summary Delete an EdgeStack
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path string true "EdgeStack Id"
|
||||
// @success 204
|
||||
|
|
|
@ -18,6 +18,7 @@ type stackFileResponse struct {
|
|||
// @summary Fetches the stack file for an EdgeStack
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path string true "EdgeStack Id"
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
// @summary Inspect an EdgeStack
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path string true "EdgeStack Id"
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
// @summary Fetches the list of EdgeStacks
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.EdgeStack
|
||||
|
|
|
@ -35,6 +35,7 @@ func (payload *updateEdgeStackPayload) Validate(r *http.Request) error {
|
|||
// @summary Update an EdgeStack
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -19,6 +19,7 @@ type templateFileFormat struct {
|
|||
// @summary Fetches the list of Edge Templates
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -36,6 +36,7 @@ func (payload *endpointGroupCreatePayload) Validate(r *http.Request) error {
|
|||
// @description Create a new environment(endpoint) group.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoint_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
// @description Remove an environment(endpoint) group.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoint_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "EndpointGroup identifier"
|
||||
// @success 204 "Success"
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @description Add an environment(endpoint) to an environment(endpoint) group
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoint_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "EndpointGroup identifier"
|
||||
// @param endpointId path int true "Environment(Endpoint) identifier"
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
// @summary Removes environment(endpoint) from an environment(endpoint) group
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoint_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "EndpointGroup identifier"
|
||||
// @param endpointId path int true "Environment(Endpoint) identifier"
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
// @description Retrieve details abont an environment(endpoint) group.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoint_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @description only return authorized environment(endpoint) groups.
|
||||
// @description **Access policy**: restricted
|
||||
// @tags endpoint_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.EndpointGroup "Environment(Endpoint) group"
|
||||
|
|
|
@ -32,6 +32,7 @@ func (payload *endpointGroupUpdatePayload) Validate(r *http.Request) error {
|
|||
// @description Update an environment(endpoint) group.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoint_groups
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
// @summary De-association an edge environment(endpoint)
|
||||
// @description De-association an edge environment(endpoint).
|
||||
// @description **Access policy**: administrator
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @tags endpoints
|
||||
// @produce json
|
||||
|
|
|
@ -152,6 +152,7 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error {
|
|||
// @description Create a new environment(endpoint) that will be used to manage an environment(endpoint).
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept multipart/form-data
|
||||
// @produce json
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
// @description Remove an environment(endpoint).
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @success 204 "Success"
|
||||
|
|
|
@ -29,6 +29,7 @@ type dockerhubStatusResponse struct {
|
|||
// @description get docker pull limits for a docker hub registry in the environment
|
||||
// @description **Access policy**:
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "endpoint ID"
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @description Retrieve details about an environment(endpoint).
|
||||
// @description **Access policy**: restricted
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
// @description only return authorized environments(endpoints).
|
||||
// @description **Access policy**: restricted
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param start query int false "Start searching from"
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
// @summary get registry for environment
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "identifier"
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
// @description **Access policy**: authenticated
|
||||
// @tags endpoints
|
||||
// @param namespace query string false "required if kubernetes environment, will show registries by namespace"
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
|
|
|
@ -25,6 +25,7 @@ func (payload *registryAccessPayload) Validate(r *http.Request) error {
|
|||
// @summary update registry access for environment
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -39,6 +39,7 @@ func (payload *endpointSettingsUpdatePayload) Validate(r *http.Request) error {
|
|||
// @summary Update settings for an environment(endpoint)
|
||||
// @description Update settings for an environment(endpoint).
|
||||
// @description **Access policy**: authenticated
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @tags endpoints
|
||||
// @accept json
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
// @description Snapshots an environment(endpoint)
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @success 204 "Success"
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @description Snapshot all environments(endpoints)
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @success 204 "Success"
|
||||
// @failure 500 "Server Error"
|
||||
|
|
|
@ -54,6 +54,7 @@ type endpointStatusInspectResponse struct {
|
|||
// @description Environment(Endpoint) for edge agent to check status of environment(endpoint)
|
||||
// @description **Access policy**: restricted only to Edge environments(endpoints)
|
||||
// @tags endpoints
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @success 200 {object} endpointStatusInspectResponse "Success"
|
||||
|
|
|
@ -57,6 +57,7 @@ func (payload *endpointUpdatePayload) Validate(r *http.Request) error {
|
|||
// @summary Update an environment(endpoint)
|
||||
// @description Update an environment(endpoint).
|
||||
// @description **Access policy**: authenticated
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @tags endpoints
|
||||
// @accept json
|
||||
|
|
|
@ -91,6 +91,10 @@ type Handler struct {
|
|||
// @BasePath /api
|
||||
// @schemes http https
|
||||
|
||||
// @securitydefinitions.apikey ApiKeyAuth
|
||||
// @in header
|
||||
// @name Authorization
|
||||
|
||||
// @securitydefinitions.apikey jwt
|
||||
// @in header
|
||||
// @name Authorization
|
||||
|
|
|
@ -26,17 +26,19 @@ type Handler struct {
|
|||
*mux.Router
|
||||
requestBouncer requestBouncer
|
||||
dataStore portainer.DataStore
|
||||
jwtService portainer.JWTService
|
||||
kubeConfigService kubernetes.KubeConfigService
|
||||
kubernetesDeployer portainer.KubernetesDeployer
|
||||
helmPackageManager libhelm.HelmPackageManager
|
||||
}
|
||||
|
||||
// NewHandler creates a handler to manage endpoint group operations.
|
||||
func NewHandler(bouncer requestBouncer, dataStore portainer.DataStore, kubernetesDeployer portainer.KubernetesDeployer, helmPackageManager libhelm.HelmPackageManager, kubeConfigService kubernetes.KubeConfigService) *Handler {
|
||||
func NewHandler(bouncer requestBouncer, dataStore portainer.DataStore, jwtService portainer.JWTService, kubernetesDeployer portainer.KubernetesDeployer, helmPackageManager libhelm.HelmPackageManager, kubeConfigService kubernetes.KubeConfigService) *Handler {
|
||||
h := &Handler{
|
||||
Router: mux.NewRouter(),
|
||||
requestBouncer: bouncer,
|
||||
dataStore: dataStore,
|
||||
jwtService: jwtService,
|
||||
kubernetesDeployer: kubernetesDeployer,
|
||||
helmPackageManager: helmPackageManager,
|
||||
kubeConfigService: kubeConfigService,
|
||||
|
@ -91,7 +93,12 @@ func (handler *Handler) getHelmClusterAccess(r *http.Request) (*options.Kubernet
|
|||
return nil, &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment on request context", err}
|
||||
}
|
||||
|
||||
bearerToken, err := security.ExtractBearerToken(r)
|
||||
tokenData, err := security.RetrieveTokenData(r)
|
||||
if err != nil {
|
||||
return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err}
|
||||
}
|
||||
|
||||
bearerToken, err := handler.jwtService.GenerateToken(tokenData)
|
||||
if err != nil {
|
||||
return nil, &httperror.HandlerError{http.StatusUnauthorized, "Unauthorized", err}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
// @description
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @param release path string true "The name of the release/application to uninstall"
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/exec/exectest"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/jwt"
|
||||
"github.com/portainer/portainer/api/kubernetes"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
@ -30,10 +31,13 @@ func Test_helmDelete(t *testing.T) {
|
|||
err = store.User().CreateUser(&portainer.User{Username: "admin", Role: portainer.AdministratorRole})
|
||||
is.NoError(err, "Error creating a user")
|
||||
|
||||
jwtService, err := jwt.NewService("1h", store)
|
||||
is.NoError(err, "Error initiating jwt service")
|
||||
|
||||
kubernetesDeployer := exectest.NewKubernetesDeployer()
|
||||
helmPackageManager := test.NewMockHelmBinaryPackageManager("")
|
||||
kubeConfigService := kubernetes.NewKubeConfigCAService("", "")
|
||||
h := NewHandler(helper.NewTestRequestBouncer(), store, kubernetesDeployer, helmPackageManager, kubeConfigService)
|
||||
h := NewHandler(helper.NewTestRequestBouncer(), store, jwtService, kubernetesDeployer, helmPackageManager, kubeConfigService)
|
||||
|
||||
is.NotNil(h, "Handler should not fail")
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ var errChartNameInvalid = errors.New("invalid chart name. " +
|
|||
// @description
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/portainer/portainer/api/exec/exectest"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
helper "github.com/portainer/portainer/api/internal/testhelpers"
|
||||
"github.com/portainer/portainer/api/jwt"
|
||||
"github.com/portainer/portainer/api/kubernetes"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
@ -32,10 +33,13 @@ func Test_helmInstall(t *testing.T) {
|
|||
err = store.User().CreateUser(&portainer.User{Username: "admin", Role: portainer.AdministratorRole})
|
||||
is.NoError(err, "error creating a user")
|
||||
|
||||
jwtService, err := jwt.NewService("1h", store)
|
||||
is.NoError(err, "Error initiating jwt service")
|
||||
|
||||
kubernetesDeployer := exectest.NewKubernetesDeployer()
|
||||
helmPackageManager := test.NewMockHelmBinaryPackageManager("")
|
||||
kubeConfigService := kubernetes.NewKubeConfigCAService("", "")
|
||||
h := NewHandler(helper.NewTestRequestBouncer(), store, kubernetesDeployer, helmPackageManager, kubeConfigService)
|
||||
h := NewHandler(helper.NewTestRequestBouncer(), store, jwtService, kubernetesDeployer, helmPackageManager, kubeConfigService)
|
||||
|
||||
is.NotNil(h, "Handler should not fail")
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
// @description
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -12,6 +12,8 @@ import (
|
|||
"github.com/portainer/libhelm/release"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/exec/exectest"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/jwt"
|
||||
"github.com/portainer/portainer/api/kubernetes"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
@ -20,28 +22,33 @@ import (
|
|||
)
|
||||
|
||||
func Test_helmList(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
store, teardown := bolt.MustNewTestStore(true)
|
||||
defer teardown()
|
||||
|
||||
err := store.Endpoint().CreateEndpoint(&portainer.Endpoint{ID: 1})
|
||||
assert.NoError(t, err, "error creating environment")
|
||||
is.NoError(err, "error creating environment")
|
||||
|
||||
err = store.User().CreateUser(&portainer.User{Username: "admin", Role: portainer.AdministratorRole})
|
||||
assert.NoError(t, err, "error creating a user")
|
||||
is.NoError(err, "error creating a user")
|
||||
|
||||
jwtService, err := jwt.NewService("1h", store)
|
||||
is.NoError(err, "Error initialising jwt service")
|
||||
|
||||
kubernetesDeployer := exectest.NewKubernetesDeployer()
|
||||
helmPackageManager := test.NewMockHelmBinaryPackageManager("")
|
||||
kubeConfigService := kubernetes.NewKubeConfigCAService("", "")
|
||||
h := NewHandler(helper.NewTestRequestBouncer(), store, kubernetesDeployer, helmPackageManager, kubeConfigService)
|
||||
h := NewHandler(helper.NewTestRequestBouncer(), store, jwtService, kubernetesDeployer, helmPackageManager, kubeConfigService)
|
||||
|
||||
// Install a single chart. We expect to get these values back
|
||||
options := options.InstallOptions{Name: "nginx-1", Chart: "nginx", Namespace: "default"}
|
||||
h.helmPackageManager.Install(options)
|
||||
|
||||
t.Run("helmList", func(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/1/kubernetes/helm", nil)
|
||||
ctx := security.StoreTokenData(req, &portainer.TokenData{ID: 1, Username: "admin", Role: 1})
|
||||
req = req.WithContext(ctx)
|
||||
req.Header.Add("Authorization", "Bearer dummytoken")
|
||||
|
||||
rr := httptest.NewRecorder()
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @param repo query string true "Helm repository URL"
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {object} string "Success"
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
// @param repo query string true "Helm repository URL"
|
||||
// @param chart query string true "Chart name"
|
||||
// @param command path string true "chart/values/readme"
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce text/plain
|
||||
|
|
|
@ -33,6 +33,7 @@ func (p *addHelmRepoUrlPayload) Validate(_ *http.Request) error {
|
|||
// @description Create a user helm repository.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
@ -93,6 +94,7 @@ func (handler *Handler) userCreateHelmRepo(w http.ResponseWriter, r *http.Reques
|
|||
// @description Inspect a user helm repositories.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "User identifier"
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
// @description Generates kubeconfig file enabling client communication with k8s api server
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags kubernetes
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @description Get CPU and memory limits of all nodes within k8s cluster
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags kubernetes
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -22,6 +22,7 @@ func (payload *namespacesToggleSystemPayload) Validate(r *http.Request) error {
|
|||
// @summary Toggle the system state for a namespace
|
||||
// @description Toggle the system state for a namespace
|
||||
// @description **Access policy**: administrator or environment(endpoint) admin
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @tags kubernetes
|
||||
// @accept json
|
||||
|
|
|
@ -22,6 +22,7 @@ func (payload *checkPayload) Validate(r *http.Request) error {
|
|||
// @description Test LDAP connectivity using LDAP details
|
||||
// @description **Access policy**: administrator
|
||||
// @tags ldap
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @param body body checkPayload true "details"
|
||||
|
|
|
@ -30,6 +30,7 @@ type motdData struct {
|
|||
// @summary fetches the message of the day
|
||||
// @description **Access policy**: restricted
|
||||
// @tags motd
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {object} motdResponse
|
||||
|
|
|
@ -83,6 +83,7 @@ func (payload *registryConfigurePayload) Validate(r *http.Request) error {
|
|||
// @description Configures a registry.
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -64,6 +64,7 @@ func (payload *registryCreatePayload) Validate(_ *http.Request) error {
|
|||
// @description Create a new registry.
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
// @description Remove a registry
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Registry identifier"
|
||||
// @success 204 "Success"
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
// @description Retrieve details about a registry.
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Registry identifier"
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
// @description will only return authorized registries.
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.Registry "Success"
|
||||
|
|
|
@ -39,6 +39,7 @@ func (payload *registryUpdatePayload) Validate(r *http.Request) error {
|
|||
// @description Update a registry
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -58,6 +58,7 @@ func (payload *resourceControlCreatePayload) Validate(r *http.Request) error {
|
|||
// @description Create a new resource control to restrict access to a Docker resource.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags resource_controls
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
// @description Remove a resource control.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags resource_controls
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Resource control identifier"
|
||||
// @success 204 "Success"
|
||||
|
|
|
@ -40,6 +40,7 @@ func (payload *resourceControlUpdatePayload) Validate(r *http.Request) error {
|
|||
// @description Update a resource control
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags resource_controls
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
// @description List all roles available for use
|
||||
// @description **Access policy**: administrator
|
||||
// @tags roles
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.Role "Success"
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
// @description Retrieve Portainer settings.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags settings
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {object} portainer.Settings "Success"
|
||||
|
|
|
@ -78,6 +78,7 @@ func (payload *settingsUpdatePayload) Validate(r *http.Request) error {
|
|||
// @description Update Portainer settings.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags settings
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
// @description Retrieve the ssl settings.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags ssl
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {object} portainer.SSLSettings "Success"
|
||||
|
|
|
@ -28,6 +28,7 @@ func (payload *sslUpdatePayload) Validate(r *http.Request) error {
|
|||
// @description Update the ssl settings.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags ssl
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
// @summary Associate an orphaned stack to a new environment(endpoint)
|
||||
// @description **Access policy**: administrator
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Stack identifier"
|
||||
|
|
|
@ -35,6 +35,7 @@ func (handler *Handler) cleanUp(stack *portainer.Stack, doCleanUp *bool) error {
|
|||
// @description Deploy a new stack into a Docker environment(endpoint) specified via the environment(endpoint) identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json,multipart/form-data
|
||||
// @produce json
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
// @description Remove a stack.
|
||||
// @description **Access policy**: restricted
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Stack identifier"
|
||||
// @param external query boolean false "Set to true to delete an external stack. Only external Swarm stacks are supported"
|
||||
|
|
|
@ -23,6 +23,7 @@ type stackFileResponse struct {
|
|||
// @description Get Stack file content.
|
||||
// @description **Access policy**: restricted
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Stack identifier"
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
// @description Retrieve details about a stack.
|
||||
// @description **Access policy**: restricted
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Stack identifier"
|
||||
|
|
|
@ -26,6 +26,7 @@ type stackListOperationFilters struct {
|
|||
// @description will only return the list of stacks the user have access to.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param filters query string false "Filters to process on the stack list. Encoded as JSON (a map[string]string). For example, {'SwarmID': 'jpofkc0i9uo9wtx1zesuk649w'} will only return stacks that are part of the specified Swarm cluster. Available filters: EndpointID, SwarmID."
|
||||
// @success 200 {array} portainer.Stack "Success"
|
||||
|
|
|
@ -36,6 +36,7 @@ func (payload *stackMigratePayload) Validate(r *http.Request) error {
|
|||
// @description Migrate a stack from an environment(endpoint) to another environment(endpoint). It will re-create the stack inside the target environment(endpoint) before removing the original stack.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Stack identifier"
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
// @description Starts a stopped Stack.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Stack identifier"
|
||||
// @success 200 {object} portainer.Stack "Success"
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
// @description Stops a stopped Stack.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Stack identifier"
|
||||
// @success 200 {object} portainer.Stack "Success"
|
||||
|
|
|
@ -53,6 +53,7 @@ func (payload *updateSwarmStackPayload) Validate(r *http.Request) error {
|
|||
// @description Update a stack.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -42,6 +42,7 @@ func (payload *stackGitUpdatePayload) Validate(r *http.Request) error {
|
|||
// @description Update the Git settings in a stack, e.g., RepositoryReferenceName and AutoUpdate
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -40,6 +40,7 @@ func (payload *stackGitRedployPayload) Validate(r *http.Request) error {
|
|||
// @description Pull and redeploy a stack via Git
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -27,6 +27,7 @@ type githubData struct {
|
|||
// @summary Check for portainer updates
|
||||
// @description Check if portainer has an update available
|
||||
// @description **Access policy**: authenticated
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @tags status
|
||||
// @produce json
|
||||
|
|
|
@ -28,6 +28,7 @@ func (payload *tagCreatePayload) Validate(r *http.Request) error {
|
|||
// @description Create a new tag.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags tags
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
// @description Remove a tag.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags tags
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "Tag identifier"
|
||||
// @success 204 "Success"
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
// @description List tags.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags tags
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.Tag "Success"
|
||||
|
|
|
@ -39,6 +39,7 @@ func (payload *teamMembershipCreatePayload) Validate(r *http.Request) error {
|
|||
// @description Create a new team memberships. Access is only available to administrators leaders of the associated team.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags team_memberships
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
// @description Remove a team membership. Access is only available to administrators leaders of the associated team.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags team_memberships
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @param id path int true "TeamMembership identifier"
|
||||
// @success 204 "Success"
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
// @description List team memberships. Access is only available to administrators and team leaders.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags team_memberships
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.TeamMembership "Success"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue