using FSO.Server.Api.Core.Utils; using FSO.Server.Common; using FSO.Server.Database.DA.Inbox; using FSO.Server.Database.DA.Users; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; using System; using System.Net; namespace FSO.Server.Api.Core.Controllers.Admin { [EnableCors("AdminAppPolicy")] [Route("admin/users")] [ApiController] public class AdminUsersController : ControllerBase { //Get information about me, useful for the admin user interface to disable UI based on who you login as public IActionResult current() { var api = Api.INSTANCE; var user = api.RequireAuthentication(Request); using (var da = api.DAFactory.Get()) { var userModel = da.Users.GetById(user.UserID); if (userModel == null) { throw new Exception("Unable to find user"); } return ApiResponse.Json(HttpStatusCode.OK, userModel); } } //Get the attributes of a specific user [HttpGet("{id}")] public IActionResult Get(string id) { if (id == "current") return current(); var api = Api.INSTANCE; api.DemandModerator(Request); using (var da = api.DAFactory.Get()) { var userModel = da.Users.GetById(uint.Parse(id)); if (userModel == null) { throw new Exception("Unable to find user"); } return ApiResponse.Json(HttpStatusCode.OK, userModel); } } /// /// Unbans a user by IP and user. /// /// ID of user to unban. /// [HttpPost] [Route("admin/unban")] public IActionResult UnbanUser([FromBody] string user_id) { Api api = Api.INSTANCE; api.DemandModerator(Request); using (var da = api.DAFactory.Get()) { User userModel = da.Users.GetById(uint.Parse(user_id)); if(userModel.is_banned) { da.Users.UpdateBanned(uint.Parse(user_id), false); } var ban = da.Bans.GetByIP(userModel.last_ip); if (ban!=null) { da.Bans.Remove(userModel.user_id); } return ApiResponse.Json(HttpStatusCode.OK, new { status = "success" }); } } /// /// Sends an in-game email message to a player. /// /// /// [HttpPost] [Route("admin/mail")] public IActionResult SendMail(MailCreateModel mail) { Api api = Api.INSTANCE; api.DemandAdmin(Request); using (var da = api.DAFactory.Get()) { User recipient = da.Users.GetById(uint.Parse(mail.target_id)); if (recipient == null) { return ApiResponse.Json(HttpStatusCode.OK, new { status = "invalid_target_id" }); } if (mail.subject.Trim() == "") { return ApiResponse.Json(HttpStatusCode.OK, new { status = "subject_empty" }); } if (mail.body.Trim() == "") { return ApiResponse.Json(HttpStatusCode.OK, new { status = "body_empty" }); } // Save mail in db int message_id = da.Inbox.CreateMessage(new DbInboxMsg { sender_id = 2147483648, target_id = uint.Parse(mail.target_id), subject = mail.subject, body = mail.body, sender_name = "FreeSO Staff", time = DateTime.UtcNow, msg_type = 4, msg_subtype = 0, read_state = 0, }); // Try and notify the user ingame api.RequestMailNotify(message_id, mail.subject, mail.body, uint.Parse(mail.target_id)); return ApiResponse.Json(HttpStatusCode.OK, new { status = "success" }); } } /// /// Kicks a user out the current session. /// /// /// [HttpPost] [Route("admin/kick")] public IActionResult KickUser([FromBody] string user_id) { Api api = Api.INSTANCE; api.DemandModerator(Request); api.RequestUserDisconnect(uint.Parse(user_id)); return ApiResponse.Json(HttpStatusCode.OK, new { status = "success" }); } /// /// Bans a user and kicks them. /// /// /// [HttpPost] [Route("admin/ban")] public IActionResult BanUser(BanCreateModel ban) { Api api = Api.INSTANCE; api.DemandModerator(Request); using (var da = api.DAFactory.Get()) { User userModel = da.Users.GetById(uint.Parse(ban.user_id)); if (userModel == null) { return ApiResponse.Json(HttpStatusCode.OK, new { status = "invalid_id" }); } if (ban.ban_type == "ip") { if (da.Bans.GetByIP(userModel.last_ip) != null) { return ApiResponse.Json(HttpStatusCode.OK, new { status = "already_banned" }); } if (userModel.last_ip == "127.0.0.1") { return ApiResponse.Json(HttpStatusCode.OK, new { status = "invalid_ip" }); } da.Bans.Add(userModel.last_ip, userModel.user_id, ban.reason, int.Parse(ban.end_date), userModel.client_id); api.RequestUserDisconnect(userModel.user_id); api.SendBanMail(userModel.username, userModel.email, uint.Parse(ban.end_date)); return ApiResponse.Json(HttpStatusCode.OK, new { status = "success" }); } else if (ban.ban_type == "user") { if (userModel.is_banned) { return ApiResponse.Json(HttpStatusCode.NotFound, new { status = "already_banned" }); } da.Users.UpdateBanned(userModel.user_id, true); api.RequestUserDisconnect(userModel.user_id); api.SendBanMail(userModel.username, userModel.email, uint.Parse(ban.end_date)); return ApiResponse.Json(HttpStatusCode.OK, new { status = "success" }); } return ApiResponse.Json(HttpStatusCode.OK, new { status = "invalid_ban_type" }); } } //List users [HttpGet] public IActionResult Get(int limit, int offset, string order) { if (limit == 0) limit = 20; if (order == null) order = "register_date"; var api = Api.INSTANCE; api.DemandModerator(Request); using (var da = api.DAFactory.Get()) { if (limit > 100) { limit = 100; } var result = da.Users.All((int)offset, (int)limit); return ApiResponse.PagedList(Request, HttpStatusCode.OK, result); } } //Create a new user [HttpPost] public IActionResult Post(UserCreateModel user) { var api = Api.INSTANCE; var nuser = api.RequireAuthentication(Request); api.DemandModerator(nuser); if (user.is_admin) { //I need admin claim to do this api.DemandAdmin(nuser); } using (var da = api.DAFactory.Get()) { var userModel = new User(); userModel.username = user.username; userModel.email = user.email; userModel.is_admin = user.is_admin; userModel.is_moderator = user.is_moderator; userModel.user_state = UserState.valid; userModel.register_date = Epoch.Now; userModel.is_banned = false; var userId = da.Users.Create(userModel); userModel = da.Users.GetById(userId); if (userModel == null) { throw new Exception("Unable to find user"); } return ApiResponse.Json(HttpStatusCode.OK, userModel); } } } public class UserCreateModel { public string username { get; set; } public string email { get; set; } public string password { get; set; } public bool is_admin { get; set; } public bool is_moderator { get; set; } } public class BanCreateModel { public string ban_type { get; set; } public string user_id { get; set; } public string reason { get; set; } public string end_date { get; set; } } public class MailCreateModel { public string target_id { get; set; } public string subject { get; set; } public string body { get; set; } public string sender_name { get; set; } } }