Skip to content

Commit

Permalink
Merge branch 'main' of github.com:Studio-Link/mix
Browse files Browse the repository at this point in the history
  • Loading branch information
sreimers committed Aug 22, 2023
2 parents df6d989 + 8ba03e6 commit 55a493b
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 32 deletions.
2 changes: 2 additions & 0 deletions include/mix.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ void slmix_session_video(struct session *sess, bool enable);
int slmix_session_speaker(struct session *sess, bool enable);
int slmix_session_new(struct mix *mix, struct session **sessp,
const struct http_msg *msg);
int slmix_session_auth(struct mix *mix, struct session *sess,
const struct http_msg *msg);
int slmix_session_start(struct session *sess,
const struct rtc_configuration *pc_config,
const struct mnat *mnat, const struct menc *menc);
Expand Down
18 changes: 18 additions & 0 deletions src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,24 @@ static void http_req_handler(struct http_conn *conn,
return;
}

if (0 == pl_strcasecmp(&msg->path, "/api/v1/client/reauth") &&
0 == pl_strcasecmp(&msg->met, "POST")) {
err = slmix_session_auth(mix, sess, msg);
if (err == EAUTH) {
http_sreply(conn, 401, "Unauthorized", "text/html", "",
0, NULL);
return;
}
if (err)
goto err;

slmix_session_user_updated(sess);
slmix_session_save(sess);

http_sreply(conn, 204, "OK", "text/html", "", 0, sess);
return;
}

if (0 == pl_strcasecmp(&msg->path, "/api/v1/client/name") &&
0 == pl_strcasecmp(&msg->met, "POST")) {

Expand Down
31 changes: 19 additions & 12 deletions src/sess.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,48 +245,55 @@ static int slmix_session_create(struct session **sessp, struct mix *mix,
}


int slmix_session_new(struct mix *mix, struct session **sessp,
const struct http_msg *msg)
int slmix_session_auth(struct mix *mix, struct session *sess,
const struct http_msg *msg)
{
struct pl token = PL_INIT;
bool speaker = false, host = false;
int err;

re_regex((char *)mbuf_buf(msg->mb), mbuf_get_left(msg->mb),
"[a-zA-Z0-9]+", &token);


if (token.l > 0) {
if (str_isset(mix->token_host) &&
0 == pl_strcmp(&token, mix->token_host)) {

info("sess: host token\n");
speaker = true;
host = true;
sess->user->host = true;
sess->user->speaker = true;
}
else if (str_isset(mix->token_guests) &&
0 == pl_strcmp(&token, mix->token_guests)) {

info("sess: guest token\n");
speaker = true;
sess->user->host = false;
sess->user->speaker = true;
}
else if (str_isset(mix->token_listeners) &&
0 == pl_strcmp(&token, mix->token_listeners)) {

info("sess: listener token\n");
speaker = false;
sess->user->host = false;
sess->user->speaker = false;
}
else {
return EAUTH;
}
}

err = slmix_session_create(sessp, mix, NULL, NULL, NULL, host,
speaker);
return 0;
}


int slmix_session_new(struct mix *mix, struct session **sessp,
const struct http_msg *msg)
{
int err;

err = slmix_session_create(sessp, mix, NULL, NULL, NULL, false, false);
if (err)
return err;

return 0;
return slmix_session_auth(mix, *sessp, msg);
}


Expand Down
4 changes: 2 additions & 2 deletions tests/bdd/environment.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import subprocess
import time
import socket
from subprocess import Popen


def is_port_reachable(host, port):
Expand Down Expand Up @@ -28,7 +28,7 @@ def before_all(context):
context.ws = {}
context.sessid = {}
context.response = {}
context.proc = subprocess.Popen(["./build/slmix", "-c", "config_example"], cwd="../../.")
context.proc = Popen(["./build/slmix", "-c", "config_example"], cwd="../../.")
wait_until_port_reachable('127.0.0.1', 9999, 1)


Expand Down
14 changes: 14 additions & 0 deletions tests/bdd/login.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ Feature: Login/Logout
Then "Alice" WebSocket receives "1" users
And "Alice" closes WebSocket

Scenario: WebSocket Session Login re-auth
Given "Alice" connects without a token
And "Alice" set client name
Then "Alice" WebSocket receives "1" users
And "Alice" WebSocket receives rooms update
Given "Alice" reauth with token "TOKENHOST"
Then "Alice" WebSocket receives updated "Alice" user
And "Alice" closes WebSocket

Scenario: WebSocket Session Login with token host
Given "Alice" connects with token "TOKENHOST"
Then "Alice" WebSocket receives "1" users
And "Alice" closes WebSocket

Scenario: Login as a audience user
Given "Alice" connects without a token
And "Alice" set client name
Expand Down
36 changes: 33 additions & 3 deletions tests/bdd/steps/steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@ def step_impl1(context, user):
"Session-ID"]


