Updated the claims so we can support more users.

Added a user management section (not yet complete)
Added the api to the solution and a api key in the settings (currently only gets the requests).
pull/226/head
TidusJar 8 years ago
parent 741a4ae75c
commit 98eadc9cc6

@ -43,6 +43,10 @@ namespace PlexRequests.Core.SettingModels
public bool UsersCanViewOnlyOwnRequests { get; set; }
public int WeeklyRequestLimit { get; set; }
public string NoApprovalUsers { get; set; }
public string ApiKey {
get;
set;
}
[JsonIgnore]
public List<string> ApprovalWhiteList

@ -64,6 +64,7 @@
<Compile Include="SerializerSettings.cs" />
<Compile Include="StringCipher.cs" />
<Compile Include="UriHelper.cs" />
<Compile Include="UserClaims.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

@ -0,0 +1,12 @@
using System;
namespace PlexRequests.Helpers
{
public class UserClaims
{
public const string Admin = "Admin";
public const string PowerUser = "PowerUser";
public const string User = "User";
}
}

@ -0,0 +1,12 @@
using System;
namespace PlexRequests.UI
{
public class ApiModel<T>
{
public T Data{ get; set; }
public bool Error{get;set;}
public string ErrorMessage{ get; set; }
}
}

@ -172,6 +172,8 @@ namespace PlexRequests.UI.Modules
Get["/headphones"] = _ => Headphones();
Post["/headphones"] = _ => SaveHeadphones();
Post ["/createapikey"] = x => CreateApiKey ();
}
private Negotiator Authentication()
@ -705,5 +707,20 @@ namespace PlexRequests.UI.Modules
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Headphones!" }
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
}
private Response CreateApiKey()
{
this.RequiresClaims (UserClaims.Admin);
var apiKey = Guid.NewGuid ().ToString ("N");
var settings = PrService.GetSettings ();
settings.ApiKey = apiKey;
PrService.SaveSettings (settings);
return Response.AsJson (apiKey);
}
}
}

@ -0,0 +1,71 @@
using System;
using PlexRequests.UI.Modules;
using Nancy;
using Nancy.Extensions;
using Nancy.ModelBinding;
using Nancy.Responses.Negotiation;
using Nancy.Validation;
using PlexRequests.Core;
using System.Collections.Generic;
using PlexRequests.Store;
using PlexRequests.Core.SettingModels;
namespace PlexRequests.UI.Modules
{
public class ApiModule : BaseModule
{
public ApiModule (IRequestService service, ISettingsService<PlexRequestSettings> settings) : base("api")
{
Get ["/requests"] = x => GetRequests ();
RequestService = service;
Settings = settings;
}
private IRequestService RequestService{ get; }
private ISettingsService<PlexRequestSettings> Settings{get;}
public Response GetRequests()
{
var apiModel = new ApiModel<List<RequestedModel>>{Data = new List<RequestedModel>()};
if (!Authenticated ()) {
apiModel.Error = true;
apiModel.ErrorMessage = "ApiKey is invalid or not present, Please use 'apikey' in the querystring.";
return ReturnReponse (apiModel);
}
var requests = RequestService.GetAll ();
apiModel.Data.AddRange (requests);
return ReturnReponse (apiModel);
}
private Response ReturnReponse(object result)
{
var queryString = (DynamicDictionary)Context.Request.Query;
dynamic value;
if (queryString.TryGetValue("xml", out value)) {
if ((bool)value) {
return Response.AsXml (result);
}
}
return Response.AsJson (result);
}
private bool Authenticated(){
var query = (DynamicDictionary)Context.Request.Query;
dynamic key;
if (!query.TryGetValue ("apikey", out key)) {
return false;
}
var settings = Settings.GetSettings ();
if ((string)key == settings.ApiKey) {
return true;
}
return false;
}
}
}

