public async Task <RestReturnObj <UserToken> > UserAuthRequest(string apiResources, UserData userData)
        {
            HttpContent         content  = new StringContent(JsonConvert.SerializeObject(userData), Encoding.UTF8, "application/json");
            HttpResponseMessage response = await m_Client.PostAsync(UriPath.Combine(m_Uri, apiResources), content);

            if (!response.IsSuccessStatusCode)
            {
                return new RestReturnObj <UserToken> {
                           IsSuccess = false
                }
            }
            ;

            var str = await response.Content.ReadAsStringAsync();

            UserToken token = new UserToken();

            if (!String.IsNullOrWhiteSpace(str))
            {
                token = JsonConvert.DeserializeObject <UserToken>(str);
            }
            return(new RestReturnObj <UserToken> {
                IsSuccess = response.IsSuccessStatusCode,
                Obj = token
            });
        }
Esempio n. 2
0
        public RedirectResult Authorize()
        {
            // Generate a random 16char GUID nonce to validate on the callback
            var nonce = Guid.NewGuid().ToString().Replace("-", "");

            Memory.Set(nonce, nonce, new MemoryCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(Config.PathOfExileApi.NonceExpirySeconds),
                Size = nonce.Length
            });

            var authUri = UriPath.Combine(Config.PathOfExileApi.Route, "/OAuth/Authorize");

            var redirectUri = Url.Action("AuthorizeCallback", "OAuth", null, Request.Scheme);
            // Build up query params to append to the provided redirect Uri
            var queryParams = new Dictionary <string, string>
            {
                { "client_id", Config.PathOfExileApi.ClientId },
                { "response_type", "code" },
                { "scope", "profile" },
                { "redirect_uri", redirectUri },
                { "state", nonce }
            };

            var authQuery = QueryHelpers.AddQueryString(authUri, queryParams);

            return(Redirect(authQuery));
        }
        public async Task <RestReturnObj <PostedFoodMarkerRetObj> > PostFoodMarker(FoodMarker foodMarker)
        {
            HttpContent content = new StringContent(JsonConvert.SerializeObject(foodMarker), Encoding.UTF8,
                                                    "application/json");
            HttpResponseMessage responseMsg = await m_Client.PostAsync(UriPath.Combine(m_Uri, "FullFoodAndGeoData"),
                                                                       content);

            if (!responseMsg.IsSuccessStatusCode)
            {
                return new RestReturnObj <PostedFoodMarkerRetObj>()
                       {
                           IsSuccess = false
                       }
            }
            ;

            var response = await responseMsg.Content.ReadAsStringAsync();

            if (String.IsNullOrEmpty(response))
            {
                return(null);
            }

            PostedFoodMarkerRetObj ret =
                JsonConvert.DeserializeObject <PostedFoodMarkerRetObj>(response);

            return(new RestReturnObj <PostedFoodMarkerRetObj>
            {
                IsSuccess = responseMsg.IsSuccessStatusCode,
                Obj = ret
            });
        }
        public async Task <RestReturnObj <IEnumerable <FoodCategories> > > GetAllFoodCategories()
        {
            HttpResponseMessage responseMsg = await m_Client.GetAsync(UriPath.Combine(m_Uri, "FoodCategories"));

            if (!responseMsg.IsSuccessStatusCode)
            {
                return new RestReturnObj <IEnumerable <FoodCategories> > {
                           IsSuccess = false
                }
            }
            ;

            var response = await responseMsg.Content.ReadAsStringAsync();

            if (String.IsNullOrEmpty(response))
            {
                return(null);
            }

            IEnumerable <FoodCategories> ret =
                JsonConvert.DeserializeObject <IEnumerable <FoodCategories> >(response);

            return(new RestReturnObj <IEnumerable <FoodCategories> >
            {
                IsSuccess = responseMsg.IsSuccessStatusCode,
                Obj = ret
            });
        }
        public async Task <bool> IsTokenValid()
        {
            HttpContent         content  = new StringContent("");
            HttpResponseMessage response = await m_Client.PostAsync(UriPath.Combine(m_Uri, "Ping"), content);

            return(response.IsSuccessStatusCode);
        }
        private void TryFindPreviousPath(KeyValuePair <UriPath, IList <ApiPermissionType> > loopUp, IDictionary <UriPath, IList <ApiPermissionType> > processed)
        {
            UriPath             path     = loopUp.Key;
            int                 count    = path.Count;
            IList <PathSegment> segments = new List <PathSegment>();
            int                 skip     = 2;

            if (path.Segments[path.Count - 1].Kind != SegmentKind.Key)
            {
                skip = 1;
            }

            for (int i = 0; i < count - skip; i++)
            {
                // get rid of the "last key segment and last property (nav) segment)
                segments.Add(path.Segments[i]);
            }

            UriPath newPath = new UriPath(segments);

            string propertyName = loopUp.Key.LastSegment.UriLiteral;

            // find all target string is same as the loop target string (prefix)
            foreach (var foundItem in processed.Where(p => p.Key.EqualsTo(newPath)))
            {
                TryFindPreviousPath(foundItem, loopUp, propertyName);
            }
        }
