mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
299 lines
10 KiB
C#
299 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Encodings.Web;
|
|
using System.Threading.Tasks;
|
|
using Remotely.Shared.Models;
|
|
using Remotely.Shared.ViewModels;
|
|
using Remotely.Server.Data;
|
|
using Remotely.Server.Services;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Remotely.Shared.ViewModels.Organization;
|
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
|
using System.Text;
|
|
using Microsoft.AspNetCore.WebUtilities;
|
|
using Remotely.Server.Auth;
|
|
|
|
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
|
|
|
namespace Remotely.Server.API
|
|
{
|
|
[Route("api/[controller]")]
|
|
[ApiController]
|
|
public class OrganizationManagementController : ControllerBase
|
|
{
|
|
public OrganizationManagementController(DataService dataService, UserManager<RemotelyUser> userManager, IEmailSender emailSender)
|
|
{
|
|
this.DataService = dataService;
|
|
this.UserManager = userManager;
|
|
this.EmailSender = emailSender;
|
|
}
|
|
|
|
private DataService DataService { get; }
|
|
private IEmailSender EmailSender { get; }
|
|
private UserManager<RemotelyUser> UserManager { get; }
|
|
|
|
|
|
[HttpPost("ChangeIsAdmin/{userID}")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public IActionResult ChangeIsAdmin(string userID, [FromBody]bool isAdmin)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
if (User.Identity.IsAuthenticated &&
|
|
DataService.GetUserByName(User.Identity.Name).Id == userID)
|
|
{
|
|
return BadRequest("You can't remove administrator rights from yourself.");
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
|
|
DataService.ChangeUserIsAdmin(orgID, userID, isAdmin);
|
|
return Ok("ok");
|
|
}
|
|
|
|
[HttpDelete("DeleteInvite/{inviteID}")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public IActionResult DeleteInvite(string inviteID)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
DataService.DeleteInvite(orgID, inviteID);
|
|
return Ok("ok");
|
|
}
|
|
|
|
[HttpDelete("DeleteUser/{userID}")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public async Task<IActionResult> DeleteUser(string userID)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
if (User.Identity.IsAuthenticated &&
|
|
DataService.GetUserByName(User.Identity.Name).Id == userID)
|
|
{
|
|
return BadRequest("You can't delete yourself here. You must go to the Personal Data page to delete your own account.");
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
await DataService.RemoveUserFromOrganization(orgID, userID);
|
|
return Ok("ok");
|
|
}
|
|
|
|
[HttpDelete("DeviceGroup")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public IActionResult DeviceGroup([FromBody]string deviceGroupID)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
DataService.DeleteDeviceGroup(orgID, deviceGroupID.Trim());
|
|
return Ok("ok");
|
|
}
|
|
|
|
[HttpPost("DeviceGroup")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public IActionResult DeviceGroup([FromBody]DeviceGroup deviceGroup)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
if (!ModelState.IsValid)
|
|
{
|
|
return BadRequest();
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
var result = DataService.AddDeviceGroup(orgID, deviceGroup, out var deviceGroupID, out var errorMessage);
|
|
if (!result)
|
|
{
|
|
return BadRequest(errorMessage);
|
|
}
|
|
return Ok(deviceGroupID);
|
|
}
|
|
|
|
[HttpDelete("DeviceGroup/{groupID}/Users/")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public async Task<IActionResult> DeviceGroupRemoveUser([FromBody]string userID, string groupID)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
if (!ModelState.IsValid)
|
|
{
|
|
return BadRequest();
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
if (!await DataService.RemoveUserFromDeviceGroup(orgID, groupID, userID))
|
|
{
|
|
return BadRequest("Failed to remove user from group.");
|
|
}
|
|
return Ok();
|
|
}
|
|
|
|
[HttpPost("DeviceGroup/{groupID}/Users/")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public IActionResult DeviceGroupAddUser([FromBody]string userID, string groupID)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
if (!ModelState.IsValid)
|
|
{
|
|
return BadRequest();
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
var result = DataService.AddUserToDeviceGroup(orgID, groupID, userID, out var resultMessage);
|
|
if (!result)
|
|
{
|
|
return BadRequest(resultMessage);
|
|
}
|
|
|
|
return Ok(resultMessage);
|
|
}
|
|
|
|
[HttpGet("GenerateResetUrl/{userID}")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public async Task<IActionResult> GenerateResetUrl(string userID)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
|
|
var user = await UserManager.FindByIdAsync(userID);
|
|
|
|
if (user.OrganizationID != orgID)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
|
|
var code = await UserManager.GeneratePasswordResetTokenAsync(user);
|
|
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
|
|
var callbackUrl = Url.Page(
|
|
"/Account/ResetPassword",
|
|
pageHandler: null,
|
|
values: new { area = "Identity", code },
|
|
protocol: Request.Scheme);
|
|
|
|
return Ok(callbackUrl);
|
|
|
|
}
|
|
|
|
[HttpPut("Name")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public IActionResult Name([FromBody]string organizationName)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
if (organizationName.Length > 25)
|
|
{
|
|
return BadRequest();
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
DataService.UpdateOrganizationName(orgID, organizationName.Trim());
|
|
return Ok("ok");
|
|
}
|
|
[HttpPost("SendInvite")]
|
|
[ServiceFilter(typeof(ApiAuthorizationFilter))]
|
|
public async Task<IActionResult> SendInvite([FromBody]Invite invite)
|
|
{
|
|
if (User.Identity.IsAuthenticated &&
|
|
!DataService.GetUserByName(User.Identity.Name).IsAdministrator)
|
|
{
|
|
return Unauthorized();
|
|
}
|
|
if (!ModelState.IsValid)
|
|
{
|
|
return BadRequest();
|
|
}
|
|
|
|
Request.Headers.TryGetValue("OrganizationID", out var orgID);
|
|
|
|
|
|
if (!DataService.DoesUserExist(invite.InvitedUser))
|
|
{
|
|
var user = new RemotelyUser
|
|
{
|
|
UserName = invite.InvitedUser,
|
|
Email = invite.InvitedUser,
|
|
OrganizationID = orgID,
|
|
IsAdministrator = invite.IsAdmin
|
|
};
|
|
var result = await UserManager.CreateAsync(user);
|
|
if (result.Succeeded)
|
|
{
|
|
//if (!DataService.SetNewUserProperties(user.UserName, orgID, invite.IsAdmin))
|
|
//{
|
|
// return BadRequest();
|
|
//}
|
|
|
|
|
|
user = await UserManager.FindByEmailAsync(invite.InvitedUser);
|
|
|
|
await UserManager.ConfirmEmailAsync(user, await UserManager.GenerateEmailConfirmationTokenAsync(user));
|
|
|
|
return Ok();
|
|
}
|
|
else
|
|
{
|
|
return BadRequest("There was an issue creating the new account.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var newInvite = DataService.AddInvite(orgID, invite);
|
|
|
|
var inviteURL = $"{Request.Scheme}://{Request.Host}/Invite?id={newInvite.ID}";
|
|
await EmailSender.SendEmailAsync(invite.InvitedUser, "Invitation to Organization in Remotely",
|
|
$@"<img src='https://remotely.one/media/Remotely_Logo.png'/>
|
|
<br><br>
|
|
Hello!
|
|
<br><br>
|
|
You've been invited to join an organization in Remotely.
|
|
<br><br>
|
|
You can join the organization by <a href='{HtmlEncoder.Default.Encode(inviteURL)}'>clicking here</a>.");
|
|
|
|
return Ok();
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|