Skip to content

Commit

Permalink
dissociate all sets from enrollment
Browse files Browse the repository at this point in the history
  • Loading branch information
jessepeterson committed Oct 23, 2024
1 parent ff71259 commit 04c1c64
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 3 deletions.
6 changes: 6 additions & 0 deletions cmd/kmfddm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ func main() {
"DELETE",
)

mux.Handle(
"/v1/enrollment-sets-all/sets/:id",
apihttp.DeleteAllEnrollmentSetsHandler(store, nanoNotif, logger.With(logkeys.Handler, "delete-all-enrollment-sets")),
"DELETE",
)

// declarations sets
mux.Handle(
"/v1/declaration-sets/:id",
Expand Down
22 changes: 22 additions & 0 deletions docs/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,28 @@ paths:
- $ref: '#/components/parameters/setNameInQuery'
parameters:
- $ref: '#/components/parameters/enrollmentID'
/v1/enrollment-sets-all/{id}:
delete:
description: Dissociate all sets from enrollment ID.
tags:
- enrollments
security:
- basicAuth: []
responses:
'204':
$ref: '#/components/responses/DissociationChanged'
'304':
$ref: '#/components/responses/DissociationUnchanged'
'401':
$ref: '#/components/responses/UnauthorizedError'
'400':
$ref: '#/components/responses/JSONBadRequest'
'500':
$ref: '#/components/responses/JSONError'
parameters:
- $ref: '#/components/parameters/noNotify'
parameters:
- $ref: '#/components/parameters/enrollmentID'
/v1/declaration-sets/{id}:
get:
description: Retrieve the list of sets that a declaration is associated with.
Expand Down
23 changes: 20 additions & 3 deletions http/api/enrollments.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/micromdm/nanolib/log"
)