@given('"{user}" connects with token "{token}"')
def step_impl1(context, user, token):
response = requests.post(context.base_url + '/api/v1/client/connect',
data=token)
assert response.ok, f'Error: {response}'
context.sessid[user] = response.headers['Session-ID']
assert response.headers['Session-ID'] is not None, response.headers[
"Session-ID"]


@given('"{user}" reauth with token "{token}"')
def step_impl1(context, user, token):
headers = {'Session-ID': context.sessid[user]}
response = requests.post(context.base_url + '/api/v1/client/reauth',
headers=headers,
data=token)
assert response.ok, f'Error: {response}'
assert response.headers['Session-ID'] is not None, response.headers[
"Session-ID"]


@then('"{user}" WebSocket receives "{count}" users')
def step_impl2(context, user, count):
ws = create_connection("ws://127.0.0.1:9999/ws/v1/users")
Expand Down Expand Up @@ -74,11 +95,13 @@ def step_impl8(context, user, updated_user):
assert resp["name"] == updated_user, f'name: {resp}'


@then('"{user}" WebSocket receives rooms update')
def step_impl8a(context, user):
@then('"{user}" WebSocket receives updated "{updated_user}" user')
def step_impl8(context, user, updated_user):
response = context.ws[user].recv()
resp = json.loads(response)
assert resp["type"] == 'rooms', f'type: {resp}'
assert resp["type"] == 'user', f'type: {resp}'
assert resp["event"] == 'updated', f'event: {resp}'
assert resp["name"] == updated_user, f'name: {resp}'


@then('"{user}" WebSocket receives "{delete_user}" delete')
Expand All @@ -90,6 +113,13 @@ def step_impl9(context, user, delete_user):
assert resp["name"] == delete_user, f'user name: {resp}'


@then('"{user}" WebSocket receives rooms update')
def step_impl8a(context, user):
response = context.ws[user].recv()
resp = json.loads(response)
assert resp["type"] == 'rooms', f'type: {resp}'


@then('"{user}" logouts')
def step_impl10(context, user):
headers = {'Session-ID': context.sessid[user]}
Expand Down
17 changes: 9 additions & 8 deletions webui/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Error } from './error'
interface Session {
id: string
auth: boolean
host: boolean
user_id: string | null
}

Expand Down Expand Up @@ -55,6 +54,13 @@ export default {
return false
},

async reauth(token: string | string[]) {
if (!token)
return

await api_fetch('POST', '/client/reauth', token)
},

