예제 #1
0
        public ActionResult CreateAPIKey(CreateAPIKey cmd)
        {
            if (!ModelState.IsValid)
            {
                return(View(cmd));
            }

            APIEndpoint.AddAPIKey(cmd.APIKey);

            return(RedirectToAction("Step1"));
        }
예제 #2
0
        public ActionResult TestApi()
        {
            var apiSettings = APIEndpoint.GetApiSettings();

            return(View(new TestAPIViewModel {
                Command = new TestAPICommand {
                    APIKey = apiSettings.APIKey,
                    EndpointUrl = apiSettings.EndpointUrl,
                    Accept = "application/json"
                }
            }));
        }
예제 #3
0
 public ActionResult TestApi(TestAPICommand cmd)
 {
     try {
         var result = APIEndpoint.TestEndpoint(cmd);
         return(View(new TestAPIViewModel {
             Command = cmd,
             Result = result
         }));
     }
     catch (Exception e) {
         return(View(new TestAPIViewModel {
             Command = cmd,
             Result = TestAPIResult.FromException(e)
         }));
     }
 }
예제 #4
0
 public static bool CheckKey(string key)
 {
     return(APIEndpoint.AuthenticateKey(key));
 }
예제 #5
0
        public void ProcessEndpoint(Type T, ContextProvider Context)
        {
            RequestProvider  Request  = Context.Request;
            ResponseProvider Response = Context.Response;

            //Create an instance of the specified endpoint and set the required values.
            //We're not using a constructor because it would require each individual endpoint to have its own constructor that just calls the base APIEndpoint constructor, and that's a pain.
            APIEndpoint Endpoint = (APIEndpoint)Activator.CreateInstance(T);

            Endpoint.Connection = Connection;
            Endpoint.Context    = Context;
            Endpoint.Response   = Context.Response;
            Endpoint.Request    = Context.Request;
            Endpoint.Params     = Context.Request.Params;

            //Set access control headers for CORS support.
            List <string> AllowedMethods = new List <string>();

            foreach (MethodInfo M in T.GetMethods())
            {
                if (M.DeclaringType == GetType())
                {
                    AllowedMethods.Add(M.Name);
                }
            }

            bool OriginHeader = Request.Headers.TryGetValue("origin", out List <string> Origins);

            if (OriginHeader && Program.CORSAddresses.Contains(Origins[0] + '/'))
            {
                Response.Headers.Add("Access-Control-Allow-Origin", Origins[0]);
            }
            Response.Headers.Add("Allow", string.Join(", ", AllowedMethods));
            Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type");

            // Get the endpoint method
            MethodInfo Method = Endpoint.GetType().GetMethod(Request.HttpMethod.ToString());

            //Check this method's required content type, if any.
            RequireContentType CT = Method.GetCustomAttribute <RequireContentType>();

            if (CT != null)
            {
                if (CT.ContentType == "application/json")
                {
                    //Try to parse the JSON. If that failed for some reason, check if the response body is actually necessary.
                    //Return null if it isn't, return a 400 Bad Request if it is.
                    using StreamReader Reader = new StreamReader(Request.InputStream, Request.ContentEncoding);
                    string JSONText = Reader.ReadToEnd();
                    try {
                        Endpoint.JSON = JObject.Parse(JSONText);
                    } catch (JsonReaderException e) {
                        if (Method.GetCustomAttribute <RequireBody>() != null)
                        {
                            Log.Warning("Refused request for endpoint " + T.Name + ": Could not parse JSON");
                            Log.Debug("Message: " + e.Message);
                            Log.Debug("Received JSON: " + JSONText);
                            Response.Send("Invalid JSON: " + e.Message, HttpStatusCode.BadRequest);
                            return;
                        }
                        Endpoint.JSON = null;
                    }
                }
            }

            //Check whether the user is allowed to use this endpoint method, if necessary.
            #region PermissionLevel Attribute
            PermissionLevel Attr = Method.GetCustomAttribute <PermissionLevel>();
            if (Attr != null)
            {
                //Check cookie. If its missing, send a 401 Unauthorized if the cookie is missing. (because a user MUST be logged in to use an endpoint with a PermissionLevel attribute)
                Cookie SessionIDCookie = Request.Cookies["SessionID"];
                if (SessionIDCookie == null)
                {
                    Response.Send("No Session", HttpStatusCode.Unauthorized);
                    return;
                }

                //Check if a session exists with the Session ID contained in the session cookie. If none is found or the session has expired, send back a 401 Unauthorized
                Session s = Session.GetUserSession(Connection, SessionIDCookie.Value);
                if (s == null)
                {
                    Response.Send("Expired session", HttpStatusCode.Unauthorized);
                    return;
                }
                //Renew the session, and save it in the endpoint object.
                s.Renew(Connection);
                Endpoint.UserSession = s;

                //Save user in endpoint object
                Endpoint.RequestUser = Connection.Get <User>(s.User);

                //Get department name. If none was found, assume Administrators
                string DepartmentName;
                if (Endpoint.Params.ContainsKey("Department"))
                {
                    DepartmentName = Endpoint.Params["Department"][0];
                }
                else
                {
                    DepartmentName = "Administrators";
                }

                //Get department. If none was found, send 400 Bad Request
                Department Dept = Department.GetByName(Connection, DepartmentName);
                if (Dept == null)
                {
                    Response.Send("No such Department", HttpStatusCode.BadRequest);
                    return;
                }

                //Get permissionlevel
                PermLevel Level = Endpoint.RequestUser.GetPermissionLevel(Connection, Dept.ID);
                Endpoint.RequestUserLevel = Level;

                //Check permission level
                if (Level < Attr.Level)
                {
                    Log.Warning("User " + Endpoint.RequestUser.Email + " attempted to access endpoint " + T.Name + " without sufficient permissions");
                    Log.Warning("Department: '" + DepartmentName + "', User is '" + Level + "' but must be at least '" + Attr.Level + "'");
                    Response.Send(HttpStatusCode.Forbidden);
                    return;
                }
            }
            #endregion

            //Attempt to invoke the API endpoint method. If this fails, send a 500 Internal Server Error to the client.
            try {
                Method.Invoke(Endpoint, null);
            } catch (Exception e) {
                Log.Error("Failed to fullfill request for endpoint " + T.Name + ": " + e.GetType().Name + ", " + e.Message);
                Response.Send(Utils.GetErrorPage(HttpStatusCode.InternalServerError, e.Message), HttpStatusCode.InternalServerError);
            }
        }
예제 #6
0
        public ActionResult ApiSettings()
        {
            var settings = APIEndpoint.GetApiSettings();

            return(View(settings));
        }