Summary

Class:ProjectX.PublicApi.Filters.AuthContextAttribute
Assembly:ProjectX.PublicApi
File(s):C:\private\projects\projectx\backend\src\ProjectX.PublicApi\Filters\AuthContextAttribute.cs
Covered lines:34
Uncovered lines:8
Coverable lines:42
Total lines:88
Line coverage:80.9%
Branch coverage:62.5%

History

Metrics

MethodCyclomatic complexity  NPath complexity  Sequence coverage  Branch coverage  
.ctor(...)10100100
OnActionExecuting(...)61672.7366.67

File(s)

C:\private\projects\projectx\backend\src\ProjectX.PublicApi\Filters\AuthContextAttribute.cs

#LineLine coverage
 1using System;
 2using System.Net;
 3using System.Security.Claims;
 4using System.Text;
 5using Microsoft.AspNetCore.Mvc;
 6using Microsoft.AspNetCore.Mvc.Filters;
 7using ProjectX.Stores;
 8
 9namespace ProjectX.PublicApi.Filters
 10{
 11    public class AuthContextAttribute : ActionFilterAttribute
 12    {
 13        private readonly IUserStore _userStore;
 14        private AppContext _appContext;
 15
 2116        public AuthContextAttribute(
 2117            IUserStore userStore,
 2118            AppContext appContext
 2119        )
 20        {
 2121            this._userStore = userStore;
 2122            this._appContext = appContext;
 2123        }
 24
 2125        public string BasicRealm { get; set; } = "None";
 26
 27        public override void OnActionExecuting(
 28            ActionExecutingContext actionExecutingContext)
 29        {
 2130            var req = actionExecutingContext.HttpContext.Request;
 2131             var auth = req.Headers.ContainsKey("Authorization") ?
 2132                req.Headers["Authorization"].ToString() : string.Empty;
 33
 2134             if (!String.IsNullOrEmpty(auth) &&
 2135                auth.ToLower().StartsWith("basic "))
 36            {
 2137                Guid userId = Guid.Empty;
 2138                string hash = null;
 39
 40                try
 41                {
 2142                    var r = Encoding.ASCII.GetString(
 2143                        Convert.FromBase64String(auth.Substring(6)))
 2144                            .Split(':');
 45
 2146                    userId = Guid.Parse(r[0]);
 2147                    hash = r[1];
 2148                }
 049                catch (Exception)
 50                {
 51                    // Something went wrong while parsing the auth header
 052                    actionExecutingContext.Result =
 053                        new BadRequestObjectResult("Error parsing auth header");
 54
 055                    return;
 56                }
 57
 2158                var user = this._userStore
 2159                    .LoadUserByCredentialsAsync(userId, hash).Result;
 60
 2161                 if (user != null)
 62                {
 63                    // Authenticate
 2064                    actionExecutingContext.HttpContext.User =
 2065                        new ClaimsPrincipal(new ClaimsIdentity(new Claim[] {
 2066                            new Claim("phone", user.Phone),
 2067                            new Claim("userId", user.Id.ToString())
 2068                    }, "Basic"));
 69
 70                    // Set ProjectX context
 2071                    _appContext.User = user;
 2072                }
 73                else
 74                {
 175                    actionExecutingContext.Result =
 176                        new StatusCodeResult((int)HttpStatusCode.Unauthorized);
 77                }
 78
 179                return;
 80            }
 81
 082            actionExecutingContext.HttpContext.Response.Headers
 083                .Add("WWW-Authenticate", $"Basic realm=\"{BasicRealm}\"");
 84
 085            actionExecutingContext.Result = new UnauthorizedResult();
 086        }
 87    }
 88}