// GetEnrollmentSetsHandler returns a handle that retrieves the list of sets for an enrollment ID.
// GetEnrollmentSetsHandler returns a handler that retrieves the list of sets for an enrollment ID.
func GetEnrollmentSetsHandler(store storage.EnrollmentSetsRetriever, logger log.Logger) http.HandlerFunc {
return simpleJSONResourceHandler(
logger,
Expand All @@ -22,7 +22,7 @@ func GetEnrollmentSetsHandler(store storage.EnrollmentSetsRetriever, logger log.
)
}

// PutEnrollmentSetHandler returns a handle that associates a set to an enrollment.
// PutEnrollmentSetHandler returns a handler that associates a set to an enrollment.
func PutEnrollmentSetHandler(store storage.EnrollmentSetStorer, notifier Notifier, logger log.Logger) http.HandlerFunc {
return simpleChangeResourceHandler(
logger,
Expand All @@ -43,7 +43,7 @@ func PutEnrollmentSetHandler(store storage.EnrollmentSetStorer, notifier Notifie
)
}

// DeleteEnrollmentSetHandler returns a handle that dissociates a set from an enrollment.
// DeleteEnrollmentSetHandler returns a handler that dissociates a set from an enrollment.
func DeleteEnrollmentSetHandler(store storage.EnrollmentSetRemover, notifier Notifier, logger log.Logger) http.HandlerFunc {
return simpleChangeResourceHandler(
logger,
Expand All @@ -63,3 +63,20 @@ func DeleteEnrollmentSetHandler(store storage.EnrollmentSetRemover, notifier Not
},
)
}

// DeleteAllEnrollmentSetsHandler returns a handler that dissociates all sets from an enrollment.
func DeleteAllEnrollmentSetsHandler(store storage.EnrollmentSetRemover, notifier Notifier, logger log.Logger) http.HandlerFunc {
return simpleChangeResourceHandler(
logger,
func(ctx context.Context, resource string, u *url.URL, notify bool) (bool, string, error) {
changed, err := store.RemoveAllEnrollmentSets(ctx, resource)
if err == nil && changed && notify {
err = notifier.Changed(ctx, nil, nil, []string{resource})
if err != nil {
err = fmt.Errorf("notify enrollment: %w", err)
}
}
return changed, "remove enrollment set", err
},
)
}
30 changes: 30 additions & 0 deletions storage/file/enrollments.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,36 @@ func (s *File) RemoveEnrollmentSet(_ context.Context, enrollmentID, setName stri
return changed, nil
}

// RemoveAllEnrollmentSets dissociates enrollment ID from any sets.
// If any associations are removed true is returned.
// It should not be an error if no associations exist.
func (s *File) RemoveAllEnrollmentSets(ctx context.Context, enrollmentID string) (bool, error) {
s.mu.Lock()
defer s.mu.Unlock()

err := s.assureEnrollmentDirExists(enrollmentID)
if err != nil {
return false, fmt.Errorf("assuring enrollment directory exists: %w", err)
}

exist := true
_, err = os.Stat(s.enrollmentSetsFilename(enrollmentID))
if errors.Is(err, os.ErrNotExist) {
exist = false
} else if err != nil {
return false, fmt.Errorf("stat sets for enrollment %s: %w", enrollmentID, err)
}

if exist {
err = os.Remove(s.enrollmentSetsFilename(enrollmentID))
if err != nil {
return exist, fmt.Errorf("removing sets for enrollment %s: %w", enrollmentID, err)
}
}

return exist, nil
}

// RetrieveEnrollmentIDs retrieves MDM enrollment IDs from storage.
// If a set, declaration, or enrollment ID doesn't exist it is ignored.
// See also the storage package for documentation on the storage interfaces.
Expand Down
11 changes: 11 additions & 0 deletions storage/mysql/enrollments.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ func qAndP(params []string) (r string, p []interface{}) {
return
}

// RemoveAllEnrollmentSets dissociates enrollment ID from any sets.
// If any associations are removed true is returned.
// It should not be an error if no associations exist.
func (s *MySQLStorage) RemoveAllEnrollmentSets(ctx context.Context, enrollmentID string) (bool, error) {
r, err := s.q.RemoveAllEnrollmentSets(ctx, enrollmentID)
if err != nil {
return false, err
}
return resultChangedRows(r)
}

// RetrieveEnrollmentIDs retrieves enrollment IDs.
// See also the storage package for documentation on the storage interfaces.
func (s *MySQLStorage) RetrieveEnrollmentIDs(ctx context.Context, declarations []string, sets []string, ids []string) ([]string, error) {
Expand Down
6 changes: 6 additions & 0 deletions storage/mysql/query.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ FROM
ON sd.set_name = es.set_name
WHERE
es.enrollment_id = ?;

-- name: RemoveAllEnrollmentSets :execresult
DELETE FROM
enrollment_sets
WHERE
enrollment_id = ?;
12 changes: 12 additions & 0 deletions storage/mysql/sqlc/query.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ type EnrollmentSetRemover interface {
// If the association is removed true is returned.
// It should not be an error if the association does not exist.
RemoveEnrollmentSet(ctx context.Context, enrollmentID, setName string) (bool, error)

// RemoveAllEnrollmentSets dissociates enrollment ID from any sets.
// If any associations are removed true is returned.
// It should not be an error if no associations exist.
RemoveAllEnrollmentSets(ctx context.Context, enrollmentID string) (bool, error)
}

// EnrollmentSetStorage are storage interfaces related to MDM enrollment IDs.
Expand Down
53 changes: 53 additions & 0 deletions storage/test/enrollments.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,57 @@ func testEnrollments(t *testing.T, store myStorage, ctx context.Context, d *ddm.
t.Error("error should be ErrDeclarationNotFound")
}

// associate again
changed, err := store.StoreEnrollmentSet(ctx, enrollmentID, setName)
if err != nil {
t.Fatal(err)
}

if have, want := changed, true; have != want {
t.Errorf("changed: have: %v, want: %v", have, want)
}

// verify 1 ref
setNames, err = store.RetrieveEnrollmentSets(ctx, enrollmentID)
if err != nil {
t.Fatal(err)
}

if have, want := len(setNames), 1; have != want {
t.Errorf("len(setName) have: %v, want: %v", have, want)
} else {
if have, want := setNames[0], setName; have != want {
t.Errorf("setNames[0] have: %v, want: %v", have, want)
}
}

// remove all sets associated with enrollmentID
changed, err = store.RemoveAllEnrollmentSets(ctx, enrollmentID)
if err != nil {
t.Fatal(err)
}

if have, want := changed, true; have != want {
t.Errorf("changed: have: %v, want: %v", have, want)
}

// verify no ref
setNames, err = store.RetrieveEnrollmentSets(ctx, enrollmentID)
if err != nil {
t.Fatal(err)
}

if have, want := len(setNames), 0; have != want {
t.Errorf("len(setName) have: %v, want: %v", have, want)
}

// remove all sets associated with enrollmentID again (to check changed status)
changed, err = store.RemoveAllEnrollmentSets(ctx, enrollmentID)
if err != nil {
t.Fatal(err)
}

if have, want := changed, false; have != want {
t.Errorf("changed: have: %v, want: %v", have, want)
}
}
10 changes: 10 additions & 0 deletions tools/api-enrollment-sets-delete-all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

URL="${BASE_URL}/v1/enrollment-sets-all/$1"

curl \
$CURL_OPTS \
-u kmfddm:$API_KEY \
-X DELETE \
-w "Response HTTP Code: %{http_code}\n" \
"$URL"

0 comments on commit 04c1c64

Please sign in to comment.