// Process API calls based on the class's HTTP URL private void ApiProcess() { // The API request wrapper UriWrapper uri = new UriWrapper(this.HttpUrl, this.HttpMethod); // The user who is accessing the API User apiUser = null; // The handler being accessed IApiHandler api = null; // No API request found? Serve web UI if (!uri.IsApiCall) { api = Injection.Kernel.Get <IApiHandlerFactory>().CreateApiHandler("web"); api.Process(uri, this, apiUser); return; } // Get client IP address string ip = ((IPEndPoint)this.Socket.Client.RemoteEndPoint).Address.ToString(); // Check for valid API action ("web" and "error" are technically valid, but can't be used in this way) if (uri.ApiAction == null || uri.ApiAction == "web" || uri.ApiAction == "error") { ErrorApiHandler errorApi = (ErrorApiHandler)Injection.Kernel.Get <IApiHandlerFactory>().CreateApiHandler("error"); errorApi.Process(uri, this, apiUser, "Invalid API call"); logger.IfInfo(String.Format("[{0}] API: {1}", ip, this.HttpUrl)); return; } // Check for session cookie authentication, unless this is a login request string sessionId = null; if (uri.ApiAction != "login") { sessionId = this.GetSessionCookie(); apiUser = Injection.Kernel.Get <IApiAuthenticate>().AuthenticateSession(sessionId); } // If no cookie, try parameter authentication if (apiUser == null) { apiUser = Injection.Kernel.Get <IApiAuthenticate>().AuthenticateUri(uri); // If user still null, failed authentication, so serve error if (apiUser == null) { ErrorApiHandler errorApi = (ErrorApiHandler)Injection.Kernel.Get <IApiHandlerFactory>().CreateApiHandler("error"); errorApi.Process(uri, this, apiUser, "Authentication failed"); logger.IfInfo(String.Format("[{0}] API: {1}", ip, this.HttpUrl)); return; } } // apiUser.SessionId will be generated on new login, so that takes precedence for new session cookie apiUser.SessionId = apiUser.SessionId ?? sessionId; this.SetSessionCookie(apiUser.SessionId); // Store user's current session object apiUser.CurrentSession = Injection.Kernel.Get <ISessionRepository>().SessionForSessionId(apiUser.SessionId); // Retrieve the requested API handler by its action IApiHandler apiHandler = Injection.Kernel.Get <IApiHandlerFactory>().CreateApiHandler(uri.ApiAction); // Check for valid API action if (apiHandler == null) { ErrorApiHandler errorApi = (ErrorApiHandler)Injection.Kernel.Get <IApiHandlerFactory>().CreateApiHandler("error"); errorApi.Process(uri, this, apiUser, "Invalid API call"); logger.IfInfo(String.Format("[{0}] API: {1}", ip, this.HttpUrl)); return; } // Log API call logger.IfInfo(String.Format("[{0}/{1}@{2}] API: {3} {4}", apiUser.UserName, apiUser.CurrentSession.ClientName, ip, this.HttpMethod, this.HttpUrl)); // Check if user has appropriate permissions for this action on this API handler if (!apiHandler.CheckPermission(apiUser, uri.Action)) { ErrorApiHandler errorApi = (ErrorApiHandler)Injection.Kernel.Get <IApiHandlerFactory>().CreateApiHandler("error"); errorApi.Process(uri, this, apiUser, "Permission denied"); return; } // Finally, process and return results apiHandler.Process(uri, this, apiUser); }