mirror of
https://github.com/mumble-voip/grumble.git
synced 2025-12-20 06:10:00 -08:00
Registration support.
This commit is contained in:
parent
95509f9138
commit
28a74743a6
4 changed files with 130 additions and 17 deletions
|
|
@ -60,6 +60,7 @@ type Client struct {
|
||||||
Username string
|
Username string
|
||||||
Session uint32
|
Session uint32
|
||||||
CertHash string
|
CertHash string
|
||||||
|
Email string
|
||||||
Tokens []string
|
Tokens []string
|
||||||
Channel *Channel
|
Channel *Channel
|
||||||
SelfMute bool
|
SelfMute bool
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,9 @@ func NewServerFromFrozen(filename string) (s *Server, err os.Error) {
|
||||||
u.LastActive = fu.LastActive
|
u.LastActive = fu.LastActive
|
||||||
|
|
||||||
s.Users[u.Id] = u
|
s.Users[u.Id] = u
|
||||||
|
if u.Id > s.nextUserId {
|
||||||
|
s.nextUserId = u.Id + 1
|
||||||
|
}
|
||||||
s.UserNameMap[u.Name] = u
|
s.UserNameMap[u.Name] = u
|
||||||
if len(u.CertHash) > 0 {
|
if len(u.CertHash) > 0 {
|
||||||
s.UserCertMap[u.CertHash] = u
|
s.UserCertMap[u.CertHash] = u
|
||||||
|
|
|
||||||
83
message.go
83
message.go
|
|
@ -601,21 +601,19 @@ func (server *Server) handleUserStateMessage(client *Client, msg *Message) {
|
||||||
if userstate.UserId != nil {
|
if userstate.UserId != nil {
|
||||||
// If user == actor, check for SelfRegisterPermission on root channel.
|
// If user == actor, check for SelfRegisterPermission on root channel.
|
||||||
// If user != actor, check for RegisterPermission permission on root channel.
|
// If user != actor, check for RegisterPermission permission on root channel.
|
||||||
permCheck := Permission(NonePermission)
|
perm := Permission(RegisterPermission)
|
||||||
uid := *userstate.UserId
|
if actor == target {
|
||||||
if target == actor {
|
perm = Permission(SelfRegisterPermission)
|
||||||
permCheck = SelfRegisterPermission
|
|
||||||
} else {
|
|
||||||
permCheck = RegisterPermission
|
|
||||||
}
|
}
|
||||||
if uid >= 0 || !server.HasPermission(actor, server.root, SelfRegisterPermission) {
|
|
||||||
client.sendPermissionDenied(actor, server.root, permCheck)
|
if target.IsRegistered() || !server.HasPermission(actor, server.root, perm) {
|
||||||
|
client.sendPermissionDenied(actor, server.root, perm)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can't register a user with an empty hash.
|
|
||||||
if len(target.CertHash) == 0 {
|
if len(target.CertHash) == 0 {
|
||||||
client.sendPermissionDeniedTypeUser("MissingCertificate", target)
|
client.sendPermissionDeniedTypeUser("MissingCertificate", target)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -733,11 +731,18 @@ func (server *Server) handleUserStateMessage(client *Client, msg *Message) {
|
||||||
broadcast = true
|
broadcast = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userRegistrationChanged := false
|
||||||
if userstate.UserId != nil {
|
if userstate.UserId != nil {
|
||||||
// fixme(mkrautz): Registration is currently unhandled.
|
uid := server.RegisterClient(client)
|
||||||
log.Printf("handleUserState: (Self)Register not implemented yet!")
|
if uid > 0 {
|
||||||
|
userstate.UserId = proto.Uint32(uid)
|
||||||
|
client.user = server.Users[uid]
|
||||||
|
userRegistrationChanged = true
|
||||||
|
} else {
|
||||||
userstate.UserId = nil
|
userstate.UserId = nil
|
||||||
}
|
}
|
||||||
|
broadcast = true
|
||||||
|
}
|
||||||
|
|
||||||
if userstate.ChannelId != nil {
|
if userstate.ChannelId != nil {
|
||||||
channel, ok := server.Channels[int(*userstate.ChannelId)]
|
channel, ok := server.Channels[int(*userstate.ChannelId)]
|
||||||
|
|
@ -799,6 +804,10 @@ func (server *Server) handleUserStateMessage(client *Client, msg *Message) {
|
||||||
userstate.CommentHash = nil
|
userstate.CommentHash = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if userRegistrationChanged {
|
||||||
|
server.ClearACLCache()
|
||||||
|
}
|
||||||
|
|
||||||
err := server.broadcastProtoMessageWithPredicate(MessageUserState, userstate, func(client *Client) bool {
|
err := server.broadcastProtoMessageWithPredicate(MessageUserState, userstate, func(client *Client) bool {
|
||||||
return client.Version >= 0x10203
|
return client.Version >= 0x10203
|
||||||
})
|
})
|
||||||
|
|
@ -1198,3 +1207,55 @@ func (server *Server) handleRequestBlob(client *Client, msg *Message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// User list query, user rename, user de-register
|
||||||
|
func (server *Server) handleUserList(client *Client, msg *Message) {
|
||||||
|
userlist := &mumbleproto.UserList{}
|
||||||
|
err := proto.Unmarshal(msg.buf, userlist)
|
||||||
|
if err != nil {
|
||||||
|
client.Panic(err.String())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only users who are allowed to register other users can access the user list.
|
||||||
|
if !server.HasPermission(client, server.root, RegisterPermission) {
|
||||||
|
client.sendPermissionDenied(client, server.root, RegisterPermission)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query user list
|
||||||
|
if len(userlist.Users) == 0 {
|
||||||
|
for uid, user := range server.Users {
|
||||||
|
if uid == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
userlist.Users = append(userlist.Users, &mumbleproto.UserList_User{
|
||||||
|
UserId: proto.Uint32(uid),
|
||||||
|
Name: proto.String(user.Name),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err := client.sendProtoMessage(MessageUserList, userlist); err != nil {
|
||||||
|
client.Panic(err.String())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Rename, registration removal
|
||||||
|
} else {
|
||||||
|
for _, listUser := range userlist.Users {
|
||||||
|
uid := *listUser.UserId
|
||||||
|
if uid == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// De-register a user
|
||||||
|
if listUser.Name == nil {
|
||||||
|
server.RemoveRegistration(uid)
|
||||||
|
// Rename user
|
||||||
|
} else {
|
||||||
|
// todo(mkrautz): Validate name.
|
||||||
|
user, ok := server.Users[uid]
|
||||||
|
if ok {
|
||||||
|
user.Name = *listUser.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
58
server.go
58
server.go
|
|
@ -84,6 +84,7 @@ type Server struct {
|
||||||
Users map[uint32]*User
|
Users map[uint32]*User
|
||||||
UserCertMap map[string]*User
|
UserCertMap map[string]*User
|
||||||
UserNameMap map[string]*User
|
UserNameMap map[string]*User
|
||||||
|
nextUserId uint32
|
||||||
|
|
||||||
// ACL cache
|
// ACL cache
|
||||||
aclcache ACLCache
|
aclcache ACLCache
|
||||||
|
|
@ -537,6 +538,11 @@ func (server *Server) finishAuthenticate(client *Client) {
|
||||||
Name: proto.String(client.ShownName()),
|
Name: proto.String(client.ShownName()),
|
||||||
ChannelId: proto.Uint32(0),
|
ChannelId: proto.Uint32(0),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(client.CertHash) > 0 {
|
||||||
|
userstate.Hash = proto.String(client.CertHash)
|
||||||
|
}
|
||||||
|
|
||||||
if client.IsRegistered() {
|
if client.IsRegistered() {
|
||||||
userstate.UserId = proto.Uint32(uint32(client.UserId()))
|
userstate.UserId = proto.Uint32(uint32(client.UserId()))
|
||||||
|
|
||||||
|
|
@ -681,6 +687,10 @@ func (server *Server) sendUserList(client *Client) {
|
||||||
ChannelId: proto.Uint32(uint32(connectedClient.Channel.Id)),
|
ChannelId: proto.Uint32(uint32(connectedClient.Channel.Id)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(connectedClient.CertHash) > 0 {
|
||||||
|
userstate.Hash = connectedClient.CertHash
|
||||||
|
}
|
||||||
|
|
||||||
if connectedClient.IsRegistered() {
|
if connectedClient.IsRegistered() {
|
||||||
userstate.UserId = proto.Uint32(uint32(connectedClient.UserId()))
|
userstate.UserId = proto.Uint32(uint32(connectedClient.UserId()))
|
||||||
|
|
||||||
|
|
@ -709,10 +719,6 @@ func (server *Server) sendUserList(client *Client) {
|
||||||
userstate.Comment = proto.String(string(buf))
|
userstate.Comment = proto.String(string(buf))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(connectedClient.user.CertHash) > 0 {
|
|
||||||
userstate.Hash = proto.String(connectedClient.user.CertHash)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if connectedClient.Mute {
|
if connectedClient.Mute {
|
||||||
|
|
@ -820,7 +826,7 @@ func (server *Server) handleIncomingMessage(client *Client, msg *Message) {
|
||||||
case MessageContextAction:
|
case MessageContextAction:
|
||||||
log.Printf("MessageContextAction from client")
|
log.Printf("MessageContextAction from client")
|
||||||
case MessageUserList:
|
case MessageUserList:
|
||||||
log.Printf("MessageUserList from client")
|
server.handleUserList(msg.client, msg)
|
||||||
case MessageVoiceTarget:
|
case MessageVoiceTarget:
|
||||||
log.Printf("MessageVoiceTarget from client")
|
log.Printf("MessageVoiceTarget from client")
|
||||||
case MessagePermissionQuery:
|
case MessagePermissionQuery:
|
||||||
|
|
@ -1003,6 +1009,48 @@ func (s *Server) FreezeServer() io.ReadCloser {
|
||||||
return fr.readCloser
|
return fr.readCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register a client on the server.
|
||||||
|
func (s *Server) RegisterClient(client *Client) (uid uint32) {
|
||||||
|
// Increment nextUserId only if registration succeeded.
|
||||||
|
defer func() {
|
||||||
|
if uid > 0 {
|
||||||
|
s.nextUserId += 1
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
user, err := NewUser(s.nextUserId, client.Username)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grumble can only register users with certificates.
|
||||||
|
if len(client.CertHash) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
user.Email = client.Email
|
||||||
|
user.CertHash = client.CertHash
|
||||||
|
|
||||||
|
uid = s.nextUserId
|
||||||
|
s.Users[uid] = user
|
||||||
|
s.UserCertMap[client.CertHash] = user
|
||||||
|
s.UserNameMap[client.Username] = user
|
||||||
|
return uid
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a registered user.
|
||||||
|
func (s *Server) RemoveRegistration(uid uint32) (err os.Error) {
|
||||||
|
user, ok := s.Users[uid]
|
||||||
|
if !ok {
|
||||||
|
return os.NewError("Unknown user ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Users[uid] = nil, false
|
||||||
|
s.UserCertMap[user.CertHash] = nil, false
|
||||||
|
s.UserNameMap[user.Name] = nil, false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// The accept loop of the server.
|
// The accept loop of the server.
|
||||||
func (s *Server) ListenAndMurmur() {
|
func (s *Server) ListenAndMurmur() {
|
||||||
// Launch the event handler goroutine
|
// Launch the event handler goroutine
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue