@@ -73,6 +73,22 @@ namespace Teknik.Areas.Admin.Controllers | |||
return View(model); | |||
} | |||
[HttpGet] | |||
[TrackPageView] | |||
public IActionResult PasteSearch() | |||
{ | |||
PasteSearchViewModel model = new PasteSearchViewModel(); | |||
return View(model); | |||
} | |||
[HttpGet] | |||
[TrackPageView] | |||
public IActionResult ShoretenedUrlSearch() | |||
{ | |||
UploadSearchViewModel model = new UploadSearchViewModel(); | |||
return View(model); | |||
} | |||
[HttpPost] | |||
public async Task<IActionResult> GetUserSearchResults(string query, [FromServices] ICompositeViewEngine viewEngine) | |||
{ | |||
@@ -133,6 +149,48 @@ namespace Teknik.Areas.Admin.Controllers | |||
return Json(new { error = new { message = "Upload does not exist" } }); | |||
} | |||
[HttpPost] | |||
public async Task<IActionResult> GetPasteSearchResults(string url, [FromServices] ICompositeViewEngine viewEngine) | |||
{ | |||
Paste.Models.Paste foundPaste = _dbContext.Pastes.Where(u => u.Url == url).FirstOrDefault(); | |||
if (foundPaste != null) | |||
{ | |||
PasteResultViewModel model = new PasteResultViewModel(); | |||
model.Url = foundPaste.Url; | |||
model.DatePosted = foundPaste.DatePosted; | |||
model.Views = foundPaste.Views; | |||
model.DeleteKey = foundPaste.DeleteKey; | |||
model.Username = foundPaste.User?.Username; | |||
string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/Admin/Views/Admin/PasteResult.cshtml", model); | |||
return Json(new { result = new { html = renderedView } }); | |||
} | |||
return Json(new { error = new { message = "Paste does not exist" } }); | |||
} | |||
[HttpPost] | |||
public async Task<IActionResult> GetShortenedUrlSearchResults(string url, [FromServices] ICompositeViewEngine viewEngine) | |||
{ | |||
Shortener.Models.ShortenedUrl foundUrl = _dbContext.ShortenedUrls.Where(u => u.ShortUrl == url).FirstOrDefault(); | |||
if (foundUrl != null) | |||
{ | |||
ShortenedUrlResultViewModel model = new ShortenedUrlResultViewModel(); | |||
model.OriginalUrl = foundUrl.OriginalUrl; | |||
model.ShortenedUrl = foundUrl.ShortUrl; | |||
model.CreationDate = foundUrl.DateAdded; | |||
model.Views = foundUrl.Views; | |||
model.Username = foundUrl.User?.Username; | |||
string renderedView = await RenderPartialViewToString(viewEngine, "~/Areas/Admin/Views/Admin/ShortenedUrlResult.cshtml", model); | |||
return Json(new { result = new { html = renderedView } }); | |||
} | |||
return Json(new { error = new { message = "Shortened Url does not exist" } }); | |||
} | |||
[HttpPost] | |||
[ValidateAntiForgeryToken] | |||
public async Task<IActionResult> EditUserAccountType(string username, AccountType accountType) |
@@ -0,0 +1,18 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Web; | |||
using Teknik.ViewModels; | |||
namespace Teknik.Areas.Admin.ViewModels | |||
{ | |||
public class PasteResultViewModel : ViewModelBase | |||
{ | |||
public string Url { get; set; } | |||
public string Title { get; set; } | |||
public DateTime DatePosted { get; set; } | |||
public int Views { get; set; } | |||
public string DeleteKey { get; set; } | |||
public string Username { get; set; } | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Web; | |||
using Teknik.ViewModels; | |||
namespace Teknik.Areas.Admin.ViewModels | |||
{ | |||
public class PasteSearchViewModel : ViewModelBase | |||
{ | |||
} | |||
} |
@@ -0,0 +1,17 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Web; | |||
using Teknik.ViewModels; | |||
namespace Teknik.Areas.Admin.ViewModels | |||
{ | |||
public class ShortenedUrlResultViewModel : ViewModelBase | |||
{ | |||
public string OriginalUrl { get; set; } | |||
public string ShortenedUrl { get; set; } | |||
public DateTime CreationDate { get; set; } | |||
public int Views { get; set; } | |||
public string Username { get; set; } | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Web; | |||
using Teknik.ViewModels; | |||
namespace Teknik.Areas.Admin.ViewModels | |||
{ | |||
public class ShortenedUrlSearchViewModel : ViewModelBase | |||
{ | |||
} | |||
} |
@@ -0,0 +1,33 @@ | |||
@model Teknik.Areas.Admin.ViewModels.PasteResultViewModel | |||
<div class="panel panel-default"> | |||
<div class="panel-heading text-center"> | |||
<a id="paste-url" href="@Url.SubRouteUrl("p", "Paste.Raw", new { url = Model.Url })">@Url.SubRouteUrl("u", "Paste.Raw", new { url = Model.Url })</a> | |||
</div> | |||
<div class="panel-body"> | |||
<div class="col-sm-2 text-center"> | |||
<label for="type">Username</label> | |||
<p id="type"> | |||
@if (!string.IsNullOrEmpty(Model.Username)) | |||
{ | |||
@:<a href="@Url.SubRouteUrl("admin", "Admin.UserInfo", new { username = Model.Username })">@Model.Username</a> | |||
} | |||
</p> | |||
</div> | |||
<div class="col-sm-2 text-center"> | |||
<label for="size">Title</label> | |||
<p id="size">@Model.Title</p> | |||
</div> | |||
<div class="col-sm-2 text-center"> | |||
<label for="dateCreated">Date Created</label> | |||
<p id="dateCreated"><time datetime="@Model.DatePosted.ToString("s")">@Model.DatePosted.ToString("MMMM dd, yyyy")</time></p> | |||
</div> | |||
<div class="col-sm-2 text-center"> | |||
<label for="views">Views</label> | |||
<p id="views">@Model.Views</p> | |||
</div> | |||
<div class="col-sm-2 text-center"> | |||
<p id="delete-paste"><button role="button" class="btn btn-danger delete-paste-button" data-paste-id="@Model.Url">Delete</button></p> | |||
</div> | |||
</div> | |||
</div> |
@@ -0,0 +1,27 @@ | |||
@model Teknik.Areas.Admin.ViewModels.PasteSearchViewModel | |||
<script> | |||
// We need to define the action URLs for the script | |||
var homeUrl = '@Url.SubRouteUrl("admin", "Admin.PasteSearch")'; | |||
var searchResultsURL = '@Url.SubRouteUrl("admin", "Admin.Action", new { action = "GetPasteSearchResults" })'; | |||
var deletePasteURL = '@Url.SubRouteUrl("p", "Paste.Delete")'; | |||
</script> | |||
<div class="container"> | |||
<div class="row"> | |||
<div class="col-sm-6 col-sm-offset-3"> | |||
<!form> | |||
<div class="form-group center-block"> | |||
<input type="text" class="form-control" id="Query" name="Query" placeholder="Paste Url" /> | |||
</div> | |||
</!form> | |||
</div> | |||
</div> | |||
<div class="row"> | |||
<div class="col-sm-10 col-sm-offset-1"> | |||
<div class="results" id="results"></div> | |||
</div> | |||
</div> | |||
</div> | |||
<bundle src="js/pasteSearch.min.js" append-version="true"></bundle> |
@@ -0,0 +1,33 @@ | |||
@model Teknik.Areas.Admin.ViewModels.ShortenedUrlResultViewModel | |||
<div class="panel panel-default"> | |||
<div class="panel-heading text-center"> | |||
<a id="paste-url" href="@Url.SubRouteUrl("shortened", "Shortener.View", new { url = Model.ShortenedUrl })">@Url.SubRouteUrl("shortened", "Shortener.View", new { url = Model.ShortenedUrl })</a> | |||
</div> | |||
<div class="panel-body"> | |||
<div class="col-sm-2 text-center"> | |||
<label for="type">Username</label> | |||
<p id="type"> | |||
@if (!string.IsNullOrEmpty(Model.Username)) | |||
{ | |||
@:<a href="@Url.SubRouteUrl("admin", "Admin.UserInfo", new { username = Model.Username })">@Model.Username</a> | |||
} | |||
</p> | |||
</div> | |||
<div class="col-sm-2 text-center"> | |||
<label for="size">Original Url</label> | |||
<p id="size">@Model.OriginalUrl</p> | |||
</div> | |||
<div class="col-sm-2 text-center"> | |||
<label for="dateCreated">Date Created</label> | |||
<p id="dateCreated"><time datetime="@Model.CreationDate.ToString("s")">@Model.CreationDate.ToString("MMMM dd, yyyy")</time></p> | |||
</div> | |||
<div class="col-sm-2 text-center"> | |||
<label for="views">Views</label> | |||
<p id="views">@Model.Views</p> | |||
</div> | |||
<div class="col-sm-2 text-center"> | |||
<p id="delete-short"><button role="button" class="btn btn-danger delete-short-url-button" data-short-id="@Model.ShortenedUrl">Delete</button></p> | |||
</div> | |||
</div> | |||
</div> |
@@ -0,0 +1,27 @@ | |||
@model Teknik.Areas.Admin.ViewModels.ShortenedUrlSearchViewModel | |||
<script> | |||
// We need to define the action URLs for the script | |||
var homeUrl = '@Url.SubRouteUrl("admin", "Admin.ShortenedUrlSearch")'; | |||
var searchResultsURL = '@Url.SubRouteUrl("admin", "Admin.Action", new { action = "GetShortenedUrlSearchResults" })'; | |||
var deleteShortenedURL = '@Url.SubRouteUrl("s", "Shortener.Delete")'; | |||
</script> | |||
<div class="container"> | |||
<div class="row"> | |||
<div class="col-sm-6 col-sm-offset-3"> | |||
<!form> | |||
<div class="form-group center-block"> | |||
<input type="text" class="form-control" id="Query" name="Query" placeholder="Shortened Url" /> | |||
</div> | |||
</!form> | |||
</div> | |||
</div> | |||
<div class="row"> | |||
<div class="col-sm-10 col-sm-offset-1"> | |||
<div class="results" id="results"></div> | |||
</div> | |||
</div> | |||
</div> | |||
<bundle src="js/shortenedUrlSearch.min.js" append-version="true"></bundle> |
@@ -381,13 +381,14 @@ namespace Teknik.Areas.Paste.Controllers | |||
Models.Paste foundPaste = _dbContext.Pastes.Where(p => p.Url == id).FirstOrDefault(); | |||
if (foundPaste != null) | |||
{ | |||
if (foundPaste.User.Username == User.Identity.Name) | |||
if (foundPaste.User.Username == User.Identity.Name || | |||
User.IsInRole("Admin")) | |||
{ | |||
DeleteFile(foundPaste); | |||
return Json(new { result = true, redirect = Url.SubRouteUrl("p", "Paste.Index") }); | |||
} | |||
return Json(new { error = new { message = "You do not have permission to edit this Paste" } }); | |||
return Json(new { error = new { message = "You do not have permission to delete this Paste" } }); | |||
} | |||
return Json(new { error = new { message = "This Paste does not exist" } }); | |||
} |
@@ -85,14 +85,15 @@ namespace Teknik.Areas.Shortener.Controllers | |||
ShortenedUrl shortenedUrl = _dbContext.ShortenedUrls.Where(s => s.ShortUrl == id).FirstOrDefault(); | |||
if (shortenedUrl != null) | |||
{ | |||
if (shortenedUrl.User.Username == User.Identity.Name) | |||
if (shortenedUrl.User.Username == User.Identity.Name || | |||
User.IsInRole("Admin")) | |||
{ | |||
_dbContext.ShortenedUrls.Remove(shortenedUrl); | |||
_dbContext.SaveChanges(); | |||
return Json(new { result = true }); | |||
} | |||
return Json(new { error = new { message = "You do not have permission to edit this Shortened URL" } }); | |||
return Json(new { error = new { message = "You do not have permission to delete this Shortened URL" } }); | |||
} | |||
return Json(new { error = new { message = "This Shortened URL does not exist" } }); | |||
} |
@@ -0,0 +1,63 @@ | |||
/* globals searchResultsURL, deletePasteURL, homeUrl */ | |||
$(document).ready(function () { | |||
$('#Query').on('input', function () { | |||
var query = $(this).val(); | |||
// Try to strip out the ID from the url | |||
var pattern = '(?:(?:.+)\\/)?([^\\?]+)(?:\\?(?:.*))?'; | |||
var reg = new RegExp(pattern); | |||
var match = reg.exec(query); | |||
query = match[1]; | |||
$.ajax({ | |||
type: "POST", | |||
url: searchResultsURL, | |||
data: { url: query }, | |||
success: function (response) { | |||
if (response.result) { | |||
$("#top_msg").css('display', 'none'); | |||
$("#top_msg").html(''); | |||
$("#results").html(response.result.html); | |||
LinkPasteDelete($('.delete-paste-button')); | |||
} | |||
else { | |||
$("#top_msg").css('display', 'inline', 'important'); | |||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>'); | |||
} | |||
} | |||
}); | |||
}); | |||
}); | |||
function LinkPasteDelete(selector) { | |||
$(selector).click(function () { | |||
var id = $(this).data('paste-id'); | |||
deleteConfirm("Are you sure you want to delete this paste?", function (result) { | |||
if (result) { | |||
$.ajax({ | |||
type: "POST", | |||
url: deletePasteURL, | |||
data: { id: id }, | |||
headers: { 'X-Requested-With': 'XMLHttpRequest' }, | |||
xhrFields: { | |||
withCredentials: true | |||
}, | |||
success: function (response) { | |||
if (response.result) { | |||
window.location.replace(homeUrl); | |||
} | |||
else { | |||
$("#top_msg").css('display', 'inline', 'important'); | |||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>'); | |||
} | |||
}, | |||
error: function (response) { | |||
$("#top_msg").css('display', 'inline', 'important'); | |||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response.responseText) + '</div>'); | |||
} | |||
}); | |||
} | |||
}); | |||
}); | |||
} |
@@ -0,0 +1,63 @@ | |||
/* globals searchResultsURL, deleteShortenedURL, homeUrl */ | |||
$(document).ready(function () { | |||
$('#Query').on('input', function () { | |||
var query = $(this).val(); | |||
// Try to strip out the ID from the url | |||
var pattern = '(?:(?:.+)\\/)?([^\\?]+)(?:\\?(?:.*))?'; | |||
var reg = new RegExp(pattern); | |||
var match = reg.exec(query); | |||
query = match[1]; | |||
$.ajax({ | |||
type: "POST", | |||
url: searchResultsURL, | |||
data: { url: query }, | |||
success: function (response) { | |||
if (response.result) { | |||
$("#top_msg").css('display', 'none'); | |||
$("#top_msg").html(''); | |||
$("#results").html(response.result.html); | |||
LinkShortUrlDelete($('.delete-short-url-button')); | |||
} | |||
else { | |||
$("#top_msg").css('display', 'inline', 'important'); | |||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>'); | |||
} | |||
} | |||
}); | |||
}); | |||
}); | |||
function LinkShortUrlDelete(selector) { | |||
$(selector).click(function () { | |||
var id = $(this).data('short-id'); | |||
deleteConfirm("Are you sure you want to delete this shortened url?", function (result) { | |||
if (result) { | |||
$.ajax({ | |||
type: "POST", | |||
url: deleteShortenedURL, | |||
data: { id: id }, | |||
headers: { 'X-Requested-With': 'XMLHttpRequest' }, | |||
xhrFields: { | |||
withCredentials: true | |||
}, | |||
success: function (response) { | |||
if (response.result) { | |||
window.location.replace(homeUrl); | |||
} | |||
else { | |||
$("#top_msg").css('display', 'inline', 'important'); | |||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response) + '</div>'); | |||
} | |||
}, | |||
error: function (response) { | |||
$("#top_msg").css('display', 'inline', 'important'); | |||
$("#top_msg").html('<div class="alert alert-danger alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + parseErrorMessage(response.responseText) + '</div>'); | |||
} | |||
}); | |||
} | |||
}); | |||
}); | |||
} |
@@ -11,6 +11,18 @@ | |||
"./wwwroot/js/App/Admin/UploadSearch.js" | |||
] | |||
}, | |||
{ | |||
"outputFileName": "./wwwroot/js/pasteSearch.min.js", | |||
"inputFiles": [ | |||
"./wwwroot/js/App/Admin/PasteSearch.js" | |||
] | |||
}, | |||
{ | |||
"outputFileName": "./wwwroot/js/shortenedUrlSearch.min.js", | |||
"inputFiles": [ | |||
"./wwwroot/js/App/Admin/ShortenedUrlSearch.js" | |||
] | |||
}, | |||
{ | |||
"outputFileName": "./wwwroot/js/userInfo.min.js", | |||
"inputFiles": [ | |||
@@ -221,12 +233,6 @@ | |||
"./wwwroot/js/app/User/ResetPass.js" | |||
] | |||
}, | |||
{ | |||
"outputFileName": "./wwwroot/js/user.settings.min.js", | |||
"inputFiles": [ | |||
"./wwwroot/js/app/User/Settings.js" | |||
] | |||
}, | |||
{ | |||
"outputFileName": "./wwwroot/js/user.settings.blog.min.js", | |||
"inputFiles": [ |