Esempio n. 7
0
        private async Task <OAuthTokenEntity> EnsureUserAsync(string access_token)
        {
            var token = await DBContext.OAuthTokens.SingleOrDefaultAsync(t => t.Value == access_token && (t.Expiry == null || t.Expiry.Value > DateTime.Now));

            // User exists, short circuit out
            if (!string.IsNullOrEmpty(token?.UserId))
            {
                return(token);
            }

            var profileUri   = UriPath.Combine(Config.PathOfExileApi.Route, "/profile");
            var profileQuery = QueryHelpers.AddQueryString(profileUri, nameof(access_token), access_token);

            using var client   = new HttpClient();
            using var response = await client.GetAsync(profileQuery);

            if (!response.IsSuccessStatusCode)
            {
                throw new AuthenticationException(response.ReasonPhrase);
            }

            var contentRaw = await response.Content.ReadAsStringAsync();

            var profile = JsonConvert.DeserializeObject <ProfileResponse>(contentRaw);

            if (string.IsNullOrEmpty(profile?.Name))
            {
                throw new AuthenticationException();
            }

            var user = await UserManager.FindByNameAsync(profile.Name);

            if (user == null)
            {
                user = new UserEntity
                {
                    UserName = profile.Name,
                    Name     = profile.Name,
                    Realm    = profile.Realm,
                    UUID     = profile.UUID
                };

                var result = await UserManager.CreateAsync(user);

                if (!result.Succeeded)
                {
                    throw new AuthenticationException(result.Errors.First().Description);
                }
            }

            token = new OAuthTokenEntity
            {
                Value  = access_token,
                UserId = user.Id
            };

            return(token);
        }
Esempio n. 8
0
        public void Add(IDictionary <UriPath, IList <ApiPermissionType> > permissions)
        {
            IDictionary <string, IList <IRecord> > targetStringMerged = new Dictionary <string, IList <IRecord> >();

            foreach (var permission in permissions)
            {
                UriPath  path   = permission.Key;
                PathKind kind   = path.Kind;
                string   target = path.GetTargetString();

                IList <IRecord> records;
                if (!targetStringMerged.TryGetValue(target, out records))
                {
                    records = new List <IRecord>();
                    targetStringMerged[target] = records;
                }

                foreach (var perm in permission.Value)
                {
                    PermissionsRecord permissionRecord;
                    try
                    {
                        permissionRecord = ApiPermissionHelper.ConvertToRecord(kind, perm);

                        ReadRestrictionsType readRest = permissionRecord as ReadRestrictionsType;
                        if (readRest != null)
                        {
                            var existingReadRest = records.FirstOrDefault(r => r is ReadRestrictionsType);
                            if (existingReadRest != null)
                            {
                                MergeReadRest(existingReadRest as ReadRestrictionsType, readRest, target);
                                continue;
                            }
                        }

                        // TODO: verify only one Restriction existing for one target?

                        records.Add(permissionRecord as IRecord);
                    }
                    catch (Exception ex)
                    {
                        //var color = Console.BackgroundColor;
                        //Console.BackgroundColor = ConsoleColor.Red;
                        Console.WriteLine("    [PermssionError]: " + ex.Message);
                        //Console.BackgroundColor = color;

                        PermissionsError[target] = ex;
                    }
                }
            }

            foreach (var item in targetStringMerged)
            {
                Write(item.Key, item.Value);
            }
        }
