mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-22 20:09:41 +01:00
some tweaks to account/channel unregistration
This commit is contained in:
parent
f4a284675d
commit
02a4aaf583
@ -10,6 +10,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/goshuirc/irc-go/ircfmt"
|
"github.com/goshuirc/irc-go/ircfmt"
|
||||||
"github.com/oragono/oragono/irc/modes"
|
"github.com/oragono/oragono/irc/modes"
|
||||||
@ -287,15 +288,10 @@ func csUnregisterHandler(server *Server, client *Client, command, params string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
info := channel.ExportRegistration(0)
|
info := channel.ExportRegistration(0)
|
||||||
// verification code is the crc32 of the name, plus the registration time
|
expectedCode := unregisterConfirmationCode(info.Name, info.RegisteredAt)
|
||||||
var codeInput bytes.Buffer
|
if expectedCode != verificationCode {
|
||||||
codeInput.WriteString(info.Name)
|
csNotice(rb, ircfmt.Unescape(client.t("$bWarning: unregistering this channel will remove all stored channel attributes.$b")))
|
||||||
codeInput.WriteString(strconv.FormatInt(info.RegisteredAt.Unix(), 16))
|
csNotice(rb, fmt.Sprintf(client.t("To confirm channel unregistration, type: /CS UNREGISTER %s %s"), channelKey, expectedCode))
|
||||||
expectedCode := int(crc32.ChecksumIEEE(codeInput.Bytes()))
|
|
||||||
receivedCode, err := strconv.Atoi(verificationCode)
|
|
||||||
if err != nil || expectedCode != receivedCode {
|
|
||||||
csNotice(rb, client.t("$bWarning:$b Unregistering this channel will remove all stored channel attributes."))
|
|
||||||
csNotice(rb, fmt.Sprintf(client.t("To confirm channel unregistration, type: /CS UNREGISTER %s %d"), channelKey, expectedCode))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,3 +299,11 @@ func csUnregisterHandler(server *Server, client *Client, command, params string,
|
|||||||
go server.channelRegistry.Delete(channelKey, info)
|
go server.channelRegistry.Delete(channelKey, info)
|
||||||
csNotice(rb, fmt.Sprintf(client.t("Channel %s is now unregistered"), channelKey))
|
csNotice(rb, fmt.Sprintf(client.t("Channel %s is now unregistered"), channelKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deterministically generates a confirmation code for unregistering a channel / account
|
||||||
|
func unregisterConfirmationCode(name string, registeredAt time.Time) (code string) {
|
||||||
|
var codeInput bytes.Buffer
|
||||||
|
codeInput.WriteString(name)
|
||||||
|
codeInput.WriteString(strconv.FormatInt(registeredAt.Unix(), 16))
|
||||||
|
return strconv.Itoa(int(crc32.ChecksumIEEE(codeInput.Bytes())))
|
||||||
|
}
|
||||||
|
@ -255,7 +255,10 @@ func umodeGreaterThan(l modes.Mode, r modes.Mode) bool {
|
|||||||
|
|
||||||
// ProcessAccountToUmodeChange processes Add/Remove/List operations for channel persistent usermodes.
|
// ProcessAccountToUmodeChange processes Add/Remove/List operations for channel persistent usermodes.
|
||||||
func (channel *Channel) ProcessAccountToUmodeChange(client *Client, change modes.ModeChange) (results []modes.ModeChange, err error) {
|
func (channel *Channel) ProcessAccountToUmodeChange(client *Client, change modes.ModeChange) (results []modes.ModeChange, err error) {
|
||||||
umodeGEQ := func(l modes.Mode, r modes.Mode) bool {
|
hasPrivsOver := func(l modes.Mode, r modes.Mode) bool {
|
||||||
|
if l == modes.ChannelAdmin {
|
||||||
|
return umodeGreaterThan(l, r)
|
||||||
|
}
|
||||||
return l == r || umodeGreaterThan(l, r)
|
return l == r || umodeGreaterThan(l, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,9 +278,9 @@ func (channel *Channel) ProcessAccountToUmodeChange(client *Client, change modes
|
|||||||
// operators and founders can do anything
|
// operators and founders can do anything
|
||||||
hasPrivs := isOperChange || (account != "" && account == channel.registeredFounder)
|
hasPrivs := isOperChange || (account != "" && account == channel.registeredFounder)
|
||||||
// halfop and up can list, and do add/removes at levels <= their own
|
// halfop and up can list, and do add/removes at levels <= their own
|
||||||
if change.Op == modes.List && umodeGEQ(clientMode, modes.Halfop) {
|
if change.Op == modes.List && hasPrivsOver(clientMode, modes.Halfop) {
|
||||||
hasPrivs = true
|
hasPrivs = true
|
||||||
} else if umodeGEQ(clientMode, modes.Halfop) && umodeGEQ(clientMode, targetModeNow) && umodeGEQ(clientMode, targetModeAfter) {
|
} else if hasPrivsOver(clientMode, modes.Halfop) && hasPrivsOver(clientMode, targetModeNow) && hasPrivsOver(clientMode, targetModeAfter) {
|
||||||
hasPrivs = true
|
hasPrivs = true
|
||||||
}
|
}
|
||||||
if !hasPrivs {
|
if !hasPrivs {
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/goshuirc/irc-go/ircfmt"
|
||||||
"github.com/oragono/oragono/irc/utils"
|
"github.com/oragono/oragono/irc/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -98,10 +99,12 @@ SADROP forcibly de-links the given nickname from the attached user account.`,
|
|||||||
},
|
},
|
||||||
"unregister": {
|
"unregister": {
|
||||||
handler: nsUnregisterHandler,
|
handler: nsUnregisterHandler,
|
||||||
help: `Syntax: $bUNREGISTER [username]$b
|
help: `Syntax: $bUNREGISTER <username> [code]$b
|
||||||
|
|
||||||
UNREGISTER lets you delete your user account (or the given one, if you're an
|
UNREGISTER lets you delete your user account (or someone else's, if you're an
|
||||||
IRC operator with the correct permissions).`,
|
IRC operator with the correct permissions). To prevent accidental
|
||||||
|
unregistrations, a verification code is required; invoking the command without
|
||||||
|
a code will display the necessary code.`,
|
||||||
helpShort: `$bUNREGISTER$b lets you delete your user account.`,
|
helpShort: `$bUNREGISTER$b lets you delete your user account.`,
|
||||||
},
|
},
|
||||||
"verify": {
|
"verify": {
|
||||||
@ -316,7 +319,7 @@ func nsRegisterHandler(server *Server, client *Client, command, params string, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
func nsUnregisterHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
|
func nsUnregisterHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
|
||||||
username, _ := utils.ExtractParam(params)
|
username, verificationCode := utils.ExtractParam(params)
|
||||||
|
|
||||||
if !server.AccountConfig().Registration.Enabled {
|
if !server.AccountConfig().Registration.Enabled {
|
||||||
nsNotice(rb, client.t("Account registration has been disabled"))
|
nsNotice(rb, client.t("Account registration has been disabled"))
|
||||||
@ -324,22 +327,32 @@ func nsUnregisterHandler(server *Server, client *Client, command, params string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if username == "" {
|
if username == "" {
|
||||||
username = client.Account()
|
nsNotice(rb, client.t("You must specify an account"))
|
||||||
}
|
|
||||||
if username == "" {
|
|
||||||
nsNotice(rb, client.t("You're not logged into an account"))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cfname, err := CasefoldName(username)
|
|
||||||
if err != nil {
|
account, err := server.accounts.LoadAccount(username)
|
||||||
nsNotice(rb, client.t("Invalid username"))
|
if err == errAccountDoesNotExist {
|
||||||
|
nsNotice(rb, client.t("Invalid account name"))
|
||||||
|
return
|
||||||
|
} else if err != nil {
|
||||||
|
nsNotice(rb, client.t("Internal error"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !(cfname == client.Account() || client.HasRoleCapabs("unregister")) {
|
|
||||||
|
cfname, _ := CasefoldName(username)
|
||||||
|
if !(cfname == client.Account() || client.HasRoleCapabs("accreg")) {
|
||||||
nsNotice(rb, client.t("Insufficient oper privs"))
|
nsNotice(rb, client.t("Insufficient oper privs"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expectedCode := unregisterConfirmationCode(account.Name, account.RegisteredAt)
|
||||||
|
if expectedCode != verificationCode {
|
||||||
|
nsNotice(rb, ircfmt.Unescape(client.t("$bWarning: unregistering this account will remove its stored privileges.$b")))
|
||||||
|
nsNotice(rb, fmt.Sprintf(client.t("To confirm account unregistration, type: /NS UNREGISTER %s %s"), cfname, expectedCode))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if cfname == client.Account() {
|
if cfname == client.Account() {
|
||||||
client.server.accounts.Logout(client)
|
client.server.accounts.Logout(client)
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ oper-classes:
|
|||||||
capabilities:
|
capabilities:
|
||||||
- "oper:rehash"
|
- "oper:rehash"
|
||||||
- "oper:die"
|
- "oper:die"
|
||||||
- "unregister"
|
- "accreg"
|
||||||
- "sajoin"
|
- "sajoin"
|
||||||
- "samode"
|
- "samode"
|
||||||
- "vhosts"
|
- "vhosts"
|
||||||
|
Loading…
Reference in New Issue
Block a user