-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdataoperations.go
172 lines (146 loc) · 4 KB
/
dataoperations.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package wireguardhttps
import (
"net"
"github.com/jinzhu/gorm"
"github.com/joncooperworks/wgrpcd"
gormbulk "github.com/t-tiger/gorm-bulk-insert"
)
type dataOperations struct {
db *gorm.DB
}
func wrapPackageError(err error) error {
if err == nil {
return nil
}
if gorm.IsRecordNotFoundError(err) {
return &RecordNotFoundError{err: err}
}
return &DatabaseError{err: err}
}
func (d *dataOperations) Initialize() error {
return wrapPackageError(d.db.AutoMigrate(&UserProfile{}, &Device{}, &IPAddress{}).Error)
}
func (d *dataOperations) Close() error {
return wrapPackageError(d.db.Close())
}
func (d *dataOperations) Addresses() ([]IPAddress, error) {
var addresses []IPAddress
err := d.db.
Find(&addresses).
Error
return addresses, wrapPackageError(err)
}
func (d *dataOperations) AllocateSubnet(addresses []net.IP) error {
var databaseInput []interface{}
// Don't allocate broadcast or network address.
for _, address := range addresses[1 : len(addresses)-1] {
ipAddress := IPAddress{
Address: address.String(),
}
databaseInput = append(databaseInput, ipAddress)
}
err := gormbulk.BulkInsert(d.db, databaseInput, 3000)
if err != nil {
return wrapPackageError(err)
}
return nil
}
func (d *dataOperations) createIPAddress() (IPAddress, error) {
var ipAddress IPAddress
err := d.db.Raw("SELECT * FROM ip_addresses ip WHERE NOT EXISTS (SELECT d.ip_address FROM devices d WHERE d.ip_address = ip.address) LIMIT 1").
Scan(&ipAddress).
Error
return ipAddress, err
}
func (d *dataOperations) CreateDevice(owner UserProfile, name, os string, deviceFunc DeviceFunc) (Device, *wgrpcd.PeerConfigInfo, error) {
var device Device
var credentials *wgrpcd.PeerConfigInfo
err := d.db.Transaction(func(db *gorm.DB) error {
ipAddress, err := d.createIPAddress()
if err != nil {
return err
}
credentials, err = deviceFunc(ipAddress)
if err != nil {
return err
}
device = Device{
Name: name,
OS: os,
PublicKey: credentials.PublicKey,
IPAddress: ipAddress.Address,
Owner: owner,
}
err = d.db.Create(&device).
Error
if err != nil {
return err
}
return nil
})
return device, credentials, wrapPackageError(err)
}
func (d *dataOperations) RekeyDevice(owner UserProfile, device Device, rekeyFunc DeviceFunc) (Device, *wgrpcd.PeerConfigInfo, error) {
var credentials *wgrpcd.PeerConfigInfo
err := d.db.Transaction(func(db *gorm.DB) error {
var err error
credentials, err = rekeyFunc(device.IP)
if err != nil {
return err
}
device.PublicKey = credentials.PublicKey
err = db.Save(&device).
Error
if err != nil {
return err
}
return nil
})
return device, credentials, wrapPackageError(err)
}
func (d *dataOperations) Devices(owner UserProfile) ([]Device, error) {
var devices []Device
err := d.db.Preload("IP").
Preload("Owner").
Where("owner_id = ?", owner.ID).
Find(&devices).
Error
return devices, wrapPackageError(err)
}
func (d *dataOperations) Device(owner UserProfile, deviceID int) (Device, error) {
var device Device
err := d.db.Preload("IP").
Preload("Owner").
Where("owner_id = ?", owner.ID).
First(&device, deviceID).
Error
return device, wrapPackageError(err)
}
func (d *dataOperations) RemoveDevice(owner UserProfile, device Device, deleteFunc DeleteFunc) error {
err := deleteFunc()
if err != nil {
return err
}
err = d.db.Unscoped().
Where("owner_id = ?", owner.ID).
Delete(&device).Error
return wrapPackageError(err)
}
func (d *dataOperations) RegisterUser(authPlatformUserID, authPlatform string) (UserProfile, error) {
user := UserProfile{
AuthPlatformUserID: authPlatformUserID,
AuthPlatform: authPlatform,
}
err := d.db.FirstOrCreate(&user, UserProfile{AuthPlatformUserID: authPlatformUserID}).
Error
return user, wrapPackageError(err)
}
func (d *dataOperations) GetUser(userID int) (UserProfile, error) {
var user UserProfile
err := d.db.First(user, userID).
Error
return user, wrapPackageError(err)
}
func (d *dataOperations) DeleteUser(userID int) error {
return nil
}