mirror of
https://github.com/micromdm/micromdm/
synced 2026-08-13 14:05:42 +08:00
129 lines
3.3 KiB
Go
129 lines
3.3 KiB
Go
package command
|
|
|
|
import (
|
|
"net/http"
|
|
"os"
|
|
|
|
"golang.org/x/net/context"
|
|
|
|
httptransport "github.com/go-kit/kit/transport/http"
|
|
|
|
"github.com/go-kit/kit/log"
|
|
"github.com/gorilla/mux"
|
|
"github.com/micromdm/mdm"
|
|
)
|
|
|
|
// MDMCommandService allows creating and deleting MDM Command Payloads
|
|
type MDMCommandService interface {
|
|
NewCommand(*mdm.CommandRequest) (*mdm.Payload, error)
|
|
NextCommand(udid string) ([]byte, int, error)
|
|
DeleteCommand(deviceUDID, commandUUID string) (int, error)
|
|
}
|
|
|
|
type mdmCommandService struct {
|
|
// a redis datastore
|
|
db Datastore
|
|
}
|
|
|
|
type config struct {
|
|
logger log.Logger
|
|
db Datastore
|
|
}
|
|
|
|
// NewCommandService creates a new MDM Command Service
|
|
func NewCommandService(options ...func(*config) error) MDMCommandService {
|
|
conf := &config{}
|
|
defaultLogger := log.NewLogfmtLogger(os.Stderr)
|
|
for _, option := range options {
|
|
if err := option(conf); err != nil {
|
|
defaultLogger.Log("err", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
var svc MDMCommandService
|
|
svc = mdmCommandService{db: conf.db}
|
|
return svc
|
|
}
|
|
|
|
// Logger adds a logger to the service
|
|
func Logger(logger log.Logger) func(*config) error {
|
|
return func(c *config) error {
|
|
c.logger = logger
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// DB adds a db connection to the service
|
|
func DB(db Datastore) func(*config) error {
|
|
return func(c *config) error {
|
|
c.db = db
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// ServiceHandler returns an http handler for the command service
|
|
func ServiceHandler(ctx context.Context, svc MDMCommandService) http.Handler {
|
|
commonOptions := []httptransport.ServerOption{
|
|
httptransport.ServerErrorEncoder(encodeError),
|
|
}
|
|
newCommandEndpoint := makeNewCommandEndpoint(svc)
|
|
newCommandHandler := httptransport.NewServer(
|
|
ctx,
|
|
newCommandEndpoint,
|
|
decodeNewCommandRequest,
|
|
encodeResponse,
|
|
commonOptions...,
|
|
)
|
|
nextCommandEndpoint := makeNextCommandEndpoint(svc)
|
|
nextCommandHandler := httptransport.NewServer(
|
|
ctx,
|
|
nextCommandEndpoint,
|
|
decodeNextCommandRequest,
|
|
encodeResponse,
|
|
commonOptions...,
|
|
)
|
|
deleteCommandEndpoint := makeDeleteCommandEndpoint(svc)
|
|
deleteCommandHandler := httptransport.NewServer(
|
|
ctx,
|
|
deleteCommandEndpoint,
|
|
decodeDeleteCommandRequest,
|
|
encodeResponse,
|
|
commonOptions...,
|
|
)
|
|
r := mux.NewRouter()
|
|
r.Methods("POST").Path("/mdm/commands").Handler(newCommandHandler)
|
|
r.Methods("GET").Path("/mdm/commands/{udid}/next").Handler(nextCommandHandler)
|
|
r.Methods("DELETE").Path("/mdm/commands/{udid}/{uuid}").Handler(deleteCommandHandler)
|
|
return r
|
|
}
|
|
|
|
func (svc mdmCommandService) NewCommand(request *mdm.CommandRequest) (*mdm.Payload, error) {
|
|
// create a payload
|
|
payload, err := mdm.NewPayload(request)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// save in redis
|
|
err = svc.db.SavePayload(payload)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// add command to a queue in redis
|
|
err = svc.db.QueueCommand(request.UDID, payload.CommandUUID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// return created payload to user
|
|
return payload, nil
|
|
}
|
|
|
|
// NextCommand returns an MDM Payload from a list of queued payloads
|
|
func (svc mdmCommandService) NextCommand(udid string) ([]byte, int, error) {
|
|
return svc.db.NextCommand(udid)
|
|
}
|
|
|
|
// DeleteCommand returns an MDM Payload from a list of queued payloads
|
|
func (svc mdmCommandService) DeleteCommand(deviceUDID, commandUUID string) (int, error) {
|
|
return svc.db.DeleteCommand(deviceUDID, commandUUID)
|
|
}
|