Esempio n. 9
0
        public async Task <RedirectResult> AuthorizeCallback(string code, string state)
        {
            if (string.IsNullOrEmpty(state) || !Memory.TryGetValue(state, out _))
            {
                // Unrecognized Nonce, go back home
                return(BackToHome());
            }

            // Delete the nonce now, we are done with it
            Memory.Remove(state);

            // Check if we already recognize this code, if not, build it
            var codeEntity = await DBContext.OAuthCodes.FindAsync(code);

            if (codeEntity == null)
            {
                codeEntity = new OAuthCodeEntity
                {
                    Value = code
                };
                await DBContext.AddAsync(codeEntity);

                await DBContext.SaveChangesAsync();
            }

            var token = string.IsNullOrEmpty(codeEntity.UserId) ? null :
                        DBContext
                        .OAuthTokens
                        .FirstOrDefault(t =>
                                        t.UserId == codeEntity.UserId && (t.Expiry == null || t.Expiry.Value > DateTime.Now)
                                        );

            // This user already has a valid access token, lets just use that instead
            if (token != null)
            {
                return(BackToHome(token));
            }

            // This is a new, unrecognized user, try and fetch an access token

            var tokenUri = UriPath.Combine(Config.PathOfExileApi.Route, "/OAuth/Token");

            var redirectUri = Url.Action("TokenCallback", "OAuth", null, Request.Scheme);
            var queryParams = new Dictionary <string, string>
            {
                { "client_id", Config.PathOfExileApi.ClientId },
                { "client_secret", Config.PathOfExileApi.ClientSecret },
                { "code", code },
                { "grant_type", "authorization_code" },
                { "redirect_uri", redirectUri }
            };

            var tokenQuery = QueryHelpers.AddQueryString(tokenUri, queryParams);

            return(Redirect(tokenQuery));
        }
        public async Task <bool> DeleteFoodMarker(int foodMarkerId)
        {
            string             uri            = UriPath.Combine(m_Uri, "FoodMarker");
            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Delete, UriPath.Combine(uri, foodMarkerId.ToString()));

            HttpResponseMessage response = await m_Client.SendAsync(requestMessage);

            if (!response.IsSuccessStatusCode)
            {
                return(false);
            }
            return(true);
        }
        public async Task <RestReturnObj <IEnumerable <FoodMarkerImageMeta> > > PostPhotos(int foodMarkerId, List <byte[]> images)
        {
            string             uri            = UriPath.Combine(m_Uri, "Photos");
            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, UriPath.Combine(uri, foodMarkerId.ToString()));

            MultipartFormDataContent content = new MultipartFormDataContent();

            foreach (var image in images)
            {
                ByteArrayContent byteArrayContent = new ByteArrayContent(image);
                byteArrayContent.Headers.Add("Content-Type", "application/octet-stream");
                Guid uniqueId = Guid.NewGuid();
                content.Add(byteArrayContent, "file", "image" + uniqueId.ToString() + ".png");
            }

            requestMessage.Content = content;

            HttpResponseMessage response = await m_Client.SendAsync(requestMessage);

            if (!response.IsSuccessStatusCode)
            {
                return new RestReturnObj <IEnumerable <FoodMarkerImageMeta> > {
                           IsSuccess = false
                }
            }
            ;

            var resContent = response.Content;
            var str        = await resContent.ReadAsStringAsync();

            var ret = JsonConvert.DeserializeObject <IEnumerable <FoodMarkerImageMeta> >(str);

            foreach (var meta in ret)
            {
                meta.ImageUrl = WebUtility.UrlDecode(meta.ImageUrl);
            }
            return(new RestReturnObj <IEnumerable <FoodMarkerImageMeta> >
            {
                IsSuccess = response.IsSuccessStatusCode,
                Obj = ret
            });
        }
