175 lines
6.5 KiB
C#
175 lines
6.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Http.Headers;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
using System.Web.Http.Controllers;
|
|
using System.Web.Http.Filters;
|
|
using Kreta.BusinessLogic.Classes.MobileApi.Common.Co;
|
|
using Kreta.BusinessLogic.Classes.MobileApi.Common.Enum;
|
|
using Kreta.Web.Configuration;
|
|
|
|
namespace Kreta.Web.Areas.MobileApi.Attributes
|
|
{
|
|
// <summary>
|
|
/// Authorization filter attribute
|
|
/// </summary>
|
|
/// <seealso cref="System.Web.Http.Filters.AuthorizationFilterAttribute" />
|
|
class MobileApiAuthorizationAttribute : AuthorizationFilterAttribute, IOverrideFilter
|
|
{
|
|
/// <summary>
|
|
/// Institute code
|
|
/// </summary>
|
|
const string InstituteCode = nameof(InstituteCode);
|
|
|
|
/// <summary>
|
|
/// Gets the API key.
|
|
/// </summary>
|
|
const string ApiKey = nameof(ApiKey);
|
|
|
|
/// <summary>
|
|
/// User Id
|
|
/// </summary>
|
|
const string UserId = nameof(UserId);
|
|
|
|
/// <summary>
|
|
/// Tutelary Id
|
|
/// </summary>
|
|
const string TutelaryId = nameof(TutelaryId);
|
|
|
|
/// <summary>
|
|
/// User roles
|
|
/// </summary>
|
|
const string UserRoles = nameof(UserRoles);
|
|
|
|
const string SchoolYearId = nameof(SchoolYearId);
|
|
|
|
/// <summary>
|
|
/// Gets the filters to override.
|
|
/// </summary>
|
|
public Type FiltersToOverride
|
|
{
|
|
get
|
|
{
|
|
return typeof(IAuthorizationFilter);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validating api key
|
|
/// </summary>
|
|
/// <param name="apiKeyHeader">Header item, contains api key</param>
|
|
/// <returns>true, if api key is valid (access granted)</returns>
|
|
private bool AccessGratnedByApiKey(KeyValuePair<string, IEnumerable<string>> apiKeyHeader)
|
|
{
|
|
if (apiKeyHeader.Value != null)
|
|
{
|
|
string targetApiKey = apiKeyHeader.Value.SingleOrDefault();
|
|
|
|
if (!string.IsNullOrWhiteSpace(targetApiKey) && targetApiKey == MobileApiConfigurationSection.Instance.ApiKey)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get mobile user
|
|
/// </summary>
|
|
/// <param name="headers">Http headers</param>
|
|
/// <returns>Mobile user</returns>
|
|
private MobileUser GetMobileUser(HttpRequestHeaders headers)
|
|
{
|
|
var instituteCodeHeaderValue = headers.SingleOrDefault(x => x.Key.Equals(InstituteCode, StringComparison.InvariantCultureIgnoreCase)).Value?.SingleOrDefault();
|
|
|
|
var schoolYearIdHeaderValue = headers.SingleOrDefault(x => x.Key.Equals(SchoolYearId, StringComparison.InvariantCultureIgnoreCase)).Value?.SingleOrDefault();
|
|
int schoolYearId;
|
|
|
|
int userId;
|
|
var userIdHeaderValue = headers.SingleOrDefault(x => x.Key.Equals(UserId, StringComparison.InvariantCultureIgnoreCase)).Value?.SingleOrDefault();
|
|
|
|
if (userIdHeaderValue == null)
|
|
{
|
|
throw new InvalidOperationException($"\"{UserId}\" header value was not found");
|
|
}
|
|
|
|
if (!int.TryParse(userIdHeaderValue, out userId))
|
|
{
|
|
throw new InvalidOperationException($"Cannot parse \"{UserId}\" header value: \"{userIdHeaderValue}\"");
|
|
}
|
|
|
|
if (schoolYearIdHeaderValue == null)
|
|
{
|
|
throw new InvalidOperationException($"\"{SchoolYearId}\" header value was not found");
|
|
}
|
|
|
|
if (!int.TryParse(schoolYearIdHeaderValue, out schoolYearId))
|
|
{
|
|
throw new InvalidOperationException($"Cannot parse \"{SchoolYearId}\" header value: \"{schoolYearIdHeaderValue}\"");
|
|
}
|
|
|
|
int? tutelaryId = null;
|
|
var tutelaryIdHeaderValue = headers.SingleOrDefault(x => x.Key.Equals(TutelaryId, StringComparison.InvariantCultureIgnoreCase)).Value?.SingleOrDefault() ?? string.Empty;
|
|
|
|
if (tutelaryIdHeaderValue == null)
|
|
{
|
|
throw new InvalidOperationException($"\"{TutelaryId}\" header value was not found");
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(tutelaryIdHeaderValue.Trim()))
|
|
{
|
|
int tutelaryId1;
|
|
if (!int.TryParse(tutelaryIdHeaderValue, out tutelaryId1))
|
|
{
|
|
throw new InvalidOperationException($"Cannot parse \"{TutelaryId}\" header value: \"{tutelaryIdHeaderValue}\"");
|
|
}
|
|
tutelaryId = tutelaryId1;
|
|
}
|
|
|
|
var userRolesHeaderValue = headers.SingleOrDefault(x => x.Key.Equals(UserRoles, StringComparison.InvariantCultureIgnoreCase)).Value?.SingleOrDefault();
|
|
|
|
if (userRolesHeaderValue == null)
|
|
{
|
|
throw new InvalidOperationException($"\"{UserRoles}\" header value was not found");
|
|
}
|
|
|
|
List<MobileUserRole> userRoles = new List<MobileUserRole>();
|
|
foreach (string userRoleHeaderValue in userRolesHeaderValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
|
{
|
|
MobileUserRole userRole;
|
|
if (!Enum.TryParse(userRoleHeaderValue, out userRole))
|
|
{
|
|
throw new InvalidOperationException($"\"{userRoleHeaderValue}\" is not a valid user role");
|
|
}
|
|
userRoles.Add(userRole);
|
|
}
|
|
|
|
return new MobileUser(instituteCodeHeaderValue, userId, tutelaryId, userRoles, schoolYearId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Authorization event
|
|
/// </summary>
|
|
/// <param name="actionContext">Context of the current action</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
|
|
{
|
|
var headers = actionContext.Request.Headers;
|
|
|
|
var apiKeyHeader = headers.SingleOrDefault(x => x.Key.Equals(ApiKey, StringComparison.InvariantCultureIgnoreCase));
|
|
|
|
if (!AccessGratnedByApiKey(apiKeyHeader))
|
|
{
|
|
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
|
|
}
|
|
|
|
HttpContext.Current?.Items?.Add(nameof(MobileUser), GetMobileUser(headers));
|
|
|
|
return Task.FromResult(0);
|
|
}
|
|
}
|
|
}
|