diff --git a/irc/accounts.go b/irc/accounts.go index 171832ec..83ab6971 100644 --- a/irc/accounts.go +++ b/irc/accounts.go @@ -18,5 +18,5 @@ type ClientAccount struct { // RegisteredAt represents the time that the account was registered. RegisteredAt time.Time // Clients that are currently logged into this account (useful for notifications). - Clients []Client + Clients []*Client } diff --git a/irc/numerics.go b/irc/numerics.go index 6430a6b3..91899438 100644 --- a/irc/numerics.go +++ b/irc/numerics.go @@ -149,6 +149,15 @@ const ( ERR_NOOPERHOST = "491" ERR_UMODEUNKNOWNFLAG = "501" ERR_USERSDONTMATCH = "502" + RPL_LOGGEDIN = "900" + RPL_LOGGEDOUT = "901" + ERR_NICKLOCKED = "902" + RPL_SASLSUCCESS = "903" + ERR_SASLFAIL = "904" + ERR_SASLTOOLONG = "905" + ERR_SASLABORTED = "906" + ERR_SASLALREADY = "907" + RPL_SASLMECHS = "908" RPL_REGISTRATION_SUCCESS = "920" ERR_ACCOUNT_ALREADY_EXISTS = "921" ERR_REG_UNSPECIFIED_ERROR = "922" diff --git a/irc/registration.go b/irc/registration.go index 1fadfb3e..913662d8 100644 --- a/irc/registration.go +++ b/irc/registration.go @@ -19,6 +19,7 @@ import ( const ( keyAccountExists = "account %s exists" keyAccountVerified = "account %s verified" + keyAccountName = "account %s name" // stores the 'preferred name' of the account, casemapped appropriately keyAccountRegTime = "account %s registered.time" keyAccountCredentials = "account %s credentials" ) @@ -94,6 +95,7 @@ func regCreateHandler(server *Server, client *Client, msg ircmsg.IrcMessage) boo // get and sanitise account name account := NewName(msg.Params[1]) + //TODO(dan): probably don't need explicit check for "*" here... until we actually casemap properly as per rfc7700 if !account.IsNickname() || msg.Params[1] == "*" { client.Send(nil, server.nameString, ERR_REG_UNSPECIFIED_ERROR, client.nickString, msg.Params[1], "Account name is not valid") return false @@ -115,6 +117,7 @@ func regCreateHandler(server *Server, client *Client, msg ircmsg.IrcMessage) boo registeredTimeKey := fmt.Sprintf(keyAccountRegTime, accountString) tx.Set(accountKey, "1", nil) + tx.Set(fmt.Sprintf(keyAccountName, accountString), strings.TrimSpace(msg.Params[1]), nil) tx.Set(registeredTimeKey, strconv.FormatInt(time.Now().Unix(), 10), nil) return nil }) @@ -230,6 +233,20 @@ func regCreateHandler(server *Server, client *Client, msg ircmsg.IrcMessage) boo if callbackNamespace == "*" { err = server.store.Update(func(tx *buntdb.Tx) error { tx.Set(keyAccountVerified, "1", nil) + + // load acct info inside store tx + account := ClientAccount{ + Name: strings.TrimSpace(msg.Params[1]), + RegisteredAt: time.Now(), + Clients: []*Client{client}, + } + //TODO(dan): Consider creating ircd-wide account adding/removing/affecting lock for protecting access to these sorts of variables + server.accounts[accountString] = &account + client.account = &account + + client.Send(nil, server.nameString, RPL_REGISTRATION_SUCCESS, client.nickString, accountString, "Account created") + client.Send(nil, server.nameString, RPL_LOGGEDIN, client.nickString, client.nickMaskString, accountString, fmt.Sprintf("You are now logged in as %s", accountString)) + client.Send(nil, server.nameString, RPL_SASLSUCCESS, client.nickString, "Authentication successful") return nil }) if err != nil { @@ -239,7 +256,6 @@ func regCreateHandler(server *Server, client *Client, msg ircmsg.IrcMessage) boo return false } - client.Notice("Account creation was successful!") return false } diff --git a/irc/server.go b/irc/server.go index 5bc78312..fe54c3b8 100644 --- a/irc/server.go +++ b/irc/server.go @@ -27,7 +27,7 @@ import ( ) type Server struct { - accounts map[string]ClientAccount + accounts map[string]*ClientAccount channels ChannelNameMap clients *ClientLookupSet commands chan Command @@ -67,7 +67,7 @@ type clientConn struct { func NewServer(config *Config) *Server { server := &Server{ - accounts: make(map[string]ClientAccount), + accounts: make(map[string]*ClientAccount), channels: make(ChannelNameMap), clients: NewClientLookupSet(), commands: make(chan Command),