/
tasks.go
157 lines (122 loc) · 2.96 KB
/
tasks.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
package tasks
import (
"fmt"
"log"
"net"
"github.com/ehmry/go-cjdns/key"
"github.com/willeponken/elvisp/cjdns"
"github.com/willeponken/elvisp/database"
"github.com/willeponken/elvisp/lease"
)
const (
errorInvalidLength = "2 Invalid length of arguments"
errorInvalidTask = "1 Invalid task specified"
)
// TaskInterface defines the methods needed for a default task
type TaskInterface interface {
Run() (result string, err error)
}
// Task needs the arguments to use, and a database to save the changes to
type Task struct {
argv []string
db *database.Database
admin *cjdns.Conn
clientIP net.IP
pubkey *key.Public
cidrs []lease.CIDR
}
// Init returns a new task
func Init(argv []string, db *database.Database, admin *cjdns.Conn, clientIP net.IP, cidrs []lease.CIDR) (task Task, err error) {
task.argv = argv
task.db = db
task.admin = admin
task.clientIP = clientIP
task.cidrs = cidrs
var k string
k, err = task.admin.LookupPubKey(clientIP.String())
if err != nil {
return task, err
}
task.pubkey, err = key.DecodePublic(k)
if err != nil {
return task, err
}
return
}
// Add should implement the add task
type Add struct{ Task }
// Remove should implement the remove task
type Remove struct{ Task }
// Lease should implement the lease task
type Lease struct{ Task }
// Release should implement the release task
type Release struct{ Task }
// Invalid should implement the invalid task, i.e. take an error
type Invalid struct{ Error error }
// allowIPTunnel adds the defined IP to the cjdns IP tunnel, if it fails, it will delete the user from the database.
func (t Add) allowIPTunnel(c lease.CIDR, id uint64) (ip net.IP, err error) {
ip, err = lease.Generate(c, id)
if err != nil {
return
}
if err = t.admin.AddUser(t.pubkey, ip); err != nil {
if e := t.db.DelUser(t.pubkey); e != nil {
log.Println(err)
}
return
}
return
}
// Run Add adds a user using the public key and a token.
func (t Add) Run() (result string, err error) {
var id uint64
var ip net.IP
id, err = t.db.AddUser(t.pubkey)
if err != nil {
return
}
for _, cidr := range t.cidrs {
ip, err = t.allowIPTunnel(cidr, id)
if err != nil {
return
}
result += ip.String() + " "
}
return
}
// Run Remove removes a user.
func (t Remove) Run() (result string, err error) {
db := t.db
admin := t.admin
pubkey := t.pubkey
if err = db.DelUser(pubkey); err != nil {
return
}
if err = admin.DelUser(pubkey); err != nil {
return
}
result = fmt.Sprintf("Removed user: %s", pubkey.String())
return
}
// Run Lease returns the users leases.
func (t Lease) Run() (result string, err error) {
var id uint64
var ip net.IP
id, err = t.db.GetID(t.pubkey)
if err != nil {
return
}
for _, cidr := range t.cidrs {
ip, err = lease.Generate(cidr, id)
if err != nil {
return
}
result += ip.String() + " "
}
return
}
// Run Invalid returns an error and empty result.
func (t Invalid) Run() (result string, err error) {
err = t.Error
return
}