• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / deviceauth / 948596009

pending completion
948596009

push

gitlab-ci

web-flow
Merge pull request #655 from merlin-northern/men_6529_merge_single_db_to_master

Merge single db to master

332 of 405 new or added lines in 5 files covered. (81.98%)

16 existing lines in 2 files now uncovered.

4809 of 5767 relevant lines covered (83.39%)

48.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.58
/store/mongo/datastore_mongo_cleanup.go
1
// Copyright 2023 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
package mongo
16

17
import (
18
        "context"
19

20
        "github.com/pkg/errors"
21
        "go.mongodb.org/mongo-driver/bson"
22
        "go.mongodb.org/mongo-driver/mongo"
23

24
        "github.com/mendersoftware/deviceauth/model"
25
        "github.com/mendersoftware/deviceauth/store"
26
)
27

28
// Retrieves devices with decommissioning flag set
29
func (db *DataStoreMongo) GetDevicesBeingDecommissioned(tenantId string) ([]model.Device, error) {
2✔
30
        c := db.client.Database(DbName).Collection(DbDevicesColl)
2✔
31

2✔
32
        devices := []model.Device{}
2✔
33

2✔
34
        cursor, err := c.Find(
2✔
35
                context.Background(),
2✔
36
                model.Device{
2✔
37
                        Decommissioning: true,
2✔
38
                        TenantID:        tenantId,
2✔
39
                },
2✔
40
        )
2✔
41
        if err != nil {
2✔
42
                return nil, err
×
43
        }
×
44
        if err = cursor.All(context.Background(), &devices); err != nil {
2✔
45
                if err == mongo.ErrNoDocuments {
×
46
                        return nil, store.ErrDevNotFound
×
47
                }
×
48
                return nil, errors.Wrap(err, "failed to fetch devices")
×
49
        }
50

51
        return devices, nil
2✔
52
}
53

54
// Retrieves Ids of the auth sets owned by devices that are in decommissioning state or not owned by
55
// any device.
56
func (db *DataStoreMongo) GetBrokenAuthSets(tenantId string) ([]string, error) {
9✔
57
        c := db.client.Database(DbName).Collection(DbAuthSetColl)
9✔
58

9✔
59
        deviceIds := []string{}
9✔
60
        brokenAuthSets := []string{}
9✔
61

9✔
62
        ctx := context.Background()
9✔
63

9✔
64
        // get all auth sets; group by device id
9✔
65
        match := bson.D{
9✔
66
                {
9✔
67
                        Key: "$match", Value: bson.D{
9✔
68
                                {Key: dbFieldTenantID, Value: tenantId}},
9✔
69
                },
9✔
70
        }
9✔
71
        group := bson.D{
9✔
72
                {
9✔
73
                        Key: "$group", Value: bson.D{
9✔
74
                                {Key: "_id", Value: "$device_id"}},
9✔
75
                },
9✔
76
        }
9✔
77
        pipeline := []bson.D{
9✔
78
                match,
9✔
79
                group,
9✔
80
        }
9✔
81
        var result []struct {
9✔
82
                DeviceId string `bson:"_id"`
9✔
83
        }
9✔
84

9✔
85
        cursor, err := c.Aggregate(ctx, pipeline)
9✔
86
        if err != nil {
9✔
87
                return nil, err
×
88
        }
×
89
        if err := cursor.All(ctx, &result); err != nil {
9✔
90
                if err == mongo.ErrNoDocuments {
×
91
                        return nil, nil
×
92
                }
×
93
                return nil, err
×
94
        }
95

96
        for _, res := range result {
18✔
97
                deviceIds = append(deviceIds, res.DeviceId)
9✔
98
        }
9✔
99

100
        //check if devices exists
101
        nonexistentDevices, err := db.filterNonExistentDevices(tenantId, deviceIds)
9✔
102
        if err != nil {
9✔
103
                return nil, err
×
104
        }
×
105

106
        // fetch auth sets for non exisitent devices
107
        for _, dev := range nonexistentDevices {
13✔
108

4✔
109
                authSets := []model.AuthSet{}
4✔
110

4✔
111
                cursor, err := c.Find(ctx, bson.M{"device_id": dev, dbFieldTenantID: tenantId})
4✔
112
                if err != nil {
4✔
113
                        return nil, errors.Wrap(err, "failed to fetch authentication sets")
×
114
                }
×
115
                if err = cursor.All(ctx, &authSets); err != nil {
4✔
116
                        if err != mongo.ErrNoDocuments {
×
117
                                return nil, errors.Wrap(err, "failed to fetch authentication sets")
×
118
                        }
×
119
                }
120

121
                for _, authSet := range authSets {
8✔
122
                        brokenAuthSets = append(brokenAuthSets, authSet.Id)
4✔
123
                }
4✔
124
        }
125

126
        return brokenAuthSets, nil
9✔
127
}
128

