Browse Source

- Added Basic Auth handling inside the auth attributes

- Removed global auth attribute and moved it to each controller
- Added new auth information to the API help doc
- Finished UI for managing auth tokens
- Added breadcrumbs to the help pages
pull/50/head
Teknikode 5 years ago
parent
commit
cbe5078b9d
  1. 2
      Teknik/App_Start/FilterConfig.cs
  2. 2
      Teknik/Areas/API/Controllers/APIController.cs
  3. 20
      Teknik/Areas/API/Controllers/APIv1Controller.cs
  4. 6
      Teknik/Areas/API/Models/APIv1BaseModel.cs
  5. 2
      Teknik/Areas/About/Controllers/AboutController.cs
  6. 2
      Teknik/Areas/Blog/Controllers/BlogController.cs
  7. 2
      Teknik/Areas/Contact/Controllers/ContactController.cs
  8. 2
      Teknik/Areas/Dev/Controllers/DevController.cs
  9. 30
      Teknik/Areas/Error/Controllers/ErrorController.cs
  10. 28
      Teknik/Areas/Error/Views/Error/Http401.cshtml
  11. 2
      Teknik/Areas/Help/Controllers/HelpController.cs
  12. 22
      Teknik/Areas/Help/Views/Help/API/API.cshtml
  13. 33
      Teknik/Areas/Help/Views/Help/API/v1/Paste.cshtml
  14. 33
      Teknik/Areas/Help/Views/Help/API/v1/Shorten.cshtml
  15. 33
      Teknik/Areas/Help/Views/Help/API/v1/Upload.cshtml
  16. 6
      Teknik/Areas/Help/Views/Help/Blog.cshtml
  17. 6
      Teknik/Areas/Help/Views/Help/Git.cshtml
  18. 6
      Teknik/Areas/Help/Views/Help/Irc.cshtml
  19. 4
      Teknik/Areas/Help/Views/Help/Mail.cshtml
  20. 6
      Teknik/Areas/Help/Views/Help/Markdown.cshtml
  21. 6
      Teknik/Areas/Help/Views/Help/Mumble.cshtml
  22. 6
      Teknik/Areas/Help/Views/Help/RSS.cshtml
  23. 6
      Teknik/Areas/Help/Views/Help/Tools.cshtml
  24. 6
      Teknik/Areas/Help/Views/Help/Upload.cshtml
  25. 2
      Teknik/Areas/Home/Controllers/HomeController.cs
  26. 2
      Teknik/Areas/Paste/Controllers/PasteController.cs
  27. 2
      Teknik/Areas/Podcast/Controllers/PodcastController.cs
  28. 2
      Teknik/Areas/Privacy/Controllers/PrivacyController.cs
  29. 2
      Teknik/Areas/RSS/Controllers/RSSController.cs
  30. 2
      Teknik/Areas/Shortener/Controllers/ShortenerController.cs
  31. 2
      Teknik/Areas/Stream/Controllers/StreamController.cs
  32. 2
      Teknik/Areas/TOS/Controllers/TOSController.cs
  33. 2
      Teknik/Areas/Transparency/Controllers/TransparencyController.cs
  34. 2
      Teknik/Areas/Upload/Controllers/UploadController.cs
  35. 112
      Teknik/Areas/User/Controllers/UserController.cs
  36. 2
      Teknik/Areas/User/Models/AuthToken.cs
  37. 81
      Teknik/Areas/User/Scripts/User.js
  38. 105
      Teknik/Areas/User/Utility/UserHelper.cs
  39. 17
      Teknik/Areas/User/ViewModels/AuthTokenViewModel.cs
  40. 2
      Teknik/Areas/User/ViewModels/SettingsViewModel.cs
  41. 17
      Teknik/Areas/User/Views/User/AuthToken.cshtml
  42. 23
      Teknik/Areas/User/Views/User/Settings.cshtml
  43. 2
      Teknik/Areas/Vault/Controllers/VaultController.cs
  44. 148
      Teknik/Attributes/TeknikAuthorizeAttribute.cs
  45. 90
      Teknik/Global.asax.cs
  46. 3
      Teknik/Teknik.csproj
  47. 1
      Utilities/Utilities/HttpRequestExtensions.cs
  48. 23
      Utilities/Utilities/StringHelper.cs
  49. 1
      Utilities/Utilities/Utilities.csproj
  50. 45
      Utilities/Utilities/ViewExtensions.cs

2
Teknik/App_Start/FilterConfig.cs

@ -10,7 +10,7 @@ namespace Teknik @@ -10,7 +10,7 @@ namespace Teknik
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
filters.Add(new TeknikAuthorizeAttribute());
//filters.Add(new TeknikAuthorizeAttribute());
filters.Add(new RequireHttpsAttribute());
}
}

2
Teknik/Areas/API/Controllers/APIController.cs

