Browse Source

add persistence for user modes

tags/v2.1.0-rc1
Shivaram Lingamneni 4 years ago
parent
commit
4d50607c79
3 changed files with 48 additions and 4 deletions
  1. 25
    1
      irc/accounts.go
  2. 19
    3
      irc/client.go
  3. 4
    0
      irc/modes.go

+ 25
- 1
irc/accounts.go View File

@@ -19,6 +19,7 @@ import (
19 19
 	"github.com/oragono/oragono/irc/connection_limits"
20 20
 	"github.com/oragono/oragono/irc/email"
21 21
 	"github.com/oragono/oragono/irc/ldap"
22
+	"github.com/oragono/oragono/irc/modes"
22 23
 	"github.com/oragono/oragono/irc/passwd"
23 24
 	"github.com/oragono/oragono/irc/utils"
24 25
 	"github.com/tidwall/buntdb"
@@ -40,6 +41,7 @@ const (
40 41
 	keyAccountChannels         = "account.channels %s" // channels registered to the account
41 42
 	keyAccountJoinedChannels   = "account.joinedto %s" // channels a persistent client has joined
42 43
 	keyAccountLastSeen         = "account.lastseen %s"
44
+	keyAccountModes            = "account.modes %s" // user modes for the always-on client as a string
43 45
 
44 46
 	keyVHostQueueAcctToId = "vhostQueue %s"
45 47
 	vhostRequestIdx       = "vhostQueue"
@@ -127,7 +129,7 @@ func (am *AccountManager) createAlwaysOnClients(config *Config) {
127 129
 		account, err := am.LoadAccount(accountName)
128 130
 		if err == nil && account.Verified &&
129 131
 			persistenceEnabled(config.Accounts.Multiclient.AlwaysOn, account.Settings.AlwaysOn) {
130
-			am.server.AddAlwaysOnClient(account, am.loadChannels(accountName), am.loadLastSeen(accountName))
132
+			am.server.AddAlwaysOnClient(account, am.loadChannels(accountName), am.loadLastSeen(accountName), am.loadModes(accountName))
131 133
 		}
132 134
 	}
133 135
 }
@@ -594,6 +596,28 @@ func (am *AccountManager) loadChannels(account string) (channels []string) {
594 596
 	return
595 597
 }
596 598
 
599
+func (am *AccountManager) saveModes(account string, uModes modes.Modes) {
600
+	modeStr := uModes.String()
601
+	key := fmt.Sprintf(keyAccountModes, account)
602
+	am.server.store.Update(func(tx *buntdb.Tx) error {
603
+		tx.Set(key, modeStr, nil)
604
+		return nil
605
+	})
606
+}
607
+
608
+func (am *AccountManager) loadModes(account string) (uModes modes.Modes) {
609
+	key := fmt.Sprintf(keyAccountModes, account)
610
+	var modeStr string
611
+	am.server.store.View(func(tx *buntdb.Tx) error {
612
+		modeStr, _ = tx.Get(key)
613
+		return nil
614
+	})
615
+	for _, m := range modeStr {
616
+		uModes = append(uModes, modes.Mode(m))
617
+	}
618
+	return
619
+}
620
+
597 621
 func (am *AccountManager) saveLastSeen(account string, lastSeen time.Time) {
598 622
 	key := fmt.Sprintf(keyAccountLastSeen, account)
599 623
 	var val string

+ 19
- 3
irc/client.go View File

@@ -360,7 +360,7 @@ func (server *Server) RunClient(conn IRCConn) {
360 360
 	client.run(session)
361 361
 }
362 362
 
363
-func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastSeen time.Time) {
363
+func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastSeen time.Time, uModes modes.Modes) {
364 364
 	now := time.Now().UTC()
365 365
 	config := server.Config()
366 366
 	if lastSeen.IsZero() {
@@ -383,9 +383,10 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string,
383 383
 		alwaysOn: true,
384 384
 	}
385 385
 
386
-	ApplyUserModeChanges(client, config.Accounts.defaultUserModes, false, nil)
387
-
388 386
 	client.SetMode(modes.TLS, true)
387
+	for _, m := range uModes {
388
+		client.SetMode(m, true)
389
+	}
389 390
 	client.writerSemaphore.Initialize(1)
390 391
 	client.history.Initialize(0, 0)
391 392
 	client.brbTimer.Initialize(client)
@@ -1633,6 +1634,7 @@ func (client *Client) historyStatus(config *Config) (status HistoryStatus, targe
1633 1634
 const (
1634 1635
 	IncludeChannels uint = 1 << iota
1635 1636
 	IncludeLastSeen
1637
+	IncludeUserModes
1636 1638
 )
1637 1639
 
1638 1640
 func (client *Client) markDirty(dirtyBits uint) {
@@ -1691,4 +1693,18 @@ func (client *Client) performWrite() {
1691 1693
 	if (dirtyBits & IncludeLastSeen) != 0 {
1692 1694
 		client.server.accounts.saveLastSeen(account, lastSeen)
1693 1695
 	}
1696
+	if (dirtyBits & IncludeUserModes) != 0 {
1697
+		uModes := make(modes.Modes, 0, len(modes.SupportedUserModes))
1698
+		for _, m := range modes.SupportedUserModes {
1699
+			switch m {
1700
+			case modes.Operator, modes.ServerNotice:
1701
+				// these can't be persisted because they depend on the operator block
1702
+			default:
1703
+				if client.HasMode(m) {
1704
+					uModes = append(uModes, m)
1705
+				}
1706
+			}
1707
+		}
1708
+		client.server.accounts.saveModes(account, uModes)
1709
+	}
1694 1710
 }

+ 4
- 0
irc/modes.go View File

@@ -102,6 +102,10 @@ func ApplyUserModeChanges(client *Client, changes modes.ModeChanges, force bool,
102 102
 		// can't do anything to TLS mode
103 103
 	}
104 104
 
105
+	if len(applied) != 0 {
106
+		client.markDirty(IncludeUserModes)
107
+	}
108
+
105 109
 	// return the changes we could actually apply
106 110
 	return applied
107 111
 }

Loading…
Cancel
Save