using AllocsFixes.NetConnections.Servers.Web.API; using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Reflection; using System.Threading; namespace AllocsFixes.NetConnections.Servers.Web.Handlers { public class ApiHandler : PathHandler { private string staticPart; private Dictionary apis = new Dictionary (); public ApiHandler (string staticPart, string moduleName = null) : base (moduleName) { this.staticPart = staticPart; foreach (Type t in Assembly.GetExecutingAssembly ().GetTypes ()) { if (!t.IsAbstract && t.IsSubclassOf (typeof(WebAPI))) { ConstructorInfo ctor = t.GetConstructor (new Type [0]); if (ctor != null) { WebAPI apiInstance = (WebAPI)ctor.Invoke (new object [0]); addApi (t.Name.ToLower (), apiInstance); } } } // Add dummy types Type dummy_t = typeof (API.Null); ConstructorInfo dummy_ctor = dummy_t.GetConstructor (new Type [0]); if (dummy_ctor != null) { WebAPI dummy_apiInstance = (WebAPI)dummy_ctor.Invoke (new object[0]); // Permissions that don't map to a real API addApi("viewallclaims", dummy_apiInstance); addApi("viewallplayers", dummy_apiInstance); } } private void addApi (string _apiName, WebAPI _api) { apis.Add (_apiName, _api); WebPermissions.Instance.AddKnownModule ("webapi." + _apiName); } public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel) { string apiName = req.Url.AbsolutePath.Remove (0, staticPart.Length); if (!AuthorizeForCommand (apiName, user, permissionLevel)) { resp.StatusCode = (int)HttpStatusCode.Forbidden; if (user != null) { //Log.Out ("ApiHandler: user '{0}' not allowed to execute '{1}'", user.SteamID, apiName); } else { //Log.Out ("ApiHandler: unidentified user from '{0}' not allowed to execute '{1}'", req.RemoteEndPoint.Address, apiName); } return; } else { foreach (KeyValuePair kvp in apis) { if (apiName.StartsWith (kvp.Key)) { try { kvp.Value.HandleRequest (req, resp, user, permissionLevel); return; } catch (Exception e) { Log.Error ("Error in ApiHandler.HandleRequest(): Handler {0} threw an exception:", kvp.Key); Log.Exception (e); resp.StatusCode = (int)HttpStatusCode.InternalServerError; return; } } } } Log.Out ("Error in ApiHandler.HandleRequest(): No handler found for API \"" + apiName + "\""); resp.StatusCode = (int)HttpStatusCode.NotFound; } private bool AuthorizeForCommand (string apiName, WebConnection user, int permissionLevel) { return WebPermissions.Instance.ModuleAllowedWithLevel ("webapi." + apiName, permissionLevel); } } }