@ -77,7 +77,9 @@ namespace PlexRequests.UI.Modules
}
Session[SessionKeys.UsernameKey] = username;
Session[SessionKeys.ClientDateTimeOffsetKey] = dtOffset;
if(redirect.Contains("userlogin")){
redirect = !string.IsNullOrEmpty(BaseUrl) ? $"/{BaseUrl}/search" : "/search";
}
return this.LoginAndRedirect(userId.Value, expiry, redirect);
};

@ -0,0 +1,39 @@
using System;
using Nancy;
using Nancy.Authentication.Forms;
using Nancy.Extensions;
using Nancy.Responses.Negotiation;
using Nancy.Security;
using PlexRequests.Core;
using PlexRequests.UI.Models;
using PlexRequests.UI.Modules;
using PlexRequests.Helpers;
namespace PlexRequests.UI
{
public class UserManagementModule : BaseModule
{
public UserManagementModule () : base("usermanagement")
{
this.RequiresClaims (UserClaims.Admin);
Get["/"] = x => Load();
Get ["/users"] = x => LoadUsers ();
}
public Negotiator Load()
{
return View ["Index"];
}
public Response LoadUsers()
{
var users = UserMapper.GetUsers ();
return Response.AsJson (users);
}
}
}

@ -195,6 +195,12 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Startup.cs" />
<Compile Include="Validators\PlexRequestsValidator.cs" />
<Compile Include="Modules\UserManagementModule.cs" />
<Content Include="Views\UserManagement\Index.cshtml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Compile Include="Modules\ApiModule.cs" />
<Compile Include="Models\ApiModel.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Content\bootstrap.min.js">
@ -464,4 +470,7 @@
<Target Name="AfterBuild">
</Target>
-->
<ItemGroup>
<Folder Include="Views\UserManagement\" />
</ItemGroup>
</Project>

@ -17,6 +17,8 @@ namespace PlexRequests.UI
RuleFor (x => x.BaseUrl).NotEqual ("test").WithMessage ("You cannot use 'test' as this is reserved by the application.");
RuleFor (x => x.BaseUrl).NotEqual ("approval").WithMessage ("You cannot use 'approval' as this is reserved by the application.");
RuleFor (x => x.BaseUrl).NotEqual ("updatechecker").WithMessage ("You cannot use 'updatechecker' as this is reserved by the application.");
RuleFor (x => x.BaseUrl).NotEqual ("usermanagement").WithMessage ("You cannot use 'usermanagement' as this is reserved by the application.");
RuleFor (x => x.BaseUrl).NotEqual ("api").WithMessage ("You cannot use 'api' as this is reserved by the application.");

@ -42,6 +42,17 @@
</div>
<small class="control-label">You will have to restart after changing the url base.</small>
<div class="form-group">
<label for="ApiKey" class="control-label">Api Key</label>
<div class="input-group">
<input type="text" disabled="disabled" class="form-control form-control-custom" id="apiKey" name="ApiKey" value="@Model.ApiKey">
<div class="input-group-addon">
<div id="refreshKey" class="fa fa-refresh" title="Reset API Key"></div>
</div>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<label>
@ -202,5 +213,27 @@ $(function() {
}
});
});
$('#refreshKey').click(function (e) {
e.preventDefault();
var base = '@Html.GetBaseUrl()';
var url = createBaseUrl(base, '/admin/createapikey');
$.ajax({
type: "post",
url: url,
dataType: "json",
success: function (response) {
if (response) {
generateNotify("Success!", "success");
$('#apiKey').val(response);
}
},
error: function (e) {
console.log(e);
generateNotify("Something went wrong!", "danger");
}
});
});
});
</script>

@ -0,0 +1,14 @@
@using PlexRequests.UI.Helpers
@{
var baseUrl = Html.GetBaseUrl().ToHtmlString();
var url = string.Empty;
if (!string.IsNullOrEmpty(baseUrl))
{
url = "/" + baseUrl;
}
}
<h2>User Management</h2>
<button class="btn btn-success-outline" type="submit">Create User <div class="fa fa-plus"/></button>
Loading…
Cancel
Save