-
Notifications
You must be signed in to change notification settings - Fork 1
/
datastore.go
147 lines (116 loc) · 3.79 KB
/
datastore.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
// Ecca Authentication Proxy
//
// Handles Eccentric Authentication in a web proxy for browsers.
//
// Copyright 2013, Guido Witmond <guido@witmond.nl>
// Licensed under AGPL v3 or later. See LICENSE
package main // eccaproxy
// This file contains the data storage bits
import (
"fmt"
// These are for the data storage
"gopkg.in/gorp.v1"
"database/sql"
_ "github.com/mattn/go-sqlite3"
"time"
)
var dbmap *gorp.DbMap
func init_datastore(datastore string) {
db, err := sql.Open("sqlite3", datastore)
check(err)
dbmap = &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
dbmap.AddTableWithName(credentials{}, "credentials").SetKeys(true, "Id")
dbmap.AddTableWithName(TorTLSlistener{}, "listeners")
dbmap.CreateTables() // if not exists
//dbmap.TraceOn("[gorp]", log.New(os.Stdout, "myapp:", log.Lmicroseconds))
}
// Add a credential to the list of credentials for the host.
// People can have multiple accounts a host.
func setCredentials(cred credentials) {
check(dbmap.Insert(&cred))
}
func updateLastUsedTime(cred credentials) {
cred.LastUsed = time.Now().Unix()
_, err := dbmap.Update(&cred)
check(err)
}
// Just get all credentials... (sorted by getCredentials)
func getAllCreds () ([]credentials) {
creds, err := getCredentials()
check(err)
return creds
}
// Get list of all creds for a specified hostname
func getCreds (hostname string) ([]credentials) {
creds, err := getCredentials(hostname)
check(err)
return creds
}
// get a credential for a hostname, cn pair.
// or return nil.
// die if there is more than one! TODO: Change that to a juicy error stating that the FPCA is dishonest.
func getCred (hostname string, cn string) (*credentials) {
creds, err := getCredentials(hostname, cn)
check(err)
switch len(creds) {
case 0:
return nil
case 1:
return &creds[0]
default: panic(fmt.Sprintf("Too many credentials for host: %s, CN: %s", hostname, cn))
}
}
// getCredentials, all of them, all for a host, or a single one.
func getCredentials(args... interface{}) (creds []credentials, err error) {
var query string
switch {
case len(args) == 0:
query = "SELECT * FROM credentials"
case len(args) == 1:
query = "SELECT * FROM credentials WHERE hostname = ?"
case len(args) == 2:
query = "SELECT * FROM credentials WHERE hostname = ? AND cn = ?"
}
query += " ORDER BY hostname, cn"
_, err = dbmap.Select(&creds, query, args...)
if err != nil { return nil, err }
return // creds
}
// Listeners
func (listener TorTLSlistener) Store() {
check(dbmap.Insert(&listener))
}
// Just get all listeners
func getAllListeners () ([]TorTLSlistener, error) {
query := "SELECT * FROM listeners"
dbls, err := dbmap.Select(TorTLSlistener{}, query)
if err != nil { return nil, err }
// ugly boilerplate. Can this be done better?
var res = make([]TorTLSlistener, len(dbls))
for i, e := range dbls {
res[i] = *e.(*TorTLSlistener)
}
return res, nil
}
type AllDetails struct {
Hostname string
ListenerCN string
CallerCN *string
Application *string
}
// get all details (realms), hosts, accounts, callers, application for all records.
func getAllDetails() (map[string][]AllDetails) {
query := `SELECT cr.hostname AS hostname, cr.cn AS listenerCN,
li.callerCN AS callerCN, li.application AS application
FROM credentials cr LEFT OUTER JOIN listeners li ON cr.cn = li.listenercn
ORDER BY cr.hostname, cr.cn, li.callercn, li.application;`
var list []AllDetails
_, err := dbmap.Select(&list, query)
check(err)
details := map[string][]AllDetails{}
for _, item := range list {
hostname := item.Hostname
details[hostname] = append(details[hostname],item)
}
return details
}