source: code/trunk/db.go@ 673

Last change on this file since 673 was 664, checked in by contact, 4 years ago

Make Network.Nick optional

Make Network.Nick optional, default to the user's username. This
will allow adding a global setting to set the nickname in the
future, just like we have for the real name.

References: https://todo.sr.ht/~emersion/soju/110

File size: 3.6 KB
Line 
1package soju
2
3import (
4 "context"
5 "fmt"
6 "net/url"
7 "strings"
8 "time"
9)
10
11type Database interface {
12 Close() error
13 Stats(ctx context.Context) (*DatabaseStats, error)
14
15 ListUsers(ctx context.Context) ([]User, error)
16 GetUser(ctx context.Context, username string) (*User, error)
17 StoreUser(ctx context.Context, user *User) error
18 DeleteUser(ctx context.Context, id int64) error
19
20 ListNetworks(ctx context.Context, userID int64) ([]Network, error)
21 StoreNetwork(ctx context.Context, userID int64, network *Network) error
22 DeleteNetwork(ctx context.Context, id int64) error
23 ListChannels(ctx context.Context, networkID int64) ([]Channel, error)
24 StoreChannel(ctx context.Context, networKID int64, ch *Channel) error
25 DeleteChannel(ctx context.Context, id int64) error
26
27 ListDeliveryReceipts(ctx context.Context, networkID int64) ([]DeliveryReceipt, error)
28 StoreClientDeliveryReceipts(ctx context.Context, networkID int64, client string, receipts []DeliveryReceipt) error
29}
30
31func OpenDB(driver, source string) (Database, error) {
32 switch driver {
33 case "sqlite3":
34 return OpenSqliteDB(source)
35 case "postgres":
36 return OpenPostgresDB(source)
37 default:
38 return nil, fmt.Errorf("unsupported database driver: %q", driver)
39 }
40}
41
42type DatabaseStats struct {
43 Users int64
44 Networks int64
45 Channels int64
46}
47
48type User struct {
49 ID int64
50 Username string
51 Password string // hashed
52 Realname string
53 Admin bool
54}
55
56type SASL struct {
57 Mechanism string
58
59 Plain struct {
60 Username string
61 Password string
62 }
63
64 // TLS client certificate authentication.
65 External struct {
66 // X.509 certificate in DER form.
67 CertBlob []byte
68 // PKCS#8 private key in DER form.
69 PrivKeyBlob []byte
70 }
71}
72
73type Network struct {
74 ID int64
75 Name string
76 Addr string
77 Nick string
78 Username string
79 Realname string
80 Pass string
81 ConnectCommands []string
82 SASL SASL
83 Enabled bool
84}
85
86func (net *Network) GetName() string {
87 if net.Name != "" {
88 return net.Name
89 }
90 return net.Addr
91}
92
93func (net *Network) URL() (*url.URL, error) {
94 s := net.Addr
95 if !strings.Contains(s, "://") {
96 // This is a raw domain name, make it an URL with the default scheme
97 s = "ircs://" + s
98 }
99
100 u, err := url.Parse(s)
101 if err != nil {
102 return nil, fmt.Errorf("failed to parse upstream server URL: %v", err)
103 }
104
105 return u, nil
106}
107
108func (net *Network) GetUsername() string {
109 if net.Username != "" {
110 return net.Username
111 }
112 return net.Nick
113}
114
115func GetNick(user *User, net *Network) string {
116 if net.Nick != "" {
117 return net.Nick
118 }
119 return user.Username
120}
121
122func GetRealname(user *User, net *Network) string {
123 if net.Realname != "" {
124 return net.Realname
125 }
126 if user.Realname != "" {
127 return user.Realname
128 }
129 return GetNick(user, net)
130}
131
132type MessageFilter int
133
134const (
135 // TODO: use customizable user defaults for FilterDefault
136 FilterDefault MessageFilter = iota
137 FilterNone
138 FilterHighlight
139 FilterMessage
140)
141
142func parseFilter(filter string) (MessageFilter, error) {
143 switch filter {
144 case "default":
145 return FilterDefault, nil
146 case "none":
147 return FilterNone, nil
148 case "highlight":
149 return FilterHighlight, nil
150 case "message":
151 return FilterMessage, nil
152 }
153 return 0, fmt.Errorf("unknown filter: %q", filter)
154}
155
156type Channel struct {
157 ID int64
158 Name string
159 Key string
160
161 Detached bool
162 DetachedInternalMsgID string
163
164 RelayDetached MessageFilter
165 ReattachOn MessageFilter
166 DetachAfter time.Duration
167 DetachOn MessageFilter
168}
169
170type DeliveryReceipt struct {
171 ID int64
172 Target string // channel or nick
173 Client string
174 InternalMsgID string
175}
Note: See TracBrowser for help on using the repository browser.