2018-06-11 13:13:19 +00:00
package resourcecontrols
import (
2019-11-12 23:41:42 +00:00
"errors"
2018-06-11 13:13:19 +00:00
"net/http"
2018-09-10 10:01:38 +00:00
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
2019-03-21 01:20:14 +00:00
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/http/security"
2018-06-11 13:13:19 +00:00
)
type resourceControlUpdatePayload struct {
2019-11-12 23:41:42 +00:00
Public bool
Users [ ] int
Teams [ ] int
AdministratorsOnly bool
2018-06-11 13:13:19 +00:00
}
func ( payload * resourceControlUpdatePayload ) Validate ( r * http . Request ) error {
2019-11-12 23:41:42 +00:00
if len ( payload . Users ) == 0 && len ( payload . Teams ) == 0 && ! payload . Public && ! payload . AdministratorsOnly {
return errors . New ( "invalid payload: must specify Users, Teams, Public or AdministratorsOnly" )
}
if payload . Public && payload . AdministratorsOnly {
return errors . New ( "invalid payload: cannot set public and administrators only" )
2018-06-11 13:13:19 +00:00
}
return nil
}
// PUT request on /api/resource_controls/:id
func ( handler * Handler ) resourceControlUpdate ( w http . ResponseWriter , r * http . Request ) * httperror . HandlerError {
resourceControlID , err := request . RetrieveNumericRouteVariableValue ( r , "id" )
if err != nil {
return & httperror . HandlerError { http . StatusBadRequest , "Invalid resource control identifier route variable" , err }
}
var payload resourceControlUpdatePayload
err = request . DecodeAndValidateJSONPayload ( r , & payload )
if err != nil {
return & httperror . HandlerError { http . StatusBadRequest , "Invalid request payload" , err }
}
resourceControl , err := handler . ResourceControlService . ResourceControl ( portainer . ResourceControlID ( resourceControlID ) )
2018-06-19 11:15:10 +00:00
if err == portainer . ErrObjectNotFound {
2018-06-11 13:13:19 +00:00
return & httperror . HandlerError { http . StatusNotFound , "Unable to find a resource control with the specified identifier inside the database" , err }
} else if err != nil {
return & httperror . HandlerError { http . StatusInternalServerError , "Unable to find a resource control with with the specified identifier inside the database" , err }
}
2018-06-11 15:58:46 +00:00
securityContext , err := security . RetrieveRestrictedRequestContext ( r )
if err != nil {
return & httperror . HandlerError { http . StatusInternalServerError , "Unable to retrieve info from request context" , err }
}
if ! security . AuthorizedResourceControlAccess ( resourceControl , securityContext ) {
2019-11-12 23:41:42 +00:00
return & httperror . HandlerError { http . StatusForbidden , "Permission denied to access the resource control" , portainer . ErrResourceAccessDenied }
2018-06-11 15:58:46 +00:00
}
2018-08-19 05:57:28 +00:00
resourceControl . Public = payload . Public
2019-11-12 23:41:42 +00:00
resourceControl . AdministratorsOnly = payload . AdministratorsOnly
2018-06-11 13:13:19 +00:00
var userAccesses = make ( [ ] portainer . UserResourceAccess , 0 )
for _ , v := range payload . Users {
userAccess := portainer . UserResourceAccess {
UserID : portainer . UserID ( v ) ,
AccessLevel : portainer . ReadWriteAccessLevel ,
}
userAccesses = append ( userAccesses , userAccess )
}
resourceControl . UserAccesses = userAccesses
var teamAccesses = make ( [ ] portainer . TeamResourceAccess , 0 )
for _ , v := range payload . Teams {
teamAccess := portainer . TeamResourceAccess {
TeamID : portainer . TeamID ( v ) ,
AccessLevel : portainer . ReadWriteAccessLevel ,
}
teamAccesses = append ( teamAccesses , teamAccess )
}
resourceControl . TeamAccesses = teamAccesses
if ! security . AuthorizedResourceControlUpdate ( resourceControl , securityContext ) {
return & httperror . HandlerError { http . StatusForbidden , "Permission denied to update the resource control" , portainer . ErrResourceAccessDenied }
}
err = handler . ResourceControlService . UpdateResourceControl ( resourceControl . ID , resourceControl )
if err != nil {
return & httperror . HandlerError { http . StatusInternalServerError , "Unable to persist resource control changes inside the database" , err }
}
return response . JSON ( w , resourceControl )
}