1
Fork 0
mirror of https://github.com/jech/galene.git synced 2024-11-25 01:55:57 +01:00

Implement kick, op and friends.

This commit is contained in:
Juliusz Chroboczek 2020-04-25 17:36:35 +02:00
parent e0eee9e7e2
commit 25825e5b22
3 changed files with 118 additions and 16 deletions

View file

@ -740,6 +740,13 @@ func clientLoop(c *client, conn *websocket.Conn) error {
} }
} }
case sendPermissionsAction:
c.write(clientMessage{
Type: "permissions",
Permissions: c.permissions,
})
case kickAction:
return userError("you have been kicked")
default: default:
log.Printf("unexpected action %T", a) log.Printf("unexpected action %T", a)
return errors.New("unexpected action") return errors.New("unexpected action")
@ -754,7 +761,7 @@ func handleClientMessage(c *client, m clientMessage) error {
switch m.Type { switch m.Type {
case "offer": case "offer":
if !c.permissions.Present { if !c.permissions.Present {
return userError("not authorized") return userError("not authorised")
} }
if m.Offer == nil { if m.Offer == nil {
return protocolError("null offer") return protocolError("null offer")
@ -786,6 +793,24 @@ func handleClientMessage(c *client, m clientMessage) error {
for _, cc := range clients { for _, cc := range clients {
cc.write(m) cc.write(m)
} }
case "op", "unop", "present", "unpresent":
if !c.permissions.Admin {
c.error(userError("not authorised"))
return nil
}
err := setPermission(c.group, m.Id, m.Type)
if err != nil {
return c.error(err)
}
case "kick":
if !c.permissions.Admin {
c.error(userError("not authorised"))
return nil
}
err := kickClient(c.group, m.Id)
if err != nil {
return c.error(err)
}
default: default:
log.Printf("unexpected message: %v", m.Type) log.Printf("unexpected message: %v", m.Type)
return protocolError("unexpected message") return protocolError("unexpected message")

View file

@ -10,8 +10,8 @@ import (
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"sync"
"strings" "strings"
"sync"
"time" "time"
"github.com/pion/webrtc/v2" "github.com/pion/webrtc/v2"
@ -84,6 +84,10 @@ type pushTracksAction struct {
c *client c *client
} }
type sendPermissionsAction struct{}
type kickAction struct{}
var groups struct { var groups struct {
mu sync.Mutex mu sync.Mutex
groups map[string]*group groups map[string]*group
@ -117,7 +121,7 @@ func addGroup(name string, desc *groupDescription) (*group, error) {
g := groups.groups[name] g := groups.groups[name]
if g == nil { if g == nil {
if(desc == nil) { if desc == nil {
desc, err = getDescription(name) desc, err = getDescription(name)
if err != nil { if err != nil {
return nil, err return nil, err
@ -235,6 +239,15 @@ func (g *group) getClients(except *client) []*client {
return clients return clients
} }
func (g *group) getClientUnlocked(id string) *client {
for _, c := range g.clients {
if c.id == id {
return c
}
}
return nil
}
func (g *group) Range(f func(c *client) bool) { func (g *group) Range(f func(c *client) bool) {
g.mu.Lock() g.mu.Lock()
defer g.mu.Unlock() defer g.mu.Unlock()
@ -295,7 +308,7 @@ type groupUser struct {
func matchUser(user, pass string, users []groupUser) (bool, bool) { func matchUser(user, pass string, users []groupUser) (bool, bool) {
for _, u := range users { for _, u := range users {
if (u.Username == "" || u.Username == user) { if u.Username == "" || u.Username == user {
return true, (u.Password == "" || u.Password == pass) return true, (u.Password == "" || u.Password == pass)
} }
} }
@ -372,22 +385,58 @@ func getPermission(desc *groupDescription, user, pass string) (userPermission, e
p.Present = true p.Present = true
return p, nil return p, nil
} }
return p, userError("not authorized") return p, userError("not authorised")
} }
if found, good := matchUser(user, pass, desc.Presenter); found { if found, good := matchUser(user, pass, desc.Presenter); found {
if good { if good {
p.Present = true p.Present = true
return p, nil return p, nil
} }
return p, userError("not authorized") return p, userError("not authorised")
} }
if found, good := matchUser(user, pass, desc.Other); found { if found, good := matchUser(user, pass, desc.Other); found {
if good { if good {
return p, nil return p, nil
} }
return p, userError("not authorized") return p, userError("not authorised")
} }
return p, userError("not authorized") return p, userError("not authorised")
}
func setPermission(g *group, id string, perm string) error {
g.mu.Lock()
defer g.mu.Unlock()
c := g.getClientUnlocked(id)
if c == nil {
return userError("no such user")
}
switch perm {
case "op":
c.permissions.Admin = true
case "unop":
c.permissions.Admin = false
case "present":
c.permissions.Present = true
case "unpresent":
c.permissions.Present = false
default:
return userError("unknown permission")
}
return c.action(sendPermissionsAction{})
}
func kickClient(g *group, id string) error {
g.mu.Lock()
defer g.mu.Unlock()
c := g.getClientUnlocked(id)
if c == nil {
return userError("no such user")
}
return c.action(kickAction{})
} }
type publicGroup struct { type publicGroup struct {

View file

@ -15,6 +15,8 @@ let up = {}, down = {};
let iceServers = []; let iceServers = [];
let permissions = {};
function toHex(array) { function toHex(array) {
let a = new Uint8Array(array); let a = new Uint8Array(array);
let s = ''; let s = '';
@ -515,9 +517,10 @@ function gotUser(id, name, del) {
addUser(id, name); addUser(id, name);
} }
function gotPermissions(permissions) { function gotPermissions(perm) {
document.getElementById('presenterbox').disabled = !permissions.present; permissions = perm;
document.getElementById('sharebox').disabled = !permissions.present; document.getElementById('presenterbox').disabled = !perm.present;
document.getElementById('sharebox').disabled = !perm.present;
} }
const urlRegexp = /https?:\/\/[-a-zA-Z0-9@:%/._\+~#=?]+[-a-zA-Z0-9@:%/_\+~#=]/g; const urlRegexp = /https?:\/\/[-a-zA-Z0-9@:%/._\+~#=?]+[-a-zA-Z0-9@:%/_\+~#=]/g;
@ -634,14 +637,39 @@ function handleInput() {
} }
switch(cmd) { switch(cmd) {
case '/nick':
setNick(rest);
storeNick(rest);
return;
case '/me': case '/me':
message = rest; message = rest;
me = true; me = true;
break; break;
case '/op':
case '/unop':
case '/kick':
case '/present':
case '/unpresent':
if(!permissions.admin) {
displayError("You're not an administrator");
return;
}
let id;
if(id in users) {
id = rest;
} else {
for(let i in users) {
if(users[i] === rest) {
id = i;
break;
}
}
}
if(!id) {
displayError('Unknown user ' + rest);
return;
}
send({
type: cmd.slice(1),
id: id,
});
return;
default: default:
displayError('Uknown command ' + cmd); displayError('Uknown command ' + cmd);
return; return;