190 lines
6.9 KiB
Plaintext
190 lines
6.9 KiB
Plaintext
@page
|
|
@inject IAntiforgery Antiforgery
|
|
@using Microsoft.AspNetCore.Antiforgery
|
|
@using Microsoft.AspNetCore.Http
|
|
@using RTMPDash.DataModels
|
|
@model AdminModel
|
|
@{
|
|
ViewData["Title"] = "Admin";
|
|
var db = new AppDb.DbConn();
|
|
var tokenSet = Antiforgery.GetAndStoreTokens(HttpContext);
|
|
|
|
if (string.IsNullOrEmpty(HttpContext.Session.GetString("authenticatedUser")) || !new AppDb.DbConn().Users.First(p => p.Username == HttpContext.Session.GetString("authenticatedUser")).IsAdmin) {
|
|
Response.Redirect("/");
|
|
return;
|
|
}
|
|
var stats = StreamUtils.GetStatsObject();
|
|
}
|
|
|
|
<h2>Users</h2>
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">Username</th>
|
|
<th scope="col">Stream status</th>
|
|
<th scope="col">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var user in db.Users) {
|
|
<tr>
|
|
<th scope="row">@user.Username</th>
|
|
<td>
|
|
@if (StreamUtils.IsLive(user.Username, stats)) {
|
|
var uptime = TimeSpan.FromMilliseconds(StreamUtils.GetClientTime(user.Username, stats)).StripMilliseconds();
|
|
|
|
if (user.AllowRestream && !string.IsNullOrWhiteSpace(user.RestreamTargets)) {
|
|
var restreams = StreamUtils.CountLiveRestreams(user.Username, stats);
|
|
if (restreams > 0) {
|
|
<button class="btn btn-dark" role="button" style="width:18ch" disabled>Restreaming (@restreams)</button>
|
|
}
|
|
else {
|
|
<button class="btn btn-warning" role="button" style="width:18ch" disabled>Restreaming (@restreams)</button>
|
|
}
|
|
}
|
|
else {
|
|
<button class="btn btn-success" role="button" style="width:18ch" disabled>Live</button>
|
|
}
|
|
<button class="btn btn-dark" role="button" disabled>@uptime.ToString("c")</button>
|
|
}
|
|
else if (StreamUtils.IsLive(user.PrivateAccessKey, stats)) {
|
|
var uptime = TimeSpan.FromMilliseconds(StreamUtils.GetClientTime(user.PrivateAccessKey, stats)).StripMilliseconds();
|
|
|
|
if (user.AllowRestream && !string.IsNullOrWhiteSpace(user.RestreamTargets)) {
|
|
var restreams = StreamUtils.CountLiveRestreams(user.Username, user.PrivateAccessKey, stats);
|
|
if (restreams > 0) {
|
|
<button class="btn btn-dark" role="button" style="width:18ch" disabled>Restreaming (@restreams)</button>
|
|
}
|
|
else {
|
|
<button class="btn btn-warning" role="button" style="width:18ch" disabled>Restreaming (@restreams)</button>
|
|
}
|
|
}
|
|
else {
|
|
<button class="btn btn-warning" role="button" style="width:18ch" disabled>Live (private)</button>
|
|
}
|
|
<button class="btn btn-dark" role="button" disabled>@uptime.ToString("c")</button>
|
|
}
|
|
else {
|
|
<button class="btn btn-danger" role="button" style="width:18ch" disabled>No data</button>
|
|
}
|
|
</td>
|
|
<td>
|
|
@if (user.IsAdmin) {
|
|
if (user.Username != HttpContext.Session.GetString("authenticatedUser")) {
|
|
<button onclick="ajax_and_reload('admin_revoke', '@user.Username')" class="btn btn-warning">Revoke Admin</button>
|
|
}
|
|
else {
|
|
<button class="btn btn-warning" disabled>Revoke Admin</button>
|
|
}
|
|
}
|
|
else {
|
|
<button onclick="ajax_and_reload('admin_grant', '@user.Username')" class="btn btn-primary">Grant Admin</button>
|
|
}
|
|
@if (user.AllowRestream) {
|
|
<button onclick="ajax_and_reload('restream_revoke', '@user.Username')" class="btn btn-secondary">Revoke Restreams</button>
|
|
}
|
|
else {
|
|
<button onclick="ajax_and_reload('restream_allow', '@user.Username')" class="btn btn-info">Allow Restreams</button>
|
|
}
|
|
@if (user.IsAdmin) {
|
|
<button class="btn btn-dark" disabled>Set Password</button>
|
|
<button class="btn btn-danger" disabled>Delete</button>
|
|
}
|
|
else {
|
|
<button class="btn btn-dark" onclick="prepareSetPasswordModal('@user.Username')">Set Password</button>
|
|
<button onclick="prepareDeleteUserModal('@user.Username')" class="btn btn-danger">Delete</button>
|
|
}
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
|
|
<hr/>
|
|
|
|
<h2>Invites <button onclick="ajax_and_reload('invite_generate')" class="btn btn-dark">Generate New Invite</button></h2>
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">Code</th>
|
|
<th scope="col">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var invite in db.Invites) {
|
|
<tr>
|
|
<td>@invite.Code</td>
|
|
<td>
|
|
<button onclick="copyToClipboard('@invite.Code')" class="btn btn-sm btn-secondary">Copy</button>
|
|
<button onclick="ajax_and_reload('invite_revoke', '@invite.Code')" class="btn btn-sm btn-danger">Revoke</button>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
|
|
<script>
|
|
function ajax_and_reload(action, target, value) {
|
|
$.ajax({method: 'POST', data: {action: action, target: target, value: value, '__RequestVerificationToken' : '@tokenSet.RequestToken'}, success: function () { location.reload() }})
|
|
}
|
|
function prepareSetPasswordModal(target) {
|
|
document.getElementById('setPasswordModalLabel').innerHTML = 'Set password for: ' + target;
|
|
document.getElementById('setPasswordTarget').value = target;
|
|
$('#setPasswordModal').modal();
|
|
}
|
|
function prepareDeleteUserModal(target) {
|
|
document.getElementById('deleteUserModalLabel').innerHTML = 'Delete user: ' + target;
|
|
document.getElementById('deleteUserTarget').value = target;
|
|
$('#deleteUserModal').modal();
|
|
}
|
|
</script>
|
|
|
|
<div class="modal fade" id="setPasswordModal" tabindex="-1" aria-labelledby="setPasswordModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="setPasswordModalLabel">Set password for</h5>
|
|
<button role="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<form method="POST">
|
|
<div class="modal-body">
|
|
<div class="form-group">
|
|
<input type="password" class="form-control" id="InputPassword" placeholder="New Password" name="value" required>
|
|
<input type="hidden" value="user_setpass" name="action">
|
|
<input type="hidden" value="" name="target" id="setPasswordTarget">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button role="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
|
<button type="submit" class="btn btn-primary">Save changes</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="deleteUserModal" tabindex="-1" aria-labelledby="setPasswordModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="deleteUserModalLabel">Delete user</h5>
|
|
<button role="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<form method="POST">
|
|
<div class="modal-body">
|
|
<div class="form-group">
|
|
<input type="hidden" value="user_delete" name="action">
|
|
<input type="hidden" value="" name="target" id="deleteUserTarget">
|
|
<button role="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-danger">Do it</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|