add lock controls for users.

This commit is contained in:
Miroslav Šedivý 2021-11-16 22:50:11 +01:00
parent 2290c4a065
commit 61fcf7f699
20 changed files with 277 additions and 113 deletions

View File

@ -404,7 +404,7 @@
} }
member(id: string) { member(id: string) {
return this.$accessor.user.members[id] return this.$accessor.user.members[id] || { id, displayname: this.$t('somebody') }
} }
timestamp(time: Date) { timestamp(time: Date) {

View File

@ -1,17 +1,17 @@
<template> <template>
<ul> <ul>
<li v-if="!isTouch"> <li v-if="!isTouch && seesControl">
<i <i
:class="[ :class="[
shakeKbd ? 'shake' : '', !disabeld && shakeKbd ? 'shake' : '',
hosted && !hosting ? 'disabled' : '', disabeld && !hosting ? 'disabled' : '',
!hosted && !hosting ? 'faded' : '', !disabeld && !hosting ? 'faded' : '',
'fas', 'fas',
'fa-keyboard', 'fa-keyboard',
'request', 'request',
]" ]"
v-tooltip="{ v-tooltip="{
content: !hosted || hosting ? (hosting ? $t('controls.release') : $t('controls.request')) : '', content: !disabeld || hosting ? (hosting ? $t('controls.release') : $t('controls.request')) : '',
placement: 'top', placement: 'top',
offset: 5, offset: 5,
boundariesElement: 'body', boundariesElement: 'body',
@ -20,7 +20,7 @@
@click.stop.prevent="toggleControl" @click.stop.prevent="toggleControl"
/> />
</li> </li>
<li> <li v-if="seesControl">
<label <label
class="switch" class="switch"
v-tooltip="{ v-tooltip="{
@ -240,7 +240,7 @@
@Component({ name: 'neko-controls' }) @Component({ name: 'neko-controls' })
export default class extends Vue { export default class extends Vue {
@Prop(Boolean) readonly shakeKbd = false @Prop(Boolean) readonly shakeKbd!: boolean
get isTouch() { get isTouch() {
return ( return (
@ -249,7 +249,15 @@
) )
} }
get hosted() { get severLocked(): boolean {
return 'control' in this.$accessor.locked && this.$accessor.locked['control']
}
get seesControl(): boolean {
return !this.severLocked || this.$accessor.user.admin || this.hosting
}
get disabeld() {
return this.$accessor.remote.hosted return this.$accessor.remote.hosted
} }

View File

@ -7,16 +7,23 @@
<ul class="menu"> <ul class="menu">
<li> <li>
<i <i
:class="[{ disabled: !admin }, { 'fa-lock-open': !locked }, { 'fa-lock': locked }, 'fas', 'lock']" :class="[{ disabled: !admin }, { locked: isLocked('control') }, 'fas', 'fa-mouse']"
@click="toggleLock" @click="toggleLock('control')"
v-tooltip="{ v-tooltip="{
content: admin content: lockedTooltip('control'),
? locked placement: 'bottom',
? $t('room.unlock') offset: 5,
: $t('room.lock') boundariesElement: 'body',
: locked delay: { show: 300, hide: 100 },
? $t('room.locked') }"
: $t('room.unlocked'), />
</li>
<li>
<i
:class="[{ disabled: !admin }, { locked: isLocked('login') }, locked ? 'fa-lock' : 'fa-lock-open', 'fas']"
@click="toggleLock('login')"
v-tooltip="{
content: lockedTooltip('login'),
placement: 'bottom', placement: 'bottom',
offset: 5, offset: 5,
boundariesElement: 'body', boundariesElement: 'body',
@ -90,7 +97,7 @@
opacity: 0.8; opacity: 0.8;
} }
.fa-lock { .locked {
color: rgba($color: $style-error, $alpha: 0.5); color: rgba($color: $style-error, $alpha: 0.5);
} }
@ -138,6 +145,7 @@
<script lang="ts"> <script lang="ts">
import { Component, Ref, Watch, Vue } from 'vue-property-decorator' import { Component, Ref, Watch, Vue } from 'vue-property-decorator'
import { AdminLockResource } from '~/neko/messages'
@Component({ name: 'neko-settings' }) @Component({ name: 'neko-settings' })
export default class extends Vue { export default class extends Vue {
@ -167,14 +175,26 @@
this.readTexts = this.texts this.readTexts = this.texts
} }
toggleLock() { toggleLock(resource: AdminLockResource) {
if (this.admin) { if (!this.admin) return
if (this.locked) {
this.$accessor.unlock() if (this.isLocked(resource)) {
this.$accessor.unlock(resource)
} else { } else {
this.$accessor.lock() this.$accessor.lock(resource)
} }
} }
isLocked(resource: AdminLockResource): boolean {
return resource in this.locked && this.locked[resource]
}
lockedTooltip(resource: AdminLockResource) {
if (this.admin) {
return this.$t(`locks.${resource}.` + (this.isLocked(resource) ? `unlock` : `lock`))
}
return this.$t(`locks.${resource}.` + (this.isLocked(resource) ? `locked` : `unlocked`))
} }
} }
</script> </script>

View File

@ -213,7 +213,7 @@
@Ref('resolution') readonly _resolution!: any @Ref('resolution') readonly _resolution!: any
@Ref('clipboard') readonly _clipboard!: any @Ref('clipboard') readonly _clipboard!: any
@Prop(Boolean) readonly hideControls = false @Prop(Boolean) readonly hideControls!: boolean
private keyboard = GuacamoleKeyboard() private keyboard = GuacamoleKeyboard()
private observer = new ResizeObserver(this.onResise.bind(this)) private observer = new ResizeObserver(this.onResise.bind(this))

View File

@ -2,6 +2,7 @@ export const logout = 'log out'
export const unsupported = 'this web-browser does not support WebRTC' export const unsupported = 'this web-browser does not support WebRTC'
export const admin_loggedin = 'You are logged in as an admin' export const admin_loggedin = 'You are logged in as an admin'
export const you = 'You' export const you = 'You'
export const somebody = 'Somebody'
export const send_a_message = 'Send a message' export const send_a_message = 'Send a message'
export const side = { export const side = {
@ -50,11 +51,23 @@ export const controls = {
unlock: 'Unlock Controls', unlock: 'Unlock Controls',
} }
export const room = { export const locks = {
control: {
lock: 'Lock Controls (for users)',
unlock: 'Unlock Controls (for users)',
locked: 'Controls Locked (for users)',
unlocked: 'Controls Unlocked (for users)',
notif_locked: 'locked controls for users',
notif_unlocked: 'unlocked controls for users',
},
login: {
lock: 'Lock Room (for users)', lock: 'Lock Room (for users)',
unlock: 'Unlock Room (for users)', unlock: 'Unlock Room (for users)',
locked: 'Room Locked (for users)', locked: 'Room Locked (for users)',
unlocked: 'Room Unlocked (for users)', unlocked: 'Room Unlocked (for users)',
notif_locked: 'locked the room',
notif_unlocked: 'unlocked the room',
},
} }
export const setting = { export const setting = {
@ -94,6 +107,4 @@ export const notifications = {
kicked: 'kicked {name}', kicked: 'kicked {name}',
muted: 'muted {name}', muted: 'muted {name}',
unmuted: 'unmuted {name}', unmuted: 'unmuted {name}',
room_locked: 'locked the room',
room_unlocked: 'unlocked the room',
} }

View File

@ -2,6 +2,8 @@ export const logout = 'salir'
export const unsupported = 'este navegador no soporta webrtc' export const unsupported = 'este navegador no soporta webrtc'
export const admin_loggedin = 'Registrado como admin' export const admin_loggedin = 'Registrado como admin'
export const you = 'Tú' export const you = 'Tú'
// TODO
//export const somebody = 'Somebody'
export const send_a_message = 'Enviar un mensaje' export const send_a_message = 'Enviar un mensaje'
export const side = { export const side = {
@ -51,11 +53,24 @@ export const controls = {
unlock: 'Controles desbloqueados', unlock: 'Controles desbloqueados',
} }
export const room = { export const locks = {
// TODO
//control: {
// lock: 'Lock Controls (for users)',
// unlock: 'Unlock Controls (for users)',
// locked: 'Controls Locked (for users)',
// unlocked: 'Controls Unlocked (for users)',
// notif_locked: 'locked controls for users',
// notif_unlocked: 'unlocked controls for users',
//},
login: {
lock: 'Bloquear sala (para usuarios)', lock: 'Bloquear sala (para usuarios)',
unlock: 'Desbloquear sala (para usuarios)', unlock: 'Desbloquear sala (para usuarios)',
locked: 'Sala bloqueada (para usuarios)', locked: 'Sala bloqueada (para usuarios)',
unlocked: 'Sala desbloqueada (para usuarios)', unlocked: 'Sala desbloqueada (para usuarios)',
notif_locked: 'bloqueó la sala',
notif_unlocked: 'desbloqueó la sala',
},
} }
export const setting = { export const setting = {
@ -98,6 +113,4 @@ export const notifications = {
kicked: '{name} expulsado', kicked: '{name} expulsado',
muted: '{name} silenciado', muted: '{name} silenciado',
unmuted: '{name} no silenciado', unmuted: '{name} no silenciado',
room_locked: 'bloqueó la sala',
room_unlocked: 'desbloqueó la sala',
} }

View File

@ -2,6 +2,8 @@ export const logout = 'Se déconnecter'
export const unsupported = 'ce navigateur ne prend pas en charge WebRTC' export const unsupported = 'ce navigateur ne prend pas en charge WebRTC'
export const admin_loggedin = "Vous êtes connecté en tant qu'admin" export const admin_loggedin = "Vous êtes connecté en tant qu'admin"
export const you = 'Vous' export const you = 'Vous'
// TODO
//export const somebody = 'Somebody'
export const send_a_message = 'Envoyer un message' export const send_a_message = 'Envoyer un message'
export const side = { export const side = {
@ -44,11 +46,24 @@ export const context = {
}, },
} }
export const controls = { export const locks = {
// TODO
//control: {
// lock: 'Lock Controls (for users)',
// unlock: 'Unlock Controls (for users)',
// locked: 'Controls Locked (for users)',
// unlocked: 'Controls Unlocked (for users)',
// notif_locked: 'locked controls for users',
// notif_unlocked: 'unlocked controls for users',
//},
login: {
release: 'Relacher le contrôle', release: 'Relacher le contrôle',
request: 'Demander le contrôle', request: 'Demander le contrôle',
lock: 'Vérouiller le contrôle', lock: 'Vérouiller le contrôle',
unlock: 'Débloquer le contrôle', unlock: 'Débloquer le contrôle',
notif_locked: 'a vérouillé la salle',
notif_unlocked: 'a dévérouillé la salle',
},
} }
export const room = { export const room = {
@ -98,6 +113,4 @@ export const notifications = {
kicked: 'a kick {name}', kicked: 'a kick {name}',
muted: 'a mute {name}', muted: 'a mute {name}',
unmuted: 'a démute {name}', unmuted: 'a démute {name}',
room_locked: 'a vérouillé la salle',
room_unlocked: 'a dévérouillé la salle',
} }

View File

@ -2,6 +2,8 @@ export const logout = 'logg ut'
export const unsupported = 'Denne nettleseren støtter ikke WebRTC' export const unsupported = 'Denne nettleseren støtter ikke WebRTC'
export const admin_loggedin = 'Du er innlogget som administrator' export const admin_loggedin = 'Du er innlogget som administrator'
export const you = 'Deg' export const you = 'Deg'
// TODO
//export const somebody = 'Somebody'
export const send_a_message = 'Send en melding' export const send_a_message = 'Send en melding'
export const side = { export const side = {
@ -51,11 +53,24 @@ export const controls = {
unlock: 'Lås opp kontrollen', unlock: 'Lås opp kontrollen',
} }
export const room = { export const locks = {
// TODO
//control: {
// lock: 'Lock Controls (for users)',
// unlock: 'Unlock Controls (for users)',
// locked: 'Controls Locked (for users)',
// unlocked: 'Controls Unlocked (for users)',
// notif_locked: 'locked controls for users',
// notif_unlocked: 'unlocked controls for users',
//},
login: {
lock: 'Lås rommet (for brukere)', lock: 'Lås rommet (for brukere)',
unlock: 'Lås opp rommet (for brukere)', unlock: 'Lås opp rommet (for brukere)',
locked: 'Rom låst (for brukere)', locked: 'Rom låst (for brukere)',
unlocked: 'Rom opplåst (for brukere)', unlocked: 'Rom opplåst (for brukere)',
notif_locked: 'låste rommet',
notif_unlocked: 'låste opp rommet',
},
} }
export const setting = { export const setting = {
@ -98,6 +113,4 @@ export const notifications = {
kicked: 'kastet ut {name}', kicked: 'kastet ut {name}',
muted: 'forstummet {name}', muted: 'forstummet {name}',
unmuted: 'opphevet forstummingen av {name}', unmuted: 'opphevet forstummingen av {name}',
room_locked: 'låste rommet',
room_unlocked: 'låste opp rommet',
} }

View File

@ -2,6 +2,8 @@ export const logout = 'odhlásiť sa'
export const unsupported = 'tento prehliadač nepodporuje webrtc' export const unsupported = 'tento prehliadač nepodporuje webrtc'
export const admin_loggedin = 'Ste prihlásení/á ako administrátor' export const admin_loggedin = 'Ste prihlásení/á ako administrátor'
// export const you = '' // Incorrect in some translations! Cannot be used! // export const you = '' // Incorrect in some translations! Cannot be used!
// TODO
//export const somebody = 'Somebody'
export const send_a_message = 'Odoslať správu' export const send_a_message = 'Odoslať správu'
export const side = { export const side = {
@ -51,11 +53,23 @@ export const controls = {
unlock: 'Odomknúť ovládanie', unlock: 'Odomknúť ovládanie',
} }
export const room = { export const locks = {
control: {
lock: 'Zakázať ovládanie (pre používateľov)',
unlock: 'Povoliť ovládanie (pre používateľov)',
locked: 'Ovládanie je zakázané (pre používateľov)',
unlocked: 'Ovládanie je povolené (pre používateľov)',
notif_locked: 'zakázal/a ovládanie pre používateľov',
notif_unlocked: 'povolil/a ovládanie pre používateľov',
},
login: {
lock: 'Zamknúť miestnosť (pre používateľov)', lock: 'Zamknúť miestnosť (pre používateľov)',
unlock: 'Odomknúť miestnosť (pre používateľov)', unlock: 'Odomknúť miestnosť (pre používateľov)',
locked: 'Miestnosť je zamknutá (pre používateľov)', locked: 'Miestnosť je zamknutá (pre používateľov)',
unlocked: 'Miestnosť odomknutá (pre používateľov)', unlocked: 'Miestnosť odomknutá (pre používateľov)',
notif_locked: 'miestnosť bola zamknutá',
notif_unlocked: 'miestnosť bola odomknutá',
},
} }
export const setting = { export const setting = {
@ -95,6 +109,4 @@ export const notifications = {
kicked: '{name} bol/a vykopnutý/a', kicked: '{name} bol/a vykopnutý/a',
muted: 'zakázal chat používateľovi {name}', muted: 'zakázal chat používateľovi {name}',
unmuted: 'povolil chat používateľovi {name}', unmuted: 'povolil chat používateľovi {name}',
room_locked: 'miestnosť bola zamknutá',
room_unlocked: 'miestnosť bola odomknutá',
} }

View File

@ -2,6 +2,8 @@ export const logout = 'logga ut'
export const unsupported = 'denna webbläsare har inte stöd för webrtc' export const unsupported = 'denna webbläsare har inte stöd för webrtc'
export const admin_loggedin = 'Du är inloggad som en administratör' export const admin_loggedin = 'Du är inloggad som en administratör'
export const you = 'Du' export const you = 'Du'
// TODO
//export const somebody = 'Somebody'
export const send_a_message = 'Skicka ett meddelande' export const send_a_message = 'Skicka ett meddelande'
export const side = { export const side = {
@ -51,11 +53,24 @@ export const controls = {
unlock: 'Lås upp kontrollen', unlock: 'Lås upp kontrollen',
} }
export const room = { export const locks = {
// TODO
//control: {
// lock: 'Lock Controls (for users)',
// unlock: 'Unlock Controls (for users)',
// locked: 'Controls Locked (for users)',
// unlocked: 'Controls Unlocked (for users)',
// notif_locked: 'locked controls for users',
// notif_unlocked: 'unlocked controls for users',
//},
login: {
lock: 'Lås rum (för användare)', lock: 'Lås rum (för användare)',
unlock: 'Lås upp rummet (för användare)', unlock: 'Lås upp rummet (för användare)',
locked: 'Rum låst (för användare)', locked: 'Rum låst (för användare)',
unlocked: 'Rum upplåst (för användare)', unlocked: 'Rum upplåst (för användare)',
notif_locked: 'låste rummet',
notif_unlocked: 'låste upp rummet',
},
} }
export const setting = { export const setting = {
@ -98,6 +113,4 @@ export const notifications = {
kicked: 'sparkade {name}', kicked: 'sparkade {name}',
muted: 'tystade {name}', muted: 'tystade {name}',
unmuted: 'tog bort tystningen på {name}', unmuted: 'tog bort tystningen på {name}',
room_locked: 'låste rummet',
room_unlocked: 'låste upp rummet',
} }

View File

@ -21,6 +21,7 @@ import {
BroadcastStatusPayload, BroadcastStatusPayload,
AdminPayload, AdminPayload,
AdminTargetPayload, AdminTargetPayload,
AdminLockMessage,
} from './messages' } from './messages'
interface NekoEvents extends BaseEvents {} interface NekoEvents extends BaseEvents {}
@ -461,21 +462,23 @@ export class NekoClient extends BaseClient implements EventEmitter<NekoEvents> {
}) })
} }
protected [EVENT.ADMIN.LOCK]({ id }: AdminPayload) { protected [EVENT.ADMIN.LOCK]({ id, resource }: AdminLockMessage) {
this.$accessor.setLocked(true) this.$accessor.setLocked(resource)
this.$accessor.chat.newMessage({ this.$accessor.chat.newMessage({
id, id,
content: this.$vue.$t('notifications.room_locked') as string, content: this.$vue.$t(`locks.${resource}.notif_locked`) as string,
type: 'event', type: 'event',
created: new Date(), created: new Date(),
}) })
} }
protected [EVENT.ADMIN.UNLOCK]({ id }: AdminPayload) { protected [EVENT.ADMIN.UNLOCK]({ id, resource }: AdminLockMessage) {
this.$accessor.setLocked(false) this.$accessor.setUnlocked(resource)
this.$accessor.chat.newMessage({ this.$accessor.chat.newMessage({
id, id,
content: this.$vue.$t('notifications.room_unlocked') as string, content: this.$vue.$t(`locks.${resource}.notif_unlocked`) as string,
type: 'event', type: 'event',
created: new Date(), created: new Date(),
}) })

View File

@ -39,6 +39,7 @@ export type WebSocketPayloads =
| ScreenResolutionPayload | ScreenResolutionPayload
| ScreenConfigurationsPayload | ScreenConfigurationsPayload
| AdminPayload | AdminPayload
| AdminLockPayload
| BroadcastStatusPayload | BroadcastStatusPayload
| BroadcastCreatePayload | BroadcastCreatePayload
@ -222,3 +223,14 @@ export interface AdminTargetPayload {
id: string id: string
target?: string target?: string
} }
export interface AdminLockMessage extends WebSocketMessage, AdminLockPayload {
event: AdminEvents
id: string
}
export type AdminLockResource = 'login' | 'control'
export interface AdminLockPayload {
resource: AdminLockResource
}

View File

@ -2,6 +2,7 @@ import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import { useAccessor, mutationTree, actionTree } from 'typed-vuex' import { useAccessor, mutationTree, actionTree } from 'typed-vuex'
import { EVENT } from '~/neko/events' import { EVENT } from '~/neko/events'
import { AdminLockResource } from '~/neko/messages'
import { get, set } from '~/utils/localstorage' import { get, set } from '~/utils/localstorage'
import * as video from './video' import * as video from './video'
@ -18,7 +19,7 @@ export const state = () => ({
active: false, active: false,
connecting: false, connecting: false,
connected: false, connected: false,
locked: false, locked: {} as Record<string, boolean>,
}) })
export const mutations = mutationTree(state, { export const mutations = mutationTree(state, {
@ -31,8 +32,12 @@ export const mutations = mutationTree(state, {
state.password = password state.password = password
}, },
setLocked(state, locked: boolean) { setLocked(state, resource: string) {
state.locked = locked Vue.set(state.locked, resource, true)
},
setUnlocked(state, resource: string) {
Vue.set(state.locked, resource, false)
}, },
setConnnecting(state) { setConnnecting(state) {
@ -58,20 +63,20 @@ export const actions = actionTree(
accessor.settings.initialise() accessor.settings.initialise()
}, },
lock() { lock(_, resource: AdminLockResource) {
if (!accessor.connected || !accessor.user.admin) { if (!accessor.connected || !accessor.user.admin) {
return return
} }
$client.sendMessage(EVENT.ADMIN.LOCK) $client.sendMessage(EVENT.ADMIN.LOCK, { resource })
}, },
unlock() { unlock(_, resource: AdminLockResource) {
if (!accessor.connected || !accessor.user.admin) { if (!accessor.connected || !accessor.user.admin) {
return return
} }
$client.sendMessage(EVENT.ADMIN.UNLOCK) $client.sendMessage(EVENT.ADMIN.UNLOCK, { resource })
}, },
login({ state }, { displayname, password }: { displayname: string; password: string }) { login({ state }, { displayname, password }: { displayname: string; password: string }) {

View File

@ -2,6 +2,9 @@
## master branch ## master branch
### New Features
- Lock controls for users, globally.
### Misc ### Misc
- ARM-based images not bound to Raspberry Pi only. - ARM-based images not bound to Raspberry Pi only.
- Add japanese characters support. - Add japanese characters support.

View File

@ -106,6 +106,12 @@ type AdminTarget struct {
ID string `json:"id"` ID string `json:"id"`
} }
type AdminLock struct {
Event string `json:"event"`
Resource string `json:"resource"`
ID string `json:"id"`
}
type ScreenResolution struct { type ScreenResolution struct {
Event string `json:"event"` Event string `json:"event"`
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`

View File

@ -8,23 +8,30 @@ import (
"m1k1o/neko/internal/types/message" "m1k1o/neko/internal/types/message"
) )
func (h *MessageHandler) adminLock(id string, session types.Session) error { func (h *MessageHandler) adminLock(id string, session types.Session, payload *message.AdminLock) error {
if !session.Admin() { if !session.Admin() {
h.logger.Debug().Msg("user not admin") h.logger.Debug().Msg("user not admin")
return nil return nil
} }
if h.locked { _, ok := h.locked[payload.Resource]
h.logger.Debug().Msg("server already locked...") if ok {
h.logger.Debug().Str("resource", payload.Resource).Msg("resource already locked...")
return nil return nil
} }
h.locked = true if payload.Resource != "login" && payload.Resource != "control" {
h.logger.Debug().Msg("unknown lock resource")
return nil
}
h.locked[payload.Resource] = id
if err := h.sessions.Broadcast( if err := h.sessions.Broadcast(
message.Admin{ message.AdminLock{
Event: event.ADMIN_LOCK, Event: event.ADMIN_LOCK,
ID: id, ID: id,
Resource: payload.Resource,
}, nil); err != nil { }, nil); err != nil {
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.ADMIN_LOCK) h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.ADMIN_LOCK)
return err return err
@ -33,23 +40,25 @@ func (h *MessageHandler) adminLock(id string, session types.Session) error {
return nil return nil
} }
func (h *MessageHandler) adminUnlock(id string, session types.Session) error { func (h *MessageHandler) adminUnlock(id string, session types.Session, payload *message.AdminLock) error {
if !session.Admin() { if !session.Admin() {
h.logger.Debug().Msg("user not admin") h.logger.Debug().Msg("user not admin")
return nil return nil
} }
if !h.locked { _, ok := h.locked[payload.Resource]
h.logger.Debug().Msg("server not locked...") if !ok {
h.logger.Debug().Str("resource", payload.Resource).Msg("resource not locked...")
return nil return nil
} }
h.locked = false delete(h.locked, payload.Resource)
if err := h.sessions.Broadcast( if err := h.sessions.Broadcast(
message.Admin{ message.AdminLock{
Event: event.ADMIN_UNLOCK, Event: event.ADMIN_UNLOCK,
ID: id, ID: id,
Resource: payload.Resource,
}, nil); err != nil { }, nil); err != nil {
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.ADMIN_UNLOCK) h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.ADMIN_UNLOCK)
return err return err

View File

@ -7,7 +7,6 @@ import (
) )
func (h *MessageHandler) controlRelease(id string, session types.Session) error { func (h *MessageHandler) controlRelease(id string, session types.Session) error {
// check if session is host // check if session is host
if !h.sessions.IsHost(id) { if !h.sessions.IsHost(id) {
h.logger.Debug().Str("id", id).Msg("is not the host") h.logger.Debug().Str("id", id).Msg("is not the host")
@ -34,6 +33,13 @@ func (h *MessageHandler) controlRelease(id string, session types.Session) error
func (h *MessageHandler) controlRequest(id string, session types.Session) error { func (h *MessageHandler) controlRequest(id string, session types.Session) error {
// check for host // check for host
if !h.sessions.HasHost() { if !h.sessions.HasHost() {
// check if control is locked or user is admin
_, ok := h.locked["control"]
if ok && !session.Admin() {
h.logger.Debug().Msg("control is locked")
return nil
}
// set host // set host
err := h.sessions.SetHost(id) err := h.sessions.SetHost(id)
if err != nil { if err != nil {
@ -91,6 +97,13 @@ func (h *MessageHandler) controlGive(id string, session types.Session, payload *
return nil return nil
} }
// check if control is locked or giver is admin
_, ok := h.locked["control"]
if ok && !session.Admin() {
h.logger.Debug().Msg("control is locked")
return nil
}
// set host // set host
err := h.sessions.SetHost(payload.ID) err := h.sessions.SetHost(payload.ID)
if err != nil { if err != nil {

View File

@ -19,7 +19,7 @@ type MessageHandler struct {
remote types.RemoteManager remote types.RemoteManager
broadcast types.BroadcastManager broadcast types.BroadcastManager
banned map[string]bool banned map[string]bool
locked bool locked map[string]string
} }
func (h *MessageHandler) Connected(admin bool, socket *WebSocket) (bool, string, error) { func (h *MessageHandler) Connected(admin bool, socket *WebSocket) (bool, string, error) {
@ -34,7 +34,8 @@ func (h *MessageHandler) Connected(admin bool, socket *WebSocket) (bool, string,
} }
} }
if h.locked && !admin { _, ok := h.locked["login"]
if ok && !admin {
h.logger.Debug().Msg("server locked") h.logger.Debug().Msg("server locked")
return false, "locked", nil return false, "locked", nil
} }
@ -128,9 +129,17 @@ func (h *MessageHandler) Message(id string, raw []byte) error {
// Admin Events // Admin Events
case event.ADMIN_LOCK: case event.ADMIN_LOCK:
return errors.Wrapf(h.adminLock(id, session), "%s failed", header.Event) payload := &message.AdminLock{}
return errors.Wrapf(
utils.Unmarshal(payload, raw, func() error {
return h.adminLock(id, session, payload)
}), "%s failed", header.Event)
case event.ADMIN_UNLOCK: case event.ADMIN_UNLOCK:
return errors.Wrapf(h.adminUnlock(id, session), "%s failed", header.Event) payload := &message.AdminLock{}
return errors.Wrapf(
utils.Unmarshal(payload, raw, func() error {
return h.adminUnlock(id, session, payload)
}), "%s failed", header.Event)
case event.ADMIN_CONTROL: case event.ADMIN_CONTROL:
return errors.Wrapf(h.adminControl(id, session), "%s failed", header.Event) return errors.Wrapf(h.adminControl(id, session), "%s failed", header.Event)
case event.ADMIN_RELEASE: case event.ADMIN_RELEASE:

View File

@ -12,6 +12,18 @@ func (h *MessageHandler) SessionCreated(id string, session types.Session) error
return err return err
} }
// notify all about what is locked
for resource, id := range h.locked {
if err := session.Send(message.AdminLock{
Event: event.ADMIN_LOCK,
ID: id,
Resource: resource,
}); err != nil {
h.logger.Warn().Str("id", id).Err(err).Msgf("sending event %s has failed", event.ADMIN_LOCK)
return err
}
}
if session.Admin() { if session.Admin() {
// send screen configurations if admin // send screen configurations if admin
if err := h.screenConfigurations(id, session); err != nil { if err := h.screenConfigurations(id, session); err != nil {
@ -22,17 +34,6 @@ func (h *MessageHandler) SessionCreated(id string, session types.Session) error
if err := h.boradcastStatus(session); err != nil { if err := h.boradcastStatus(session); err != nil {
return err return err
} }
// if locked, notify admin about that
if h.locked {
if err := session.Send(message.Admin{
Event: event.ADMIN_LOCK,
ID: id,
}); err != nil {
h.logger.Warn().Str("id", id).Err(err).Msgf("sending event %s has failed", event.ADMIN_LOCK)
return err
}
}
} }
return nil return nil

View File

@ -39,7 +39,7 @@ func New(sessions types.SessionManager, remote types.RemoteManager, broadcast ty
sessions: sessions, sessions: sessions,
webrtc: webrtc, webrtc: webrtc,
banned: make(map[string]bool), banned: make(map[string]bool),
locked: false, locked: make(map[string]string),
}, },
conns: 0, conns: 0,
} }