Esempio n. 12
0
        public void Process(ISemanticProcessor proc, IMembrane membrane, Route route)
        {
            IPublicRouterService routerService = proc.ServiceManager.Get <IPublicRouterService>();
            HttpListenerContext  context       = route.Context;
            HttpVerb             verb          = context.Verb();
            UriPath   path        = context.Path();
            string    searchRoute = GetSearchRoute(verb, path);
            RouteInfo routeInfo;

            // Semantic routes can be either public or authenticated.
            if (routerService.Routes.TryGetValue(searchRoute, out routeInfo))
            {
                string        data = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding).ReadToEnd();
                Type          receptorSemanticType = routeInfo.ReceptorSemanticType;
                SemanticRoute semanticRoute        = (SemanticRoute)Activator.CreateInstance(receptorSemanticType);
                semanticRoute.PostData = data;

                if (!String.IsNullOrEmpty(data))
                {
                    // Is it JSON?
                    if (data[0] == '{')
                    {
                        JsonConvert.PopulateObject(data, semanticRoute);
                    }
                    else
                    {
                        // Example: "username=sdfsf&password=sdfsdf&LoginButton=Login"
                        string[] parms = data.Split('&');

                        foreach (string parm in parms)
                        {
                            string[]     keyVal = parm.Split('=');
                            PropertyInfo pi     = receptorSemanticType.GetProperty(keyVal[0], BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

                            if (pi != null)
                            {
                                // TODO: Convert to property type.
                                // TODO: value needs to be re-encoded to handle special characters.
                                pi.SetValue(semanticRoute, keyVal[1]);
                            }
                        }
                    }
                }
                else if (verb.Value == "GET")
                {
                    // Parse parameters
                    NameValueCollection nvc = context.Request.QueryString;

                    foreach (string key in nvc.AllKeys)
                    {
                        PropertyInfo pi = receptorSemanticType.GetProperty(key, BindingFlags.Public | BindingFlags.Instance);

                        if (pi != null)
                        {
                            // TODO: Convert to property type.
                            // TODO: value needs to be re-encoded to handle special characters.
                            pi.SetValue(semanticRoute, nvc[key]);
                        }
                    }
                }

                // Must be done AFTER populating the object -- sometimes the json converter nulls the base class!
                semanticRoute.Context = context;
                proc.ProcessInstance <WebServerMembrane>(semanticRoute, true);                          // TODO: Why execute on this thread?
            }
            else if (verb.Value == "GET")
            {
                // Only issue the UnhandledContext if this is not an authenticated route.
                if (!proc.ServiceManager.Get <IAuthenticatingRouterService>().IsAuthenticatedRoute(searchRoute))
                {
                    // Put the context on the bus for some service to pick up.
                    // All unhandled context are assumed to be public routes.
                    proc.ProcessInstance <WebServerMembrane, UnhandledContext>(c => c.Context = context);
                }
            }
            else
            {
                proc.ProcessInstance <WebServerMembrane, ExceptionResponse>(e =>
                {
                    e.Context   = context;
                    e.Exception = new Exception("Route " + searchRoute + " not defined.");
                });
            }
        }
        public void Process(ISemanticProcessor proc, IMembrane membrane, Route route)
        {
            IAuthenticatingRouterService routerService = proc.ServiceManager.Get <IAuthenticatingRouterService>();
            HttpListenerContext          context       = route.Context;
            HttpVerb  verb        = context.Verb();
            UriPath   path        = context.Path();
            string    searchRoute = GetSearchRoute(verb, path);
            string    data        = route.Data;
            RouteInfo routeInfo;

            // TODO: Session manager may not exist.  How do we handle services that are missing?
            IWebSessionService session = proc.ServiceManager.Get <IWebSessionService>();

            // Semantic routes can be either public or authenticated.
            if (routerService.Routes.TryGetValue(searchRoute, out routeInfo))
            {
                // Public routes always authenticate.
                bool authenticatedRoute = true;
                bool authorizedRoute    = true;

                if (routeInfo.RouteType == RouteType.AuthenticatedRoute)
                {
                    session.UpdateState(context);
                    authenticatedRoute = session.IsAuthenticated(context);
                }

                if (routeInfo.RouteType == RouteType.RoleRoute)
                {
                    session.UpdateState(context);
                    authenticatedRoute = session.IsAuthenticated(context);

                    // User must be authenticated and have the correct role setting.
                    if (authenticatedRoute)
                    {
                        // Any bits that are set with a binary "and" of the route's role mask and the current role passes the authorization test.
                        uint mask = session.GetSessionObject <uint>(context, "RoleMask");
                        authorizedRoute = (mask & routeInfo.RoleMask) != 0;
                    }
                }

                if (authenticatedRoute && authorizedRoute)
                {
                    Type          receptorSemanticType = routeInfo.ReceptorSemanticType;
                    SemanticRoute semanticRoute        = (SemanticRoute)Activator.CreateInstance(receptorSemanticType);
                    semanticRoute.PostData = data;

                    if (!String.IsNullOrEmpty(data))
                    {
                        // Is it JSON?
                        // NOTE: "JSON" is passed in as a string, not object.  So this is what it looks like in the Javascript:
                        // $.post("/geeks/createProfile", '{ "profileName": "foobar" }'
                        // Note the surrounding ' marks
                        if (data[0] == '{')
                        {
                            JsonConvert.PopulateObject(data, semanticRoute);
                        }
                        else
                        {
                            // Instead here, the data is passed in as an object, which comes in as params.  The Javascript for this looks like:
                            // $.post("/geeks/createProfile", { "profileName": profileName }
                            // Note the lack of surrounding ' around the { }
                            // Example: "username=sdfsf&password=sdfsdf&LoginButton=Login"
                            string[] parms = data.Split('&');

                            foreach (string parm in parms)
                            {
                                string[]     keyVal = parm.Split('=');
                                PropertyInfo pi     = receptorSemanticType.GetProperty(keyVal[0], BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

                                if (pi != null)
                                {
                                    // TODO: Should handling of "+" be before or after the UnescapedDataString call?
                                    object valOfType = Converter.Convert(Uri.UnescapeDataString(keyVal[1].Replace('+', ' ')), pi.PropertyType);
                                    pi.SetValue(semanticRoute, valOfType);
                                }
                            }
                        }
                    }
                    else if (verb.Value == "GET")
                    {
                        // Parse parameters
                        NameValueCollection nvc = context.Request.QueryString;

                        foreach (string key in nvc.AllKeys)
                        {
                            PropertyInfo pi = receptorSemanticType.GetProperty(key, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

                            if (pi != null)
                            {
                                // pi.SetValue(semanticRoute, Uri.UnescapeDataString(nvc[key].Replace('+', ' ')));
                                // TODO: Should handling of "+" be before or after the UnescapedDataString call?
                                object valOfType = Converter.Convert(Uri.UnescapeDataString(nvc[key].Replace('+', ' ')), pi.PropertyType);
                                pi.SetValue(semanticRoute, valOfType);
                            }
                        }
                    }

                    // Must be done AFTER populating the object -- sometimes the json converter nulls the base class!
                    semanticRoute.Context = context;
                    proc.ProcessInstance <WebServerMembrane>(semanticRoute, true);
                }
                else
                {
                    // Deal with expired or requires authentication.
                    switch (session.GetState(context))
                    {
                    case SessionState.New:
                        // TODO: Oh man, this is application specific!!!
                        session.SetSessionObject(context, "OneTimeBadAlert", "Please Sign In");
                        context.Redirect("/account/login");
                        //proc.ProcessInstance<WebServerMembrane, StringResponse>(r =>
                        //{
                        //	r.Context = context;
                        //	r.Message = "authenticationRequired";		// used in clifton.spa.js to handle SPA error responses
                        //	r.StatusCode = 403;
                        //});
                        break;

                    case SessionState.Authenticated:
                        proc.ProcessInstance <WebServerMembrane, StringResponse>(r =>
                        {
                            r.Context    = context;
                            r.Message    = "notAuthorized";                                                             // used in clifton.spa.js to handle SPA error responses
                            r.StatusCode = 401;
                        });
                        break;

                    case SessionState.Expired:
                        session.SetSessionObject(context, "OneTimeBadAlert", "Session expired.  Please sign in again.");
                        context.Redirect("/account/login");
                        //proc.ProcessInstance<WebServerMembrane, StringResponse>(r =>
                        //{
                        //	r.Context = context;
                        //	r.Message = "sessionExpired";				// used in clifton.spa.js to handle SPA error responses
                        //	r.StatusCode = 401;
                        //});
                        break;
                    }
                }
            }
            else
            {
                proc.ProcessInstance <LoggerMembrane, ST_Log>(msg => msg.Message = "Using default handler: " + verb.Value + ": " + path.Value);
                // Put the context on the bus for some service to pick up.
                // All unhandled context are assumed to be public routes.
                proc.ProcessInstance <WebServerMembrane, UnhandledContext>(c => c.Context = context);
            }
        }
 protected string GetSearchRoute(HttpVerb verb, UriPath path)
 {
     return(verb.Value + ":" + path.Value);
 }
Esempio n. 15
0
 protected string GetSearchRoute(HttpVerb verb, UriPath path)
 {
     return verb.Value + ":" + path.Value;
 }
Esempio n. 16
0
 /// <summary>
 /// Return the URL path.
 /// </summary>
 public static UriPath Path(this HttpListenerContext context)
 {
     return(UriPath.Create(context.Request.RawUrl.LeftOf("?").RightOf("/").ToLower()));
 }
Esempio n. 17
0
        public void Process(ISemanticProcessor proc, IMembrane membrane, Route route)
        {
            IAuthenticatingRouterService routerService = proc.ServiceManager.Get <IAuthenticatingRouterService>();
            IContext context = route.Context;
            HttpVerb verb    = context.Verb();
            UriPath  path    = context.Path();

            string    searchRoute = GetSearchRoute(verb, path);
            string    data        = route.Data;
            RouteInfo routeInfo;

            IPAddress addr = context.Request.RemoteEndPoint.Address;
            string    ip   = addr.ToString();

            // Handle localhost format.
            if (ip == "::1")
            {
                addr = new IPAddress(new byte[] { 127, 0, 0, 1 });
            }

            Console.WriteLine(DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss tt ") + "IP: " + addr.ToString() + "    URL: " + route.Context.Request.Url);

            // TODO: Session manager may not exist.  How do we handle services that are missing?
            IWebSessionService session = proc.ServiceManager.Get <IWebSessionService>();

            // Semantic routes can be either public or authenticated.
            if (routerService.Routes.TryGetValue(searchRoute, out routeInfo))
            {
                // Public routes always authenticate.
                bool authenticatedRoute = true;
                bool authorizedRoute    = true;

                if (routeInfo.RouteType == RouteType.AuthenticatedRoute)
                {
                    session.UpdateState(context);
                    authenticatedRoute = session.IsAuthenticated(context);
                }

                if (routeInfo.RouteType == RouteType.RoleRoute)
                {
                    session.UpdateState(context);
                    authenticatedRoute = session.IsAuthenticated(context);

                    // User must be authenticated and have the correct role setting.
                    if (authenticatedRoute)
                    {
                        // Any bits that are set with a binary "and" of the route's role mask and the current role passes the authorization test.
                        uint mask = session.GetSessionObject <uint>(context, "RoleMask");
                        authorizedRoute = (mask & routeInfo.RoleMask) != 0;
                    }
                }

                if (authenticatedRoute)                     // user is authenticated
                {
                    session.UpdateLastTransaction(context);
                }

                if (authenticatedRoute && authorizedRoute)
                {
                    Type          receptorSemanticType = routeInfo.ReceptorSemanticType;
                    SemanticRoute semanticRoute        = (SemanticRoute)Activator.CreateInstance(receptorSemanticType);
                    semanticRoute.PostData = data;

                    if (!String.IsNullOrEmpty(data))
                    {
                        // Is it JSON?
                        // NOTE: "JSON" is passed in as a string, not object.  So this is what it looks like in the Javascript:
                        // $.post("/geeks/createProfile", '{ "profileName": "foobar" }'
                        // Note the surrounding ' marks
                        if (data[0] == '{')
                        {
                            JsonConvert.PopulateObject(data, semanticRoute);
                            SetUrlParameters(context.Request.Url.ToString(), semanticRoute, receptorSemanticType);
                        }
                        else if (MultiPartParser.IsMultiPart(data))
                        {
                            MultiPartParser.ContentType ct = MultiPartParser.GetContentType(data);
                            string content = MultiPartParser.GetContent(data);

                            if (!(semanticRoute is IFileUpload))
                            {
                                throw new RouterException("Semantic route class must implement IFileUpload");
                            }

                            ((IFileUpload)semanticRoute).Content = content;
                        }
                        else
                        {
                            // Instead here, the data is passed in as an object, which comes in as params.  The Javascript for this looks like:
                            // $.post("/geeks/createProfile", { "profileName": profileName }
                            // Note the lack of surrounding ' around the { }
                            // Example: "username=sdfsf&password=sdfsdf&LoginButton=Login"
                            // Use $.post(url, JSON.stringify(data) to convert to JSON
                            string[] parms = data.Split('&');

                            foreach (string parm in parms)
                            {
                                string[]     keyVal = parm.Split('=');
                                PropertyInfo pi     = receptorSemanticType.GetProperty(keyVal[0], BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

                                if (pi != null)
                                {
                                    // TODO: Should handling of "+" be before or after the UnescapedDataString call?
                                    object valOfType = Converter.Convert(Uri.UnescapeDataString(keyVal[1].Replace('+', ' ')), pi.PropertyType);
                                    pi.SetValue(semanticRoute, valOfType);
                                }
                            }
                        }
                    }
                    else if (verb.Value == "GET")
                    {
                        SetUrlParameters(context.Request.Url.ToString(), semanticRoute, receptorSemanticType);
                    }

                    // Must be done AFTER populating the object -- sometimes the json converter nulls the base class!
                    semanticRoute.Context = context;
                    // TODO: Why are we doing this on the caller thread, except for debugging???
                    proc.ProcessInstance <WebServerMembrane>(semanticRoute, true);
                }
                else
                {
                    // Deal with expired or requires authentication.
                    switch (session.GetState(context))
                    {
                    case SessionState.New:
                        // TODO: Oh man, this is application specific!!!
                        session.SetSessionObject(context, "OneTimeBadAlert", "Please Sign In");
                        context.Redirect("/account/login");
                        //proc.ProcessInstance<WebServerMembrane, StringResponse>(r =>
                        //{
                        //	r.Context = context;
                        //	r.Message = "authenticationRequired";		// used in clifton.spa.js to handle SPA error responses
                        //	r.StatusCode = 403;
                        //});
                        break;

                    case SessionState.Authenticated:
                        proc.ProcessInstance <WebServerMembrane, StringResponse>(r =>
                        {
                            r.Context    = context;
                            r.Message    = "notAuthorized";                                                             // used in clifton.spa.js to handle SPA error responses
                            r.StatusCode = 401;
                        });
                        break;

                    case SessionState.Expired:
                        session.SetSessionObject(context, "OneTimeBadAlert", "Session expired.  Please sign in again.");
                        context.Redirect("/account/login");
                        //proc.ProcessInstance<WebServerMembrane, StringResponse>(r =>
                        //{
                        //	r.Context = context;
                        //	r.Message = "sessionExpired";				// used in clifton.spa.js to handle SPA error responses
                        //	r.StatusCode = 401;
                        //});
                        break;
                    }
                }
            }
            else
            {
                // proc.ProcessInstance<LoggerMembrane, ST_Log>(msg => msg.Message = "Using default handler: " + verb.Value + ": " + path.Value);
                // Put the context on the bus for some service to pick up.
                // All unhandled context are assumed to be public routes.
                proc.ProcessInstance <WebServerMembrane, UnhandledContext>(c => c.Context = context);
            }
        }