@ -9,9 +9,11 @@ using Teknik.Areas.Upload; @@ -9,9 +9,11 @@ using Teknik.Areas.Upload;
using Teknik.Controllers;
using Teknik.Utilities;
using Teknik.Models;
using Teknik.Attributes;
namespace Teknik.Areas.API.Controllers
{
[TeknikAuthorize]
public class APIController : DefaultController
{
private TeknikEntities db = new TeknikEntities();

20
Teknik/Areas/API/Controllers/APIv1Controller.cs

@ -17,9 +17,11 @@ using Teknik.Filters; @@ -17,9 +17,11 @@ using Teknik.Filters;
using Teknik.Areas.API.Models;
using Teknik.Areas.Users.Models;
using Teknik.Areas.Users.Utility;
using Teknik.Attributes;
namespace Teknik.Areas.API.Controllers
{
[TeknikAuthorize(AuthType.Basic)]
public class APIv1Controller : DefaultController
{
private TeknikEntities db = new TeknikEntities();
@ -27,7 +29,7 @@ namespace Teknik.Areas.API.Controllers @@ -27,7 +29,7 @@ namespace Teknik.Areas.API.Controllers
[AllowAnonymous]
public ActionResult Index()
{
return Redirect(Url.SubRouteUrl("help", "Help.Topic", new { topic = "API" }));
return Redirect(Url.SubRouteUrl("help", "Help.API"));
}
[HttpPost]
@ -120,9 +122,9 @@ namespace Teknik.Areas.API.Controllers @@ -120,9 +122,9 @@ namespace Teknik.Areas.API.Controllers
if (upload != null)
{
// Associate this with the user if they provided an auth key
if (!string.IsNullOrEmpty(model.authToken))
if (User.Identity.IsAuthenticated)
{
User foundUser = UserHelper.GetUserFromToken(db, model.authToken);
User foundUser = UserHelper.GetUser(db, User.Identity.Name);
if (foundUser != null)
{
upload.UserId = foundUser.UserId;
@ -183,10 +185,10 @@ namespace Teknik.Areas.API.Controllers @@ -183,10 +185,10 @@ namespace Teknik.Areas.API.Controllers
{
Paste.Models.Paste paste = PasteHelper.CreatePaste(model.code, model.title, model.syntax, model.expireUnit, model.expireLength, model.password, model.hide);
// Associate this with the user if they provided an auth key
if (!string.IsNullOrEmpty(model.authToken))
// Associate this with the user if they are logged in
if (User.Identity.IsAuthenticated)
{
User foundUser = UserHelper.GetUserFromToken(db, model.authToken);
User foundUser = UserHelper.GetUser(db, User.Identity.Name);
if (foundUser != null)
{
paste.UserId = foundUser.UserId;
@ -228,10 +230,10 @@ namespace Teknik.Areas.API.Controllers @@ -228,10 +230,10 @@ namespace Teknik.Areas.API.Controllers
{
ShortenedUrl newUrl = Shortener.Shortener.ShortenUrl(model.url, Config.ShortenerConfig.UrlLength);
// Associate this with the user if they provided an auth key
if (!string.IsNullOrEmpty(model.authToken))
// Associate this with the user if they are logged in
if (User.Identity.IsAuthenticated)
{
User foundUser = UserHelper.GetUserFromToken(db, model.authToken);
User foundUser = UserHelper.GetUser(db, User.Identity.Name);
if (foundUser != null)
{
newUrl.UserId = foundUser.UserId;

6
Teknik/Areas/API/Models/APIv1BaseModel.cs

@ -9,15 +9,9 @@ namespace Teknik.Areas.API.Models @@ -9,15 +9,9 @@ namespace Teknik.Areas.API.Models
{
public bool doNotTrack { get; set; }
public string username { get; set; }
public string authToken { get; set; }
public APIv1BaseModel()
{
doNotTrack = false;
username = string.Empty;
authToken = string.Empty;
}
}
}

2
Teknik/Areas/About/Controllers/AboutController.cs

@ -4,11 +4,13 @@ using System.Linq; @@ -4,11 +4,13 @@ using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.About.ViewModels;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
namespace Teknik.Areas.About.Controllers
{
[TeknikAuthorize]
public class AboutController : DefaultController
{
[AllowAnonymous]

2
Teknik/Areas/Blog/Controllers/BlogController.cs

@ -14,9 +14,11 @@ using Teknik.Controllers; @@ -14,9 +14,11 @@ using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Utilities;
using Teknik.Models;
using Teknik.Attributes;
namespace Teknik.Areas.Blog.Controllers
{
[TeknikAuthorize]
public class BlogController : DefaultController
{
private TeknikEntities db = new TeknikEntities();

2
Teknik/Areas/Contact/Controllers/ContactController.cs

@ -10,9 +10,11 @@ using Teknik.Areas.Contact.Models; @@ -10,9 +10,11 @@ using Teknik.Areas.Contact.Models;
using Teknik.Models;
using System.Text;
using Teknik.Filters;
using Teknik.Attributes;
namespace Teknik.Areas.Contact.Controllers
{
[TeknikAuthorize]
public class ContactController : DefaultController
{
private TeknikEntities db = new TeknikEntities();

2
Teknik/Areas/Dev/Controllers/DevController.cs

@ -3,12 +3,14 @@ using System.Collections.Generic; @@ -3,12 +3,14 @@ using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Utilities;
namespace Teknik.Areas.Dev.Controllers
{
[TeknikAuthorize]
public class DevController : DefaultController
{
[TrackPageView]

30
Teknik/Areas/Error/Controllers/ErrorController.cs

@ -10,9 +10,11 @@ using Teknik.Controllers; @@ -10,9 +10,11 @@ using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Utilities;
using Teknik.Logging;
using Teknik.Attributes;
namespace Teknik.Areas.Error.Controllers
{
[TeknikAuthorize]
public class ErrorController : DefaultController
{
[TrackPageView]
@ -69,7 +71,33 @@ namespace Teknik.Areas.Error.Controllers @@ -69,7 +71,33 @@ namespace Teknik.Areas.Error.Controllers
return View("~/Areas/Error/Views/Error/General.cshtml", model);
}
[AllowAnonymous]
public ActionResult Http401(Exception exception)
{
ViewBag.Title = "401 - " + Config.Title;
ViewBag.Description = "Unauthorized";
if (Response != null)
{
Response.StatusCode = 401;
Response.TrySkipIisCustomErrors = true;
}
string errorMessage = "Unauthorized";
if (Request != null && Request.Url != null)
{
errorMessage += " for page: " + Request.Url.AbsoluteUri;
}
Logger.WriteEntry(LogLevel.Error, errorMessage, exception);
ErrorViewModel model = new ErrorViewModel();
model.Exception = exception;
return View("~/Areas/Error/Views/Error/Http401.cshtml", model);
}
[AllowAnonymous]
public ActionResult Http403(Exception exception)
{

28
Teknik/Areas/Error/Views/Error/Http401.cshtml

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
@model Teknik.Areas.Error.ViewModels.ErrorViewModel
@using Teknik.Utilities
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="error-template text-center">
<h2>401 Unauthorized</h2>
<div class="error-details">
The request has not been applied because it lacks valid authentication credentials for the target resource.
</div>
<br />
<div class="error-actions">
<a href="@Url.SubRouteUrl("www", "Home.Index")" class="btn btn-primary btn-lg">
<span class="glyphicon glyphicon-home"></span>
Take Me Home
</a>
<a href="@Url.SubRouteUrl("contact", "Contact.Index")" class="btn btn-default btn-lg">
<span class="glyphicon glyphicon-envelope"></span>
Contact Support
</a>
</div>
</div>
</div>
</div>
</div>

2
Teknik/Areas/Help/Controllers/HelpController.cs

@ -4,11 +4,13 @@ using System.Linq; @@ -4,11 +4,13 @@ using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.Help.ViewModels;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
namespace Teknik.Areas.Help.Controllers
{
[TeknikAuthorize]
public class HelpController : DefaultController
{
// GET: Help/Help

22
Teknik/Areas/Help/Views/Help/API/API.cshtml

@ -5,6 +5,10 @@ @@ -5,6 +5,10 @@
@Styles.Render("~/Content/help");
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">API</a></li>
</ol>
<div class="row api">
<div class="col-sm-4">
<h3><b>API Versions</b></h3>
@ -13,7 +17,7 @@ @@ -13,7 +17,7 @@
<ul class="list-unstyled">
<li><a href="@Url.SubRouteUrl("help", "Help.API", new { version = "v1", service = "Upload" })">Upload Service</a></li>
<li><a href="@Url.SubRouteUrl("help", "Help.API", new { version = "v1", service = "Paste" })">Paste Service</a></li>
<li><a href="@Url.SubRouteUrl("help", "Help.API", new { version = "v1", service = "Shorten" })">Url Shortening Service</a></li>
<li><a href="@Url.SubRouteUrl("help", "Help.API", new { version = "v1", service = "Shorten" })">Url Shortening</a></li>
</ul>
</p>
</div>
@ -26,6 +30,22 @@ @@ -26,6 +30,22 @@
<br />
The general API calls can be summarized as follows: <code>@Url.SubRouteUrl("api", "Api.Index")v@(Model.Config.ApiConfig.Version)/<b>Service</b>/<b>Action</b></code>
</p>
<h3>Basic Authentication</h3>
<p>
For some services, you may be required to authenticate to access them, or to associate generated content with your account. In all cases, the same authentication method is used.
<br />
<br />
<h4>Generating Authentication Tokens</h4>
To generate a new authentication token, navigate to your <a href="@Url.SubRouteUrl("user", "User.Settings")">user profile</a> and click the <b>Security</b> tab. There, you can manage your existing tokens and generate new ones.
<br />
<br />
<h4>Using the Authentication Tokens</h4>
To use Basic Authentication with your token, simply send the username and token.
<br />
<br />
For example, if you're accessing the API via cURL, the following command would associate the create paste with your account. Just replace <code>&lt;username&gt;</code> with your Teknik username and <code>&lt;token&gt;</code> with your token.
<pre><code>$ curl -u &lt;username&gt;:&lt;token&gt; --data code="Test" @Url.SubRouteUrl("api", "API.v1.Paste")</code></pre>
</p>
<h3>Responses</h3>
<p>
All responses are returned as json. The returned json can contain any of the following sections.

33
Teknik/Areas/Help/Views/Help/API/v1/Paste.cshtml

@ -6,12 +6,45 @@ @@ -6,12 +6,45 @@
@Styles.Render("~/Content/help");
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li><a href="@Url.SubRouteUrl("help", "Help.API", new { version = string.Empty, service = string.Empty })">API</a></li>
<li>v1</li>
<li class="active"><a href="#">Paste Service</a></li>
</ol>
<div class="row api">
<h2><b>Paste Service</b></h2>
<hr>
<p>This is a description of the API commands available for the Paste service.</p>
<h3>Submit a Paste</h3>
<pre><code>POST @Url.SubRouteUrl("api", "API.v1.Paste")</code></pre>
<h4>Headers</h4>
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>Default Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>Authorize</code>
</td>
<td>
<code>Basic <i>Encoding.Base64</i>(&lt;username&gt;:&lt;token&gt;)</code>
</td>
<td>
<var>NULL</var>
</td>
<td>
Basic Authentication to associate the paste with your account.
</td>
</tr>
</tbody>
</table>
<h4>Parameters</h4>
<table>
<thead>

33
Teknik/Areas/Help/Views/Help/API/v1/Shorten.cshtml

@ -5,12 +5,45 @@ @@ -5,12 +5,45 @@
@Styles.Render("~/Content/help");
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li><a href="@Url.SubRouteUrl("help", "Help.API", new { version = string.Empty, service = string.Empty })">API</a></li>
<li>v1</li>
<li class="active"><a href="#">Url Shortening</a></li>
</ol>
<div class="row api">
<h2><b>Url Shortening Service</b></h2>
<hr>
<p>This is a description of the API commands available for the Url Shortening service.</p>
<h3>Shorten a Url</h3>
<pre><code>POST @Url.SubRouteUrl("api", "API.v1.Shortener")</code></pre>
<h4>Headers</h4>
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>Default Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>Authorize</code>
</td>
<td>
<code>Basic <i>Encoding.Base64</i>(&lt;username&gt;:&lt;token&gt;)</code>
</td>
<td>
<var>NULL</var>
</td>
<td>
Basic Authentication to associate the shortened url with your account.
</td>
</tr>
</tbody>
</table>
<h4>Parameters</h4>
<table>
<thead>

33
Teknik/Areas/Help/Views/Help/API/v1/Upload.cshtml

@ -5,12 +5,45 @@ @@ -5,12 +5,45 @@
@Styles.Render("~/Content/help");
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li><a href="@Url.SubRouteUrl("help", "Help.API", new { version = string.Empty, service = string.Empty })">API</a></li>
<li>v1</li>
<li class="active"><a href="#">Upload Service</a></li>
</ol>
<div class="row api">
<h2><b>Upload Service</b></h2>
<hr>
<p>This is a description of the API commands available for the Upload service.</p>
<h3>Upload a File</h3>
<pre><code>POST @Url.SubRouteUrl("api", "API.v1.Upload")</code></pre>
<h4>Headers</h4>
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>Default Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>Authorize</code>
</td>
<td>
<code>Basic <i>Encoding.Base64</i>(&lt;username&gt;:&lt;token&gt;)</code>
</td>
<td>
<var>NULL</var>
</td>
<td>
Basic Authentication to associate the upload with your account.
</td>
</tr>
</tbody>
</table>
<h4>Parameters</h4>
<table>
<thead>

6
Teknik/Areas/Help/Views/Help/Blog.cshtml

@ -1,6 +1,12 @@ @@ -1,6 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
@using Teknik.Utilities
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">Blogging</a></li>
</ol>
<div class="row">
<h2><b>Blogging</b></h2>
<hr>

6
Teknik/Areas/Help/Views/Help/Git.cshtml

@ -1,6 +1,12 @@ @@ -1,6 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
@using Teknik.Utilities
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">Git Repositories</a></li>
</ol>
<div class="row">
<h2><b>Git</b></h2>
<hr>

6
Teknik/Areas/Help/Views/Help/Irc.cshtml

@ -1,6 +1,12 @@ @@ -1,6 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
@using Teknik.Utilities
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">IRC Network</a></li>
</ol>
<div class="row">
<h2><b>IRC</b></h2>
<hr>

4
Teknik/Areas/Help/Views/Help/Mail.cshtml

@ -3,6 +3,10 @@ @@ -3,6 +3,10 @@
@using Teknik.Utilities
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">Mail Server</a></li>
</ol>
<div class="row">
<h2><b>Mail</b></h2>
<hr>

6
Teknik/Areas/Help/Views/Help/Markdown.cshtml

@ -1,6 +1,12 @@ @@ -1,6 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
@using Teknik.Utilities
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">Markdown</a></li>
</ol>
<div class="row">
<h2>Markdown Formatting</h2>
<p><a href="http://daringfireball.net/projects/markdown/" target="_blank">Markdown</a> turns plain text formatting into fancy HTML formatting.</p>

6
Teknik/Areas/Help/Views/Help/Mumble.cshtml

@ -1,6 +1,12 @@ @@ -1,6 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
@using Teknik.Utilities
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">Mumble Chat Server</a></li>
</ol>
<div class="row">
<h2><b>Mumble</b></h2>
<hr>

6
Teknik/Areas/Help/Views/Help/RSS.cshtml

@ -1,6 +1,12 @@ @@ -1,6 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
@using Teknik.Utilities
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">RSS Feeds</a></li>
</ol>
<div class="row">
<h2><b>RSS</b></h2>
<hr>

6
Teknik/Areas/Help/Views/Help/Tools.cshtml

@ -1,6 +1,12 @@ @@ -1,6 +1,12 @@
@model Teknik.Areas.Help.ViewModels.HelpViewModel
@using Teknik.Utilities
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">Tools</a></li>
</ol>
<div class="row">
<h2 class="text-center"><b>Tools Utilizing Teknik Services</b></h2>
<hr>

6
Teknik/Areas/Help/Views/Help/Upload.cshtml

@ -3,6 +3,10 @@ @@ -3,6 +3,10 @@
@using Teknik.Utilities
<div class="container">
<ol class="breadcrumb">
<li><a href="@Url.SubRouteUrl("help", "Help.Index")">Help Index</a></li>
<li class="active"><a href="#">Uploads</a></li>
</ol>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<h2 class="text-center"><b>Uploads</b></h2>
@ -14,7 +18,7 @@ @@ -14,7 +18,7 @@
When you using the web interface for uploads, the file is loaded using the javascript <a href="https://developer.mozilla.org/en-US/docs/Web/API/FileReader">FileReader</a> API.
</p>
<p>
Once the file is completely loaded into the buffer, a key and iv are generated by a random string generator to create a key that is <b>@Model.Config.UploadConfig.KeySize Bytes</b> and an iv (Block Size) that is <b>@Model.Config.UploadConfig.BlockSize Bytes</b>.
Once the file is completely loaded into the buffer, a key and iv are generated by a random string generator to create a key that is <b>@Model.Config.UploadConfig.KeySize Bytes</b> and an iv (Block Size) that is <b>@Model.Config.UploadConfig.BlockSize Bytes</b>.
Then the file buffer, key, and iv are passed into a Web Worker for encryption.
</p>
<p>

2
Teknik/Areas/Home/Controllers/HomeController.cs

@ -10,9 +10,11 @@ using Teknik.Controllers; @@ -10,9 +10,11 @@ using Teknik.Controllers;
using Teknik.Utilities;
using Teknik.Models;
using Teknik.Filters;
using Teknik.Attributes;
namespace Teknik.Areas.Home.Controllers
{
[TeknikAuthorize]
public class HomeController : DefaultController
{
// GET: Home/Home

2
Teknik/Areas/Paste/Controllers/PasteController.cs

@ -14,9 +14,11 @@ using Teknik.Controllers; @@ -14,9 +14,11 @@ using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Utilities;
using Teknik.Models;
using Teknik.Attributes;
namespace Teknik.Areas.Paste.Controllers
{
[TeknikAuthorize]
public class PasteController : DefaultController
{
private TeknikEntities db = new TeknikEntities();

2
Teknik/Areas/Podcast/Controllers/PodcastController.cs

@ -8,6 +8,7 @@ using System.Web.Mvc; @@ -8,6 +8,7 @@ using System.Web.Mvc;
using Teknik.Areas.Podcast.Models;
using Teknik.Areas.Podcast.ViewModels;
using Teknik.Areas.Users.Utility;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Models;
@ -15,6 +16,7 @@ using Teknik.Utilities; @@ -15,6 +16,7 @@ using Teknik.Utilities;
namespace Teknik.Areas.Podcast.Controllers
{
[TeknikAuthorize]
public class PodcastController : DefaultController
{
private TeknikEntities db = new TeknikEntities();

2
Teknik/Areas/Privacy/Controllers/PrivacyController.cs

@ -4,11 +4,13 @@ using System.Linq; @@ -4,11 +4,13 @@ using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.Privacy.ViewModels;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
namespace Teknik.Areas.Privacy.Controllers
{
[TeknikAuthorize]
public class PrivacyController : DefaultController
{
// GET: Privacy/Privacy

2
Teknik/Areas/RSS/Controllers/RSSController.cs

@ -11,9 +11,11 @@ using Teknik.Controllers; @@ -11,9 +11,11 @@ using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Utilities;
using Teknik.Models;
using Teknik.Attributes;
namespace Teknik.Areas.RSS.Controllers
{
[TeknikAuthorize(AuthType.Basic)]
public class RSSController : DefaultController
{
private TeknikEntities db = new TeknikEntities();

2
Teknik/Areas/Shortener/Controllers/ShortenerController.cs

@ -6,6 +6,7 @@ using System.Web.Mvc; @@ -6,6 +6,7 @@ using System.Web.Mvc;
using Teknik.Areas.Shortener.Models;
using Teknik.Areas.Shortener.ViewModels;
using Teknik.Areas.Users.Utility;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Models;
@ -13,6 +14,7 @@ using Teknik.Utilities; @@ -13,6 +14,7 @@ using Teknik.Utilities;
namespace Teknik.Areas.Shortener.Controllers
{
[TeknikAuthorize]
public class ShortenerController : DefaultController
{
private TeknikEntities db = new TeknikEntities();

2
Teknik/Areas/Stream/Controllers/StreamController.cs

@ -5,11 +5,13 @@ using System.Net; @@ -5,11 +5,13 @@ using System.Net;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.Stream.ViewModels;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
namespace Teknik.Areas.Stream.Controllers
{
[TeknikAuthorize]
public class StreamController : DefaultController
{
[TrackPageView]

2
Teknik/Areas/TOS/Controllers/TOSController.cs

@ -4,11 +4,13 @@ using System.Linq; @@ -4,11 +4,13 @@ using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Areas.TOS.ViewModels;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
namespace Teknik.Areas.TOS.Controllers
{
[TeknikAuthorize]
public class TOSController : DefaultController
{
// GET: Privacy/Privacy

2
Teknik/Areas/Transparency/Controllers/TransparencyController.cs

@ -5,12 +5,14 @@ using System.Web; @@ -5,12 +5,14 @@ using System.Web;
using System.Web.Mvc;
using Teknik.Areas.Transparency.Models;
using Teknik.Areas.Transparency.ViewModels;
using Teknik.Attributes;
using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Models;
namespace Teknik.Areas.Transparency.Controllers
{
[TeknikAuthorize]
public class TransparencyController : DefaultController
{
private TeknikEntities db = new TeknikEntities();

2
Teknik/Areas/Upload/Controllers/UploadController.cs

@ -17,9 +17,11 @@ using Teknik.Controllers; @@ -17,9 +17,11 @@ using Teknik.Controllers;
using Teknik.Filters;
using Teknik.Utilities;
using Teknik.Models;
using Teknik.Attributes;
namespace Teknik.Areas.Upload.Controllers
{
[TeknikAuthorize]
public class UploadController : DefaultController
{
private TeknikEntities db = new TeknikEntities();

112
Teknik/Areas/User/Controllers/UserController.cs

@ -15,9 +15,11 @@ using Teknik.Filters; @@ -15,9 +15,11 @@ using Teknik.Filters;
using QRCoder;
using TwoStepsAuthenticator;
using System.Drawing;
using Teknik.Attributes;
namespace Teknik.Areas.Users.Controllers
{
[TeknikAuthorize]
public class UserController : DefaultController
{
private static readonly UsedCodesManager usedCodesManager = new UsedCodesManager();
@ -100,7 +102,16 @@ namespace Teknik.Areas.Users.Controllers @@ -100,7 +102,16 @@ namespace Teknik.Areas.Users.Controllers
model.UserID = user.UserId;
model.Username = user.Username;
model.TrustedDeviceCount = user.TrustedDevices.Count;
model.AuthTokens = user.AuthTokens.ToList();
model.AuthTokens = new List<AuthTokenViewModel>();
foreach (AuthToken token in user.AuthTokens)
{
AuthTokenViewModel tokenModel = new AuthTokenViewModel();
tokenModel.AuthTokenId = token.AuthTokenId;
tokenModel.Name = token.Name;
tokenModel.LastDateUsed = token.LastDateUsed;
model.AuthTokens.Add(tokenModel);
}
model.UserSettings = user.UserSettings;
model.SecuritySettings = user.SecuritySettings;
@ -788,7 +799,7 @@ namespace Teknik.Areas.Users.Controllers @@ -788,7 +799,7 @@ namespace Teknik.Areas.Users.Controllers
User user = UserHelper.GetUser(db, User.Identity.Name);
if (user != null)
{
string newTokenStr = UserHelper.GenerateAuthToken(Config, user.Username);
string newTokenStr = UserHelper.GenerateAuthToken(db, user.Username);
if (!string.IsNullOrEmpty(newTokenStr))
{
@ -796,11 +807,16 @@ namespace Teknik.Areas.Users.Controllers @@ -796,11 +807,16 @@ namespace Teknik.Areas.Users.Controllers
token.UserId = user.UserId;
token.HashedToken = SHA256.Hash(newTokenStr);
token.Name = name;
token.LastDateUsed = DateTime.Now;
db.AuthTokens.Add(token);
db.SaveChanges();
return Json(new { result = newTokenStr });
AuthTokenViewModel model = new AuthTokenViewModel();
model.AuthTokenId = token.AuthTokenId;
model.Name = token.Name;
model.LastDateUsed = token.LastDateUsed;
return Json(new { result = new { token = newTokenStr, html = PartialView("~/Areas/User/Views/User/AuthToken.cshtml", model).RenderToString() } });
}
return Json(new { error = "Unable to generate Auth Token" });
}
@ -811,5 +827,93 @@ namespace Teknik.Areas.Users.Controllers @@ -811,5 +827,93 @@ namespace Teknik.Areas.Users.Controllers
return Json(new { error = ex.GetFullMessage(true) });
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RevokeAllTokens()
{
try
{
User user = UserHelper.GetUser(db, User.Identity.Name);
if (user != null)
{
user.AuthTokens.Clear();
List<AuthToken> foundTokens = db.AuthTokens.Where(d => d.UserId == user.UserId).ToList();
if (foundTokens != null)
{
foreach (AuthToken token in foundTokens)
{
db.AuthTokens.Remove(token);
}
}
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return Json(new { result = true });
}
return Json(new { error = "User does not exist" });
}
catch (Exception ex)
{
return Json(new { error = ex.GetFullMessage(true) });
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditTokenName(int tokenId, string name)
{
try
{
User user = UserHelper.GetUser(db, User.Identity.Name);
if (user != null)
{
AuthToken foundToken = db.AuthTokens.Where(d => d.UserId == user.UserId && d.AuthTokenId == tokenId).FirstOrDefault();
if (foundToken != null)
{
foundToken.Name = name;
db.Entry(foundToken).State = EntityState.Modified;
db.SaveChanges();
return Json(new { result = new { name = name } });
}
return Json(new { error = "Authentication Token does not exist" });
}
return Json(new { error = "User does not exist" });
}
catch (Exception ex)
{
return Json(new { error = ex.GetFullMessage(true) });
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DeleteToken(int tokenId)
{
try
{
User user = UserHelper.GetUser(db, User.Identity.Name);
if (user != null)
{
AuthToken foundToken = db.AuthTokens.Where(d => d.UserId == user.UserId && d.AuthTokenId == tokenId).FirstOrDefault();
if (foundToken != null)
{
db.AuthTokens.Remove(foundToken);
user.AuthTokens.Remove(foundToken);
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return Json(new { result = true });
}
return Json(new { error = "Authentication Token does not exist" });
}
return Json(new { error = "User does not exist" });
}
catch (Exception ex)
{
return Json(new { error = ex.GetFullMessage(true) });
}
}
}
}

2
Teknik/Areas/User/Models/AuthToken.cs

@ -20,6 +20,6 @@ namespace Teknik.Areas.Users.Models @@ -20,6 +20,6 @@ namespace Teknik.Areas.Users.Models
[CaseSensitive]
public string HashedToken { get; set; }
public DateTime LastDateUsed { get; set; }
public DateTime? LastDateUsed { get; set; }
}
}

81
Teknik/Areas/User/Scripts/User.js

@ -102,11 +102,21 @@ @@ -102,11 +102,21 @@
success: function (response) {
if (response.result) {
bootbox.dialog({
closeButton: false,
buttons: {
close: {
label: 'Close',
className: 'btn-primary',
callback: function () {
if ($('#noAuthTokens')) {
$('#noAuthTokens').remove();
}
$('#authTokenList').append(response.result.html);
}
}
},
title: "Authentication Token",
message: '<label for="authToken">Make sure to copy your new personal access token now.<br />You won\'t be able to see it again!</label><input type="text" class="form-control" id="authToken" onClick="this.select();" value="' + response.result + '">',
callback: function () {
window.location.reload();
}
message: '<label for="authToken">Make sure to copy your new personal access token now.<br />You won\'t be able to see it again!</label><input type="text" class="form-control" id="authToken" onClick="this.select();" value="' + response.result.token + '">',
});
}
else {
@ -135,7 +145,7 @@ @@ -135,7 +145,7 @@
data: AddAntiForgeryToken({}),
success: function (response) {
if (response.result) {
window.location.reload();
$('#authTokenList').html('<li class="list-group-item text-center" id="noAuthTokens">No Authentication Tokens</li>');
}
else {
errorMsg = response;
@ -299,4 +309,63 @@ @@ -299,4 +309,63 @@
});
return false;
});
});
});
function editAuthToken(authTokenId) {
bootbox.prompt("Specify a new name for this Auth Token", function (result) {
if (result) {
$.ajax({
type: "POST",
url: editTokenNameURL,
data: AddAntiForgeryToken({ tokenId: authTokenId, name: result }),
success: function (response) {
if (response.result) {
$('#authTokenName_' + authTokenId).html(response.result.name);
}
else {
errorMsg = response;
if (response.error) {
errorMsg = response.error;
if (response.error.message) {
errorMsg = response.error.message;
}
}
$("#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">&times;</button>' + errorMsg + '</div>');
}
}
});
}
});
}
function deleteAuthToken(authTokenId) {
bootbox.confirm("Are you sure you want to revoke this auth token?<br /><br />This is <b>irreversable</b> and all applications using this token will stop working.", function (result) {
if (result) {
$.ajax({
type: "POST",
url: deleteTokenURL,
data: AddAntiForgeryToken({ tokenId: authTokenId }),
success: function (response) {
if (response.result) {
$('#authToken_' + authTokenId).remove();
if ($('#authTokenList li').length <= 0) {
$('#authTokenList').html('<li class="list-group-item text-center" id="noAuthTokens">No Authentication Tokens</li>');
}
}
else {
errorMsg = response;
if (response.error) {
errorMsg = response.error;
if (response.error.message) {
errorMsg = response.error.message;
}
}
$("#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">&times;</button>' + errorMsg + '</div>');
}
}
});
}
});
}

105
Teknik/Areas/User/Utility/UserHelper.cs

@ -134,15 +134,27 @@ namespace Teknik.Areas.Users.Utility @@ -134,15 +134,27 @@ namespace Teknik.Areas.Users.Utility
}
}
public static string GenerateAuthToken(Config config, string username)
public static string GenerateAuthToken(TeknikEntities db, string username)
{
try
{
username = username.ToLower();
byte[] hashBytes = SHA384.Hash(username, StringHelper.RandomString(24));
string hash = hashBytes.ToHex();
bool validToken = false;
string token = string.Empty;
while (!validToken)
{
username = username.ToLower();
byte[] hashBytes = SHA384.Hash(username, StringHelper.RandomString(24));
token = hashBytes.ToHex();
return hash;
// Make sure it isn't a duplicate
string hashedToken = SHA256.Hash(token);
if (!db.AuthTokens.Where(t => t.HashedToken == hashedToken).Any())
{
validToken = true;
}
}
return token;
}
catch (Exception ex)
{
@ -228,11 +240,14 @@ namespace Teknik.Areas.Users.Utility @@ -228,11 +240,14 @@ namespace Teknik.Areas.Users.Utility
return user;
}
public static User GetUserFromToken(TeknikEntities db, string token)
public static User GetUserFromToken(TeknikEntities db, string username, string token)
{
string hashedToken = SHA256.Hash(token);
User foundUser = db.Users.FirstOrDefault(u => u.AuthTokens.Select(a => a.HashedToken).Contains(hashedToken));
return foundUser;
if (token != null && !string.IsNullOrEmpty(username))
{
string hashedToken = SHA256.Hash(token);
return db.Users.FirstOrDefault(u => u.AuthTokens.Select(a => a.HashedToken).Contains(hashedToken) && u.Username == username);
}
return null;
}
public static bool UserExists(TeknikEntities db, string username)
@ -263,6 +278,25 @@ namespace Teknik.Areas.Users.Utility @@ -263,6 +278,25 @@ namespace Teknik.Areas.Users.Utility
}
}
public static void UpdateTokenLastUsed(TeknikEntities db, string username, string token, DateTime lastUsed)
{
User foundUser = GetUser(db, username);
if (foundUser != null)
{
string hashedToken = SHA256.Hash(token);
List<AuthToken> tokens = foundUser.AuthTokens.Where(t => t.HashedToken == hashedToken).ToList();
if (tokens != null)
{
foreach (AuthToken foundToken in tokens)
{
foundToken.LastDateUsed = lastUsed;
db.Entry(foundToken).State = EntityState.Modified;
}
db.SaveChanges();
}
}
}
public static bool UserPasswordCorrect(TeknikEntities db, Config config, User user, string password)
{
try
@ -276,6 +310,59 @@ namespace Teknik.Areas.Users.Utility @@ -276,6 +310,59 @@ namespace Teknik.Areas.Users.Utility
}
}
public static bool UserTokenCorrect(TeknikEntities db, string username, string token)
{
User foundUser = GetUserFromToken(db, username, token);
if (foundUser != null)
{
return true;
}
return false;
}
public static bool UserHasRoles(TeknikEntities db, User user, params string[] roles)
{
bool hasRole = true;
if (user != null)
{
// Check if they have the role specified
if (roles.Any())
{
foreach (string role in roles)
{
if (!string.IsNullOrEmpty(role))
{
if (user.Groups.Where(g => g.Roles.Where(r => role == r.Name).Any()).Any())
{
// They have the role!
return true;
}
else
{
// They don't have this role, so let's reset the hasRole
hasRole = false;
}
}
else
{
// Only set this if we haven't failed once already
hasRole &= true;
}
}
}
else
{
// No roles to check, so they pass!
return true;
}
}
else
{
hasRole = false;
}
return hasRole;
}
public static void TransferUser(TeknikEntities db, Config config, User user, string password)
{
try

17
Teknik/Areas/User/ViewModels/AuthTokenViewModel.cs

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Teknik.ViewModels;
namespace Teknik.Areas.Users.ViewModels
{
public class AuthTokenViewModel : ViewModelBase
{
public int AuthTokenId { get; set; }
public string Name { get; set; }
public DateTime? LastDateUsed { get; set; }
}
}

2
Teknik/Areas/User/ViewModels/SettingsViewModel.cs

@ -15,7 +15,7 @@ namespace Teknik.Areas.Users.ViewModels @@ -15,7 +15,7 @@ namespace Teknik.Areas.Users.ViewModels
public int TrustedDeviceCount { get; set; }
public List<AuthToken> AuthTokens { get; set; }
public List<AuthTokenViewModel> AuthTokens { get; set; }
public UserSettings UserSettings { get; set; }

17
Teknik/Areas/User/Views/User/AuthToken.cshtml

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
@model Teknik.Areas.Users.ViewModels.AuthTokenViewModel
<li class="list-group-item" id="authToken_@Model.AuthTokenId">
<div class="btn-group btn-group-sm pull-right" role="group" aria-label="...">
<button type="button" class="btn btn-default" onclick="editAuthToken(@Model.AuthTokenId)">Edit</button>
<button type="button" class="btn btn-danger text-danger" onclick="deleteAuthToken(@Model.AuthTokenId)">Delete</button>
</div>
<h4 class="list-group-item-heading" id="authTokenName_@Model.AuthTokenId">@Model.Name</h4>
@if (Model.LastDateUsed.HasValue)
{
<p class="list-group-item-text">Last Used on <i><time datetime="@Model.LastDateUsed.Value.ToString("s")">@Model.LastDateUsed.Value.ToString("MMMM dd, yyyy hh:mm tt")</time></i></p>
}
else
{
<p class="list-group-item-text">Last Used <i>Never</i></p>
}
</li>

23
Teknik/Areas/User/Views/User/Settings.cshtml

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
@model Teknik.Areas.Users.ViewModels.SettingsViewModel
@using Teknik.Utilities
@using Teknik.Areas.Users.Models
@using Teknik.Areas.Users.ViewModels
<script>
var homeUrl = '@Url.SubRouteUrl("www", "Home.Index")';
@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
var clearTrustedDevicesURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "ClearTrustedDevices" })';
var generateTokenURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "GenerateToken" })';
var revokeAllTokensURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "RevokeAllTokens" })';
var editTokenName = '@Url.SubRouteUrl("user", "User.Action", new { action = "EditTokenName" })';
var editTokenNameURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "EditTokenName" })';
var deleteTokenURL = '@Url.SubRouteUrl("user", "User.Action", new { action = "DeleteToken" })';
</script>
@ -181,26 +181,19 @@ @@ -181,26 +181,19 @@
</div>
<div class="col-sm-8">
<br />
<label for="authCodes"><h4>Authentication Tokens</h4></label><span class="pull-right"><button type="button" class="btn btn-default" id="generate_token">Generate Token</button> <button type="button" class="btn btn-danger" id="revoke_all_tokens">Revoke All</button></span>
<div id="authCodes" style="overflow-y: auto; max-height: 400px;">
<ul class="list-group">
<label for="authTokens"><h4>Authentication Tokens</h4></label><span class="pull-right"><button type="button" class="btn btn-default" id="generate_token">Generate Token</button> <button type="button" class="btn btn-danger" id="revoke_all_tokens">Revoke All</button></span>
<div id="authTokens" style="overflow-y: auto; max-height: 400px;">
<ul class="list-group" id="authTokenList">
@if (Model.AuthTokens.Any())
{
foreach (AuthToken token in Model.AuthTokens)
foreach (AuthTokenViewModel token in Model.AuthTokens)
{
<li class="list-group-item">
<div class="btn-group btn-group-sm pull-right" role="group" aria-label="...">
<button type="button" class="btn btn-default">Edit</button>
<button type="button" class="btn btn-danger text-danger">Delete</button>
</div>
<h4 class="list-group-item-heading" id="update_auth_token_name">@token.Name</h4>
<p class="list-group-item-text">Last Used on <time datetime="@token.LastDateUsed.ToString("s")">@token.LastDateUsed.ToString("MMMM dd, yyyy hh:mm tt")</time></p>
</li>
@Html.Partial("AuthToken", token)
}
}
else
{
<li class="list-group-item text-center">No Auth Codes</li>
<li class="list-group-item text-center" id="noAuthTokens">No Authentication Tokens</li>
}
</ul>
</div>

2
Teknik/Areas/Vault/Controllers/VaultController.cs

@ -3,10 +3,12 @@ using System.Collections.Generic; @@ -3,10 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Teknik.Attributes;
using Teknik.Controllers;
namespace Teknik.Areas.Vault.Controllers
{
[TeknikAuthorize]
public class VaultController : DefaultController
{
[AllowAnonymous]

148
Teknik/Attributes/TeknikAuthorizeAttribute.cs

@ -7,12 +7,33 @@ using System.Web.Routing; @@ -7,12 +7,33 @@ using System.Web.Routing;
using Teknik.Areas.Error.Controllers;
using Teknik.Utilities;
using Teknik.Areas.Users.Controllers;
using Teknik.Models;
using Teknik.Areas.Users.Utility;
using Teknik.Areas.Users.Models;
using Teknik.Configuration;
namespace Teknik.Attributes
{
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public enum AuthType
{
Basic,
Forms
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class TeknikAuthorizeAttribute : AuthorizeAttribute
{
private AuthType m_AuthType { get; set; }
public TeknikAuthorizeAttribute() : this(AuthType.Forms)
{
}
public TeknikAuthorizeAttribute(AuthType authType)
{
m_AuthType = authType;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
@ -36,7 +57,7 @@ namespace Teknik.Attributes @@ -36,7 +57,7 @@ namespace Teknik.Attributes
return;
// Check the users auth
if (base.AuthorizeCore(filterContext.HttpContext))
if (AuthorizeCore(filterContext.HttpContext))
{
// ** IMPORTANT **
// Since we're performing authorization at the action level, the authorization code runs
@ -54,7 +75,7 @@ namespace Teknik.Attributes @@ -54,7 +75,7 @@ namespace Teknik.Attributes
}
else if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
this.HandleUnauthorizedRequest(filterContext);
HandleUnauthorizedRequest(filterContext);
}
else
{
@ -63,34 +84,119 @@ namespace Teknik.Attributes @@ -63,34 +84,119 @@ namespace Teknik.Attributes
}
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
protected override bool AuthorizeCore(HttpContextBase httpContext)
<