public PermissionLevel(PermLevel Level) => this.Level = Level;
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); } }
public async Task HandleCommand(ICommandContext context) { try { string[] args = context.Message.Content.Split(' '); IGuildUser user = (IGuildUser)context.Message.Author; if (context.Message.Content.StartsWith(context.Guild.EveryoneRole.Mention)) { await context.Channel.SendMessageAsync("You cannot mention everyone in a command."); return; } args[0] = args[0].Replace(Program.Config.BotPrefix, ""); switch (args[0].ToLower()) { case "ping": await context.Channel.SendMessageAsync($"Pong!"); return; case "addusr": { if (user.RoleIds.All(r => r != Program.Config.StaffRoleId)) { await context.Channel.SendMessageAsync("Code 4: Permission Denied."); return; } if (args.Length != 3) { await context.Channel.SendMessageAsync("Code 3: Improper number of arguments."); return; } string id = args[1].Replace("<", "").Replace("@", "").Replace(">", "").Replace("!", ""); if (!ulong.TryParse(id, out ulong userId)) { await context.Channel.SendMessageAsync($"Code 2: invalid Discord user defined."); return; } if (!ulong.TryParse(args[2], out ulong steamId)) { await context.Channel.SendMessageAsync("Code 5: Invalid steamID defined."); return; } File.AppendAllText(userSync, $"{userId}:{steamId}@steam\n"); await context.Channel.SendMessageAsync("User successfully added to user sync file."); return; } case "addrole": { if (user.RoleIds.All(r => r != Program.Config.StaffRoleId)) { await context.Channel.SendMessageAsync("Code 4: Permission Denied."); return; } if (args.Length != 3) { await context.Channel.SendMessageAsync($"Code 3: Improper number of arguments."); return; } string id = args[1].Replace("<", "").Replace("@", "").Replace(">", "").Replace("&", "") .Replace("!", ""); if (!ulong.TryParse(id, out ulong roleId) || context.Guild.GetRole(roleId) == null) { await context.Channel.SendMessageAsync("Code 6: Unable to retrieve Discord Role."); return; } File.AppendAllText(roleSync, $"{id}:{args[2]}"); await context.Channel.SendMessageAsync($"New role sync added successfully."); return; } case "resync": { await ReloadConfig(); await context.Channel.SendMessageAsync("Role sync configs reloaded."); return; } case "delusr": { if (user.RoleIds.All(r => r != Program.Config.StaffRoleId)) { await context.Channel.SendMessageAsync("Code 4: Permission Denied."); return; } if (args.Length != 2) { await context.Channel.SendMessageAsync("Code 3: Improper number of arguments."); return; } string[] readArray = File.ReadAllLines(userSync); List <string> toKeep = new List <string>(); foreach (string usr in readArray) { string[] sync = usr.Split(':'); if (sync[1] != $"{args[1]}@steam") { toKeep.Add(usr); } } File.WriteAllLines(userSync, toKeep); await context.Channel.SendMessageAsync("User sync successfully removed."); return; } case "delrole": { if (user.RoleIds.All(r => r != Program.Config.StaffRoleId)) { await context.Channel.SendMessageAsync("Code 4: Permission Denied."); return; } if (args.Length != 2) { await context.Channel.SendMessageAsync($"Code 3: Improper number of arguments."); return; } string id = args[1].Replace("<", "").Replace("@", "").Replace(">", "").Replace("&", "") .Replace("!", ""); if (!ulong.TryParse(id, out ulong roleId) || context.Guild.GetRole(roleId) == null) { await context.Channel.SendMessageAsync("Code 6: Unable to retrieve Discord Role."); return; } string[] readArray = File.ReadAllLines(roleSync); List <string> toKeep = new List <string>(); foreach (string role in readArray) { string[] sync = role.Split(':'); if (sync[0] != id) { toKeep.Add(role); } } File.WriteAllLines(roleSync, toKeep); await context.Channel.SendMessageAsync("Role sync successfully removed."); return; } } if (Program.Config.AllowedCommands.ContainsKey(args[0].ToLower())) { PermLevel lvl = PermLevel.PermLevel0; foreach (ulong id in user.RoleIds.Where(s => s == Program.Config.PermLevel1Id || s == Program.Config.Permlevel2Id || s == Program.Config.Permlevel3Id || s == Program.Config.Permlevel4Id)) { if (GetPermlevel(id) > lvl) { lvl = GetPermlevel(id); } } if (lvl >= Program.Config.AllowedCommands[args[0].ToLower()]) { ProcessSTT.SendData(context.Message.Content, Program.Config.Port, context.Message.Author.Username, context.Channel.Id); } else { await context.Channel.SendMessageAsync("Permission denied."); } } } catch (Exception e) { Program.Error($"Command failure: {e}"); } }
public override void PATCH() { //Get required fields if (!Params.ContainsKey("email")) { Response.Send("Missing fields", HttpStatusCode.BadRequest); return; } //Administrator account can't be modified; if (Params["email"][0] == "Administrator") { Response.Send(HttpStatusCode.Forbidden); return; } //Check if the specified user exists. If it doesn't, send a 404 Not Found User Acc = User.GetUserByEmail(Connection, Params["email"][0]); if (Acc == null) { Response.Send("No such user", HttpStatusCode.NotFound); return; } //Change email if necessary if (JSON.TryGetValue <string>("Email", out JToken NewEmail)) { //Check if the new address is valid Regex rx = new Regex("^[A-z0-9]*@[A-z0-9]*.[A-z]*$"); if (!rx.IsMatch((string)NewEmail)) { Response.Send("Invalid Email", HttpStatusCode.BadRequest); return; } //Check if the new address is already in use if (User.GetUserByEmail(Connection, (string)NewEmail) != null) { Response.Send("New Email already in use", HttpStatusCode.BadRequest); return; } Acc.Email = (string)NewEmail; } //Change password if necessary if (JSON.TryGetValue <string>("Password", out JToken Password)) { Regex PasswordRx = new Regex((string)Config.GetValue("AuthenticationSettings.PasswordRegex")); if (!PasswordRx.IsMatch((string)Password) || ((string)Password).Length == 0) { Response.Send("Password does not meet requirements", HttpStatusCode.BadRequest); return; } Acc.ChangePassword(Connection, (string)Password); } //Set department permissions if necessary if (JSON.TryGetValue <JObject>("MemberDepartments", out JToken MemberDepartment)) { JObject Perms = (JObject)MemberDepartment; foreach (KeyValuePair <string, JToken> Entry in Perms) { //Check if the specified department exists, skip if it doesn't. Department Dept = Department.GetByName(Connection, Entry.Key); if (Dept == null) { continue; } //Check if the specified account type is valid. If it isn't, skip it. if (!PermLevel.TryParse((string)Entry.Value, out PermLevel Level)) { continue; } //If the new user has a greater perm than the requestuser, skip it. if (Level > RequestUserLevel) { continue; } //Set level Acc.SetPermissionLevel(Connection, Level, Dept); } } //Set optional fields foreach (var x in JSON) { if (x.Key == "Email" || x.Key == "PasswordHash") { continue; } PropertyInfo Prop = Acc.GetType().GetProperty(x.Key); if (Prop == null) { continue; } dynamic Value = x.Value.ToObject(Prop.PropertyType); Prop.SetValue(Acc, Value); } //Update DB row Connection.Update <User>(Acc); Response.Send(StatusCode: HttpStatusCode.OK); }
/// <summary> /// Sets a user permission level. /// </summary> /// <param name="Connection"></param> /// <param name="Level"></param> /// <param name="Department"></param> public void SetPermissionLevel(SQLiteConnection Connection, PermLevel Level, int Department) => Connection.Execute("INSERT OR REPLACE INTO Permissions (User, Permission, Department) VALUES (@User, @Permission, @Department)", new { user = this.ID, Permission = Level, Department });
/// <summary> /// Sets a user permission level. /// </summary> /// <param name="Connection"></param> /// <param name="Level"></param> /// <param name="Department"></param> public void SetPermissionLevel(SQLiteConnection Connection, PermLevel Level, Department Department) => SetPermissionLevel(Connection, Level, Department.ID);