async connect(token?: string | null) {
if (!token)
token = window.localStorage.getItem('token')
Expand All @@ -71,7 +77,7 @@ export default {
}

/* Readonly! Use ws/users for updated states */
sess = { id: session_id, auth: false, host: false, user_id: null }
sess = { id: session_id, auth: false, user_id: null }

window.localStorage.setItem('sess', JSON.stringify(sess))
},
Expand All @@ -88,7 +94,6 @@ export default {
const user = JSON.parse(await resp?.text())

sess.user_id = user.id
sess.host = user.host
window.localStorage.setItem('sess', JSON.stringify(sess))

router.push({ name: 'Home' })
Expand Down Expand Up @@ -143,12 +148,8 @@ export default {
else await api_fetch('PUT', '/webrtc/audio/disable', null)
},

is_host(): boolean {
return sess.host
},

async record_switch(type: RecordType) {
if (!sess.host) return
if (!Users.host_status.value) return

if (Users.record.value) {
Users.record.value = false
Expand Down
2 changes: 1 addition & 1 deletion webui/src/components/Listeners.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
</picture>
</div>
<button
v-if="api.is_host()"
v-if="Users.host_status.value"
@click="api.speaker(item.id)"
type="button"
class="hidden group-hover:inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-2.5 py-1.5 text-xs font-bold text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
Expand Down
4 changes: 2 additions & 2 deletions webui/src/components/RecButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div
class="fadeout inline-flex rounded-md shadow-sm px-3 h-9"
:class="{
hidden: !Users.record.value && !api.is_host(),
hidden: !Users.record.value && !Users.host_status.value,
}"
>
<button
Expand All @@ -13,7 +13,7 @@
'bg-gray-600 hover:bg-gray-500 rounded-md': Users.record.value,
}"
class="relative inline-flex items-center px-3 py-2 uppercase text-xs font-semibold text-white hover:bg-red-600 focus:z-10"
:disabled="!api.is_host()"
:disabled="!Users.host_status.value"
>
<span v-if="Users.record.value && Users.record_type.value === RecordType.AudioVideo" class="font-mono">REC {{ Users.record_timer.value }}</span>
<span v-if="Users.record.value && Users.record_type.value === RecordType.AudioOnly" class="font-mono">REC Audio {{ Users.record_timer.value }}</span>
Expand Down
4 changes: 2 additions & 2 deletions webui/src/components/Speakers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
</picture>
</div>
<button
v-if="api.is_host()"
v-if="Users.host_status.value"
@click="api.listener(item.id)"
type="button"
class="hidden group-hover:inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-2.5 py-1.5 text-xs font-bold text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
Expand All @@ -105,7 +105,7 @@
To Audience
</button>
<button
v-if="!api.is_host() && item.id === api.session().user_id && room?.show"
v-if="!Users.host_status.value && item.id === api.session().user_id && room?.show"
@click="api.listener(item.id)"
type="button"
class="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-2.5 py-1.5 text-xs font-bold text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
Expand Down
4 changes: 2 additions & 2 deletions webui/src/components/WebrtcVideo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Audio RTT: {{item.stats.artt}} ms
</span>

<button
v-if="api.is_host()"
v-if="Users.host_status.value"
@click="api.listener(item.id)"
type="button"
class="hidden group-hover:inline-flex ml-2 items-center rounded-md border border-transparent bg-indigo-600 px-2.5 py-1.5 text-xs font-bold text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
Expand All @@ -119,7 +119,7 @@ Audio RTT: {{item.stats.artt}} ms
To Audience
</button>
<button
v-if="!api.is_host() && item.id === api.session().user_id && room?.show"
v-if="!Users.host_status.value && item.id === api.session().user_id && room?.show"
@click="api.listener(item.id)"
type="button"
class="hidden group-hover:inline-flex ml-2 items-center rounded-md border border-transparent bg-indigo-600 px-2.5 py-1.5 text-xs font-bold text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
Expand Down
2 changes: 2 additions & 0 deletions webui/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ router.beforeEach(async (to) => {
return { name: 'Login' }
}
if (auth && to.name === 'Login') {
if (to.params.token)
await api.reauth(to.params.token)
return { name: 'Home' }
}
})
Expand Down
4 changes: 4 additions & 0 deletions webui/src/ws/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ interface Users {
record_type: Ref<RecordType>
hand_status: Ref<boolean>
speaker_status: Ref<boolean>
host_status: Ref<boolean>
}

function pad(num: number, size: number) {
Expand All @@ -81,6 +82,7 @@ export const Users: Users = {
record_type: ref(RecordType.AudioVideo),
hand_status: ref(false),
speaker_status: ref(false),
host_status: ref(false),

ws_close() {
this.socket?.close()
Expand Down Expand Up @@ -116,6 +118,7 @@ export const Users: Users = {
if (data.users[key].id === api.session().user_id) {
this.hand_status.value = data.users[key].hand
this.speaker_status.value = data.users[key].speaker
this.host_status.value = data.users[key].host
}
if (data.users[key].speaker) {
if (data.users[key].video && data.users[key].pidx) {
Expand Down Expand Up @@ -157,6 +160,7 @@ export const Users: Users = {
if (user.id === api.session().user_id) {
this.hand_status.value = user.hand
this.speaker_status.value = data.speaker
this.host_status.value = data.host

/* Only allow remote disable */
if (!data.speaker) {
Expand Down

0 comments on commit 55a493b

Please sign in to comment.