diff --git a/irc/client.go b/irc/client.go index 5cf9a476..4e076b54 100644 --- a/irc/client.go +++ b/irc/client.go @@ -227,6 +227,10 @@ func (client *Client) Friends() ClientSet { } func (client *Client) SetNickname(nickname Name) { + if client.HasNick() { + Log.error.Printf("%s nickname already set!", client) + return + } client.nick = nickname client.server.clients.Add(client) } diff --git a/irc/commands.go b/irc/commands.go index 7601969b..6c2e053a 100644 --- a/irc/commands.go +++ b/irc/commands.go @@ -40,6 +40,7 @@ var ( NAMES: NewNamesCommand, NICK: NewNickCommand, NOTICE: NewNoticeCommand, + ONICK: NewOperNickCommand, OPER: NewOperCommand, PART: NewPartCommand, PASS: NewPassCommand, @@ -228,15 +229,6 @@ func NewPassCommand(args []string) (Command, error) { // NICK -type NickCommand struct { - BaseCommand - nickname Name -} - -func (m *NickCommand) String() string { - return fmt.Sprintf("NICK(nickname=%s)", m.nickname) -} - func NewNickCommand(args []string) (Command, error) { if len(args) != 1 { return nil, NotEnoughArgsError @@ -1006,3 +998,14 @@ func NewWhoWasCommand(args []string) (Command, error) { } return cmd, nil } + +func NewOperNickCommand(args []string) (Command, error) { + if len(args) < 2 { + return nil, NotEnoughArgsError + } + + return &OperNickCommand{ + target: NewName(args[0]), + nick: NewName(args[1]), + }, nil +} diff --git a/irc/constants.go b/irc/constants.go index d9426cb8..0fc6b0d1 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -21,6 +21,7 @@ const ( NAMES StringCode = "NAMES" NICK StringCode = "NICK" NOTICE StringCode = "NOTICE" + ONICK StringCode = "ONICK" OPER StringCode = "OPER" PART StringCode = "PART" PASS StringCode = "PASS" diff --git a/irc/nickname.go b/irc/nickname.go new file mode 100644 index 00000000..00a27c17 --- /dev/null +++ b/irc/nickname.go @@ -0,0 +1,99 @@ +package irc + +import ( + "fmt" +) + +type NickCommand struct { + BaseCommand + nickname Name +} + +func (m *NickCommand) String() string { + return fmt.Sprintf("NICK(nickname=%s)", m.nickname) +} + +func (m *NickCommand) HandleRegServer(s *Server) { + client := m.Client() + if !client.authorized { + client.ErrPasswdMismatch() + client.Quit("bad password") + return + } + + if client.capState == CapNegotiating { + client.capState = CapNegotiated + } + + if m.nickname == "" { + client.ErrNoNicknameGiven() + return + } + + if s.clients.Get(m.nickname) != nil { + client.ErrNickNameInUse(m.nickname) + return + } + + if !m.nickname.IsNickname() { + client.ErrErroneusNickname(m.nickname) + return + } + + client.SetNickname(m.nickname) + s.tryRegister(client) +} + +func (msg *NickCommand) HandleServer(server *Server) { + client := msg.Client() + + if msg.nickname == "" { + client.ErrNoNicknameGiven() + return + } + + if !msg.nickname.IsNickname() { + client.ErrErroneusNickname(msg.nickname) + return + } + + if msg.nickname == client.nick { + return + } + + target := server.clients.Get(msg.nickname) + if (target != nil) && (target != client) { + client.ErrNickNameInUse(msg.nickname) + return + } + + client.ChangeNickname(msg.nickname) +} + +type OperNickCommand struct { + BaseCommand + target Name + nick Name +} + +func (msg *OperNickCommand) HandleServer(server *Server) { + client := msg.Client() + + if !client.flags[Operator] { + client.ErrNoPrivileges() + return + } + + if !msg.nick.IsNickname() { + client.ErrErroneusNickname(msg.nick) + return + } + + target := server.clients.Get(msg.target) + if target == nil { + client.ErrNoSuchNick(msg.target) + return + } + + target.ChangeNickname(msg.nick) +} diff --git a/irc/server.go b/irc/server.go index c6ccc7c4..927d9b31 100644 --- a/irc/server.go +++ b/irc/server.go @@ -289,37 +289,6 @@ func (msg *ProxyCommand) HandleRegServer(server *Server) { msg.Client().hostname = msg.hostname } -func (m *NickCommand) HandleRegServer(s *Server) { - client := m.Client() - if !client.authorized { - client.ErrPasswdMismatch() - client.Quit("bad password") - return - } - - if client.capState == CapNegotiating { - client.capState = CapNegotiated - } - - if m.nickname == "" { - client.ErrNoNicknameGiven() - return - } - - if s.clients.Get(m.nickname) != nil { - client.ErrNickNameInUse(m.nickname) - return - } - - if !m.nickname.IsNickname() { - client.ErrErroneusNickname(m.nickname) - return - } - - client.SetNickname(m.nickname) - s.tryRegister(client) -} - func (msg *RFC1459UserCommand) HandleRegServer(server *Server) { client := msg.Client() if !client.authorized { @@ -380,32 +349,6 @@ func (m *PongCommand) HandleServer(s *Server) { // no-op } -func (msg *NickCommand) HandleServer(server *Server) { - client := msg.Client() - - if msg.nickname == "" { - client.ErrNoNicknameGiven() - return - } - - if !msg.nickname.IsNickname() { - client.ErrErroneusNickname(msg.nickname) - return - } - - if msg.nickname == client.nick { - return - } - - target := server.clients.Get(msg.nickname) - if (target != nil) && (target != client) { - client.ErrNickNameInUse(msg.nickname) - return - } - - client.ChangeNickname(msg.nickname) -} - func (m *UserCommand) HandleServer(s *Server) { m.Client().ErrAlreadyRegistered() }