public override Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context) => Task.Run(() => { //potential bug: capturing this datacontext is dangerous because if the cache gets invalidated and this logon is requested, //the datacontext will MOST LIKELY be disposed when it is queried for the logon. //The solution is to find a way to get at the current owin context, to get a fresh db context from there. var _dataContext = context.OwinContext.GetPerRequestValue <IDataContext>(nameof(IDataContext)); //cache the logon associated to the given token _cache.GetOrAdd(context.AccessToken, _token => { var agent = Parser.Parse(context.Request.Headers.Get("User-Agent")); var _l = _dataContext.Store <UserLogon>() .QueryWith(_ul => _ul.User) .Where(_ul => _ul.User.EntityId == context.Identity.Name) .Where(_ul => _ul.OwinToken == _token) //get the bearer token from the header .FirstOrDefault(); if (_l != null) { return(_l); } else { _l = new UserLogon { UserId = context.Identity.Name, Client = new Core.Models.UserAgent { OS = agent.OS.Family, OSVersion = $"{agent.OS.Major}.{agent.OS.Minor}", Browser = agent.UserAgent.Family, BrowserVersion = $"{agent.UserAgent.Major}.{agent.UserAgent.Minor}", Device = $"{agent.Device.Family}" }, OwinToken = _token, Location = null, ModifiedOn = DateTime.Now }; _dataContext.Store <UserLogon>().Add(_l).Context.CommitChanges(); return(_l); } }); });
/// <summary> /// This method is faster than the <c>CurrentProcessPermissionProfile</c> because it doesnt rely on the StackTrace method anymore. The downside of this /// is that the method it needs to get the resource from on the service specified cannot be an overloaded method. /// </summary> /// <typeparam name="Service">The service type whose method has been decorated with the <c>Axis.Pollux.RBAC.Auth.ResourceAttribute</c></typeparam> /// <param name="context"></param> /// <returns></returns> public static PermissionProfile PermissionProfile <Service>(this Service service, User user, [CallerMemberName] string methodName = null) { var serviceType = typeof(Service); var resources = Cache.GetOrAdd($"{serviceType.MinimalAQName()}.{methodName}", _k => { var mi = serviceType.GetMethod(methodName); return(mi.GetResourceAttribute().SelectMany(ratt => ratt.Resources).ToList()); }); return(new PermissionProfile { Principal = user, ResourcePaths = resources }); }