2018-06-11 13:13:19 +00:00
package resourcecontrols
import (
"net/http"
"github.com/portainer/portainer"
httperror "github.com/portainer/portainer/http/error"
"github.com/portainer/portainer/http/request"
"github.com/portainer/portainer/http/response"
"github.com/portainer/portainer/http/security"
)
type resourceControlUpdatePayload struct {
AdministratorsOnly bool
Users [ ] int
Teams [ ] int
}
func ( payload * resourceControlUpdatePayload ) Validate ( r * http . Request ) error {
if len ( payload . Users ) == 0 && len ( payload . Teams ) == 0 && ! payload . AdministratorsOnly {
return portainer . Error ( "Invalid resource control declaration. Must specify Users, Teams or AdministratorOnly" )
}
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 ) )
if err == portainer . ErrResourceControlNotFound {
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 ) {
return & httperror . HandlerError { http . StatusForbidden , "Permission denied to update the resource control" , portainer . ErrResourceAccessDenied }
}
2018-06-11 13:13:19 +00:00
resourceControl . AdministratorsOnly = payload . AdministratorsOnly
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 )
}