129
// Deletes devices with decommissioning flag set
130
func (db *DataStoreMongo) DeleteDevicesBeingDecommissioned(tenantId string) error {
2✔
131
        c := db.client.Database(DbName).Collection(DbDevicesColl)
2✔
132

2✔
133
        _, err := c.DeleteMany(
2✔
134
                context.Background(),
2✔
135
                model.Device{
2✔
136
                        Decommissioning: true,
2✔
137
                        TenantID:        tenantId,
2✔
138
                },
2✔
139
        )
2✔
140
        if err != nil {
2✔
141
                return errors.Wrap(err, "failed to remove decommissioned devices")
×
142
        }
×
143

144
        return nil
2✔
145
}
146

147
// Deletes auth sets owned by devices that are in decommissioning state and auth sets not
148
// owned by any device.
149
func (db *DataStoreMongo) DeleteBrokenAuthSets(tenantId string) error {
3✔
150
        database := db.client.Database(DbName)
3✔
151
        collAuthSets := database.Collection(DbAuthSetColl)
3✔
152
        collTokens := database.Collection(DbTokensColl)
3✔
153

3✔
154
        authSets, err := db.GetBrokenAuthSets(tenantId)
3✔
155
        if err != nil {
3✔
156
                return err
×
157
        }
×
158

159
        // delete authsets for non-existent devices
160
        ctx := context.Background()
3✔
161
        for _, as := range authSets {
4✔
162
                _, err := collAuthSets.DeleteOne(ctx, model.AuthSet{Id: as, TenantID: tenantId})
1✔
163
                if err != nil {
1✔
NEW
164
                        return errors.Wrapf(err, "tenant %s, failed to delete authentication sets", tenantId)
×
165
                }
×
166
                // Attempt to delete token (may have already expired).
167
                _, _ = collTokens.DeleteOne(ctx, bson.M{"_id": as, dbFieldTenantClaim: tenantId})
1✔
168
        }
169

170
        return nil
3✔
171
}
172

173
// Filters list of device ids.
174
// Result is the list of ids of non-existent devices and devices with decommissioning flag set.
175
func (db *DataStoreMongo) filterNonExistentDevices(
176
        tenantId string,
177
        devIds []string,
178
) ([]string, error) {
9✔
179
        c := db.client.Database(DbName).Collection(DbDevicesColl)
9✔
180

9✔
181
        nonexistentDevices := []string{}
9✔
182

9✔
183
        //check if device exists
9✔
184
        for _, devId := range devIds {
18✔
185
                res := model.Device{}
9✔
186
                err := c.FindOne(
9✔
187
                        context.Background(),
9✔
188
                        bson.M{
9✔
189
                                "_id":           devId,
9✔
190
                                dbFieldTenantID: tenantId,
9✔
191
                        },
9✔
192
                ).Decode(&res)
9✔
193

9✔
194
                if err != nil {
12✔
195
                        if err == mongo.ErrNoDocuments {
6✔
196
                                nonexistentDevices = append(nonexistentDevices, devId)
3✔
197
                        } else {
3✔
NEW
198
                                return nil, errors.Wrapf(err, "tenant %s, failed to fetch device", tenantId)
×
199
                        }
×
200
                }
201

202
                if res.Decommissioning {
10✔
203
                        nonexistentDevices = append(nonexistentDevices, devId)
1✔
204
                }
1✔
205
        }
206

207
        return nonexistentDevices, nil
9✔
208
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc