mirror of
https://github.com/micromdm/micromdm/
synced 2026-08-13 05:45:41 +08:00
Revert acknowledge handlers code.
Add stub for acknowledging installed applications list.
This commit is contained in:
@@ -1,125 +0,0 @@
|
||||
package applications
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/micromdm/mdm"
|
||||
// "github.com/micromdm/micromdm/device"
|
||||
"github.com/micromdm/micromdm/device"
|
||||
)
|
||||
|
||||
func AppListPredicate(response mdm.Response) bool {
|
||||
fmt.Println("InstalledApplicationList Predicate")
|
||||
|
||||
if response.RequestType == "InstalledApplicationList" {
|
||||
return true
|
||||
}
|
||||
|
||||
if response.InstalledApplicationList != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func any(list []Application, predicate func(Application) bool) bool {
|
||||
for _, v := range list {
|
||||
if predicate(v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func AppListResponse(response mdm.Response, datastores map[string]interface{}) error {
|
||||
store, found := datastores["applications"]
|
||||
if !found {
|
||||
return errors.New("Do not have access to datastore for saving application information")
|
||||
}
|
||||
|
||||
appsStore, ok := store.(Datastore)
|
||||
if !ok {
|
||||
return errors.New("could not acknowledge installed application list because the given datastore isnt an application datastore.")
|
||||
}
|
||||
|
||||
dstore, found := datastores["devices"]
|
||||
if !found {
|
||||
return errors.New("Do not have access to datastore for retrieving device information")
|
||||
}
|
||||
|
||||
deviceStore, ok := dstore.(device.Datastore)
|
||||
if !ok {
|
||||
return errors.New("could not acknowledge installed application list because the given device datastore isnt a device datastore.")
|
||||
}
|
||||
|
||||
device, err := deviceStore.GetDeviceByUDID(response.UDID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deviceApps, err := appsStore.GetApplicationsByDeviceUUID(device.UUID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var uuids []string
|
||||
for _, app := range response.InstalledApplicationList {
|
||||
//var uuid string
|
||||
|
||||
existingApps, err := appsStore.Applications(Name{app.Name}, Version{app.Version})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(existingApps) > 0 {
|
||||
existingApp := existingApps[0]
|
||||
uuid = existingApp.UUID
|
||||
uuids = append(uuids, existingApp.UUID)
|
||||
} else {
|
||||
dbApp := &Application{Name: app.Name}
|
||||
|
||||
identifier := sql.NullString{}
|
||||
identifier.Scan(app.Identifier)
|
||||
dbApp.Identifier = identifier
|
||||
|
||||
bundleSize := sql.NullInt64{}
|
||||
bundleSize.Scan(app.BundleSize)
|
||||
dbApp.BundleSize = bundleSize
|
||||
|
||||
shortVersion := sql.NullString{}
|
||||
shortVersion.Scan(app.ShortVersion)
|
||||
dbApp.ShortVersion = shortVersion
|
||||
|
||||
version := sql.NullString{}
|
||||
version.Scan(app.Version)
|
||||
dbApp.Version = version
|
||||
|
||||
dynamicSize := sql.NullInt64{}
|
||||
dynamicSize.Scan(app.DynamicSize)
|
||||
dbApp.DynamicSize = dynamicSize
|
||||
|
||||
isValidated := sql.NullBool{}
|
||||
isValidated.Scan(app.IsValidated)
|
||||
dbApp.IsValidated = isValidated
|
||||
|
||||
uuid, err := appsStore.New(dbApp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uuids = append(uuids, uuid)
|
||||
}
|
||||
|
||||
if !any(deviceApps, app) {
|
||||
// App installed on device but not recorded
|
||||
|
||||
//deviceApp := &DeviceApplication{
|
||||
// DeviceUUID: device.UUID,
|
||||
// ApplicationUUID: app.UUID,
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package connect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"github.com/micromdm/mdm"
|
||||
"github.com/micromdm/micromdm/command"
|
||||
"github.com/micromdm/micromdm/device"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Service defines methods for an MDM service
|
||||
@@ -14,10 +15,6 @@ type Service interface {
|
||||
Acknowledge(ctx context.Context, req mdm.Response) (int, error)
|
||||
NextCommand(ctx context.Context, req mdm.Response) ([]byte, int, error)
|
||||
FailCommand(ctx context.Context, req mdm.Response) (int, error)
|
||||
|
||||
RegisterAckHandler(predicate func(req mdm.Response) bool, handler func(req mdm.Response, datastores map[string]interface{}) error, datastores map[string]interface{})
|
||||
FindAckHandler(req mdm.Response) (func(req mdm.Response) error, bool)
|
||||
ExecAckHandler(req mdm.Response) error
|
||||
}
|
||||
|
||||
// NewService creates a mdm service
|
||||
@@ -25,25 +22,27 @@ func NewService(devices device.Datastore, cs command.Service) Service {
|
||||
return &service{
|
||||
commands: cs,
|
||||
devices: devices,
|
||||
handlers: []ackHandler{},
|
||||
}
|
||||
}
|
||||
|
||||
type ackHandler struct {
|
||||
predicate func(req mdm.Response) bool
|
||||
handler func(req mdm.Response) error
|
||||
}
|
||||
|
||||
type service struct {
|
||||
devices device.Datastore
|
||||
commands command.Service
|
||||
handlers []ackHandler
|
||||
}
|
||||
|
||||
func (svc service) Acknowledge(ctx context.Context, req mdm.Response) (int, error) {
|
||||
err := svc.ExecAckHandler(req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
switch req.RequestType {
|
||||
case "DeviceInformation":
|
||||
if err := svc.ackQueryResponses(req); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
default:
|
||||
// Need to handle the absence of RequestType in IOS8 devices
|
||||
if req.QueryResponses.UDID != "" {
|
||||
if err := svc.ackQueryResponses(req); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total, err := svc.commands.DeleteCommand(req.UDID, req.CommandUUID)
|
||||
@@ -87,33 +86,46 @@ func (svc service) checkRequeue(deviceUDID string) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Register a handler function for a given request, include datastore dependencies as a map.
|
||||
func (svc *service) RegisterAckHandler(predicate func(req mdm.Response) bool, handler func(req mdm.Response, datastores map[string]interface{}) error, datastores map[string]interface{}) {
|
||||
datastoreInjectedHandler := func(req mdm.Response) error {
|
||||
return handler(req, datastores)
|
||||
}
|
||||
newHandler := ackHandler{predicate: predicate, handler: datastoreInjectedHandler}
|
||||
svc.handlers = append(svc.handlers, newHandler)
|
||||
}
|
||||
// Acknowledge Queries sent with DeviceInformation command
|
||||
func (svc service) ackQueryResponses(req mdm.Response) error {
|
||||
devices, err := svc.devices.Devices(
|
||||
device.SerialNumber{SerialNumber: req.QueryResponses.SerialNumber},
|
||||
device.UDID{UDID: req.UDID},
|
||||
)
|
||||
|
||||
// Find a handler function which is registered to deal with the RequestType
|
||||
func (svc service) FindAckHandler(req mdm.Response) (func(req mdm.Response) error, bool) {
|
||||
for i, h := range svc.handlers {
|
||||
fmt.Println(i)
|
||||
if h.predicate(req) {
|
||||
return h.handler, true
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Execute any registered handler function which matches the given RequestType
|
||||
func (svc service) ExecAckHandler(req mdm.Response) error {
|
||||
handler, found := svc.FindAckHandler(req)
|
||||
if !found {
|
||||
return errors.New("There is no registered handler for the response.")
|
||||
if len(devices) > 1 {
|
||||
return errors.New("expected a single query result for device, got more than one.")
|
||||
}
|
||||
|
||||
return handler(req)
|
||||
existing := devices[0]
|
||||
|
||||
now := time.Now()
|
||||
existing.LastCheckin = &now
|
||||
existing.LastQueryResponse, err = json.Marshal(req.QueryResponses)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var serialNumber device.JsonNullString
|
||||
serialNumber.Scan(req.QueryResponses.SerialNumber)
|
||||
|
||||
existing.ProductName = req.QueryResponses.ProductName
|
||||
existing.BuildVersion = req.QueryResponses.BuildVersion
|
||||
existing.DeviceName = req.QueryResponses.DeviceName
|
||||
existing.IMEI = req.QueryResponses.IMEI
|
||||
existing.MEID = req.QueryResponses.MEID
|
||||
existing.Model = req.QueryResponses.Model
|
||||
existing.OSVersion = req.QueryResponses.OSVersion
|
||||
existing.SerialNumber = serialNumber
|
||||
|
||||
return svc.devices.Save("queryResponses", &existing)
|
||||
}
|
||||
|
||||
//func (svc service) ackInstalledApplicationList(req mdm.Response) error {
|
||||
//
|
||||
//}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/micromdm/mdm"
|
||||
"time"
|
||||
)
|
||||
|
||||
func AckQueryResponsesPredicate(req mdm.Response) bool {
|
||||
if req.RequestType == "DeviceInformation" {
|
||||
return true
|
||||
}
|
||||
|
||||
//// Need to handle the absence of RequestType in IOS8 devices
|
||||
if req.QueryResponses.UDID != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Acknowledge Queries sent with DeviceInformation command
|
||||
func AckQueryResponsesResponse(req mdm.Response, datastores map[string]interface{}) error {
|
||||
store, found := datastores["devices"]
|
||||
if !found {
|
||||
return errors.New("Do not have access to datastore for saving device information")
|
||||
}
|
||||
|
||||
devicesStore, ok := store.(Datastore)
|
||||
if !ok {
|
||||
return errors.New("could not acknowledge device information because the given datastore isnt a device datastore.")
|
||||
}
|
||||
|
||||
devices, err := devicesStore.Devices(
|
||||
SerialNumber{SerialNumber: req.QueryResponses.SerialNumber},
|
||||
UDID{UDID: req.UDID},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(devices) > 1 {
|
||||
return errors.New("expected a single query result for device, got more than one.")
|
||||
}
|
||||
|
||||
existing := devices[0]
|
||||
|
||||
now := time.Now()
|
||||
existing.LastCheckin = &now
|
||||
existing.LastQueryResponse, err = json.Marshal(req.QueryResponses)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var serialNumber JsonNullString
|
||||
serialNumber.Scan(req.QueryResponses.SerialNumber)
|
||||
|
||||
existing.ProductName = req.QueryResponses.ProductName
|
||||
existing.BuildVersion = req.QueryResponses.BuildVersion
|
||||
existing.DeviceName = req.QueryResponses.DeviceName
|
||||
existing.IMEI = req.QueryResponses.IMEI
|
||||
existing.MEID = req.QueryResponses.MEID
|
||||
existing.Model = req.QueryResponses.Model
|
||||
existing.OSVersion = req.QueryResponses.OSVersion
|
||||
existing.SerialNumber = serialNumber
|
||||
|
||||
return devicesStore.Save("queryResponses", &existing)
|
||||
}
|
||||
Reference in New Issue
Block a user