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 }); }
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); } }
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); }
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); } }
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 }); }
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); }
protected string GetSearchRoute(HttpVerb verb, UriPath path) { return verb.Value + ":" + path.Value; }
/// <summary> /// Return the URL path. /// </summary> public static UriPath Path(this HttpListenerContext context) { return(UriPath.Create(context.Request.RawUrl.LeftOf("?").RightOf("/").ToLower())); }
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); } }