1
0
Flawless-Version-Control/Flawless.Server/Controllers/RepositoryManageController.cs

232 lines
9.8 KiB
C#

using Flawless.Communication.Request;
using Flawless.Communication.Response;
using Flawless.Communication.Shared;
using Flawless.Server.Models;
using Flawless.Server.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Flawless.Server.Controllers;
[ApiController, Authorize, Route("api/repo_manage")]
public class RepositoryManageController(AppDbContext dbContext, UserManager<AppUser> userManager) : ControllerBase
{
[HttpGet("list")]
public async Task<IActionResult> ListAllAvailableRepositoriesAsync(QueryPagesRequest r)
{
var u = (await userManager.GetUserAsync(HttpContext.User))!;
var query = await dbContext.Repositories
.Include(repository => repository.Owner)
.Include(repository => repository.Commits)
.Include(repository => repository.Members)
.ThenInclude(repositoryMember => repositoryMember.User)
.Where(rp => rp.Members.Any(m => m.User == u))
.Skip(r.Offset)
.Take(r.Length)
.ToArrayAsync();
return Ok(new PagedResponse<RepositoryInfoResponse>
{
Length = r.Length,
Offset = r.Offset,
Data = query.Select(rp => new RepositoryInfoResponse
{
RepositoryName = rp.Name,
OwnerUsername = rp.Owner.UserName!,
LatestCommitId = rp.Commits.OrderByDescending(cm => cm.CommittedOn).FirstOrDefault()?.Id ?? Guid.Empty,
Description = rp.Description,
IsArchived = rp.IsArchived,
Role = rp.Members.First(m => m.User == u).Role
}),
});
}
[HttpPost("create/{repositoryName}")]
public async Task<IActionResult> CreateRepositoryAsync(string repositoryName)
{
if (string.IsNullOrWhiteSpace(repositoryName) || repositoryName.Length <= 3)
return BadRequest(new FailedResponse("Repository name is empty or too short!"));
var u = (await userManager.GetUserAsync(HttpContext.User))!;
if (await dbContext.Repositories.AnyAsync(rp => rp.Name == repositoryName && u == rp.Owner))
return BadRequest(new FailedResponse("Repository name has already created!"));
await dbContext.Repositories.AddAsync(new Repository()
{
Name = repositoryName,
Owner = u,
});
await dbContext.SaveChangesAsync();
return Ok();
}
[HttpPost("delete/{repositoryName}")]
public async Task<IActionResult> DeleteRepositoryAsync(string repositoryName)
{
if (string.IsNullOrWhiteSpace(repositoryName) || repositoryName.Length <= 3)
return BadRequest(new FailedResponse("Repository name is empty or too short!"));
var u = (await userManager.GetUserAsync(HttpContext.User))!;
var rp = await dbContext.Repositories.FirstOrDefaultAsync(rp => rp.Name == repositoryName && u == rp.Owner);
if (rp == null) return BadRequest(new FailedResponse("Repository not found!"));
dbContext.Repositories.Remove(rp);
await dbContext.SaveChangesAsync();
return Ok();
}
[HttpGet("info/{repositoryName}")]
public async Task<IActionResult> IsRepositoryArchiveAsync(string repositoryName)
{
if (string.IsNullOrWhiteSpace(repositoryName) || repositoryName.Length <= 3)
return BadRequest(new FailedResponse("Repository name is empty or too short!"));
var u = (await userManager.GetUserAsync(HttpContext.User))!;
var rp = await dbContext.Repositories
.Include(repository => repository.Owner)
.Include(repository => repository.Commits)
.Include(repository => repository.Members)
.ThenInclude(repositoryMember => repositoryMember.User)
.FirstOrDefaultAsync(rp => rp.Name == repositoryName && u == rp.Owner);
if (rp == null) return BadRequest(new FailedResponse("Repository not found!"));
return Ok(new RepositoryInfoResponse
{
RepositoryName = rp.Name,
OwnerUsername = rp.Owner.UserName!,
LatestCommitId = rp.Commits.Max(cm => cm.Id),
Description = rp.Description,
IsArchived = rp.IsArchived,
Role = rp.Members.First(m => m.User == u).Role
});
}
[HttpPost("archive/{repositoryName}")]
public async Task<IActionResult> ArchiveRepositoryAsync(string repositoryName)
{
if (string.IsNullOrWhiteSpace(repositoryName) || repositoryName.Length <= 3)
return BadRequest(new FailedResponse("Repository name is empty or too short!"));
var u = (await userManager.GetUserAsync(HttpContext.User))!;
var rp = await dbContext.Repositories.FirstOrDefaultAsync(rp => rp.Name == repositoryName && u == rp.Owner);
if (rp == null) return BadRequest(new FailedResponse("Repository not found!"));
if (rp.IsArchived) return BadRequest(new FailedResponse("Repository is archived!"));
rp.IsArchived = true;
await dbContext.SaveChangesAsync();
return Ok();
}
[HttpPost("unarchive/{repositoryName}")]
public async Task<IActionResult> UnarchiveRepositoryAsync(string repositoryName)
{
if (string.IsNullOrWhiteSpace(repositoryName) || repositoryName.Length <= 3)
return BadRequest(new FailedResponse("Repository name is empty or too short!"));
var u = (await userManager.GetUserAsync(HttpContext.User))!;
var rp = await dbContext.Repositories.FirstOrDefaultAsync(rp => rp.Name == repositoryName && u == rp.Owner);
if (rp == null) return BadRequest(new FailedResponse("Repository not found!"));
if (!rp.IsArchived) return BadRequest(new FailedResponse("Repository is not archived!"));
rp.IsArchived = false;
await dbContext.SaveChangesAsync();
return Ok();
}
[HttpGet("get_users/{repositoryName}")]
public async Task<IActionResult> GetUsersAsync(string repositoryName, QueryPagesRequest r)
{
if (string.IsNullOrWhiteSpace(repositoryName) || repositoryName.Length <= 3)
return BadRequest(new FailedResponse("Repository name is empty or too short!"));
var u = (await userManager.GetUserAsync(HttpContext.User))!;
var rp = await dbContext.Repositories
.Include(repository => repository.Owner)
.Include(repository => repository.Members)
.ThenInclude(repositoryMember => repositoryMember.User)
.FirstOrDefaultAsync(rp => rp.Name == repositoryName && u == rp.Owner);
if (rp == null) return BadRequest(new FailedResponse("Repository not found!"));
return Ok(new PagedResponse<RepoUserRole>
{
Length = r.Length,
Offset = r.Offset,
Total = rp.Members.Count,
Data = rp.Members.Select(pm => new RepoUserRole
{
Username = pm.User.UserName!,
Role = pm.Role
})
});
}
[HttpPost("update_user/{repositoryName}")]
public async Task<IActionResult> UpdateUserAsync(string repositoryName, [FromBody] RepoUserRole r)
{
if (string.IsNullOrWhiteSpace(repositoryName) || repositoryName.Length <= 3)
return BadRequest(new FailedResponse("Repository name is empty or too short!"));
var u = (await userManager.GetUserAsync(HttpContext.User))!;
var tu = await userManager.FindByNameAsync(r.Username);
if (tu == null) return BadRequest(new FailedResponse("User not found!"));
if (u == tu) return BadRequest(new FailedResponse("Not able to update the role on self-own repository!"));
var rp = await dbContext.Repositories
.Include(repository => repository.Members)
.ThenInclude(repositoryMember => repositoryMember.User)
.FirstOrDefaultAsync(rp => rp.Name == repositoryName && u == rp.Owner);
if (rp == null) return BadRequest(new FailedResponse("Repository not found!"));
var m = rp.Members.FirstOrDefault(m => m.User == tu);
if (m == null)
{
m = new RepositoryMember
{
User = tu,
Role = r.Role ?? RepositoryRole.Guest
};
rp.Members.Add(m);
}
else
{
m.Role = r.Role ?? RepositoryRole.Guest;
}
await dbContext.SaveChangesAsync();
return Ok();
}
[HttpPost("delete_user/{repositoryName}")]
public async Task<IActionResult> DeleteUserAsync(string repositoryName, [FromBody] RepoUserRole r)
{
if (string.IsNullOrWhiteSpace(repositoryName) || repositoryName.Length <= 3)
return BadRequest(new FailedResponse("Repository name is empty or too short!"));
var u = (await userManager.GetUserAsync(HttpContext.User))!;
var tu = await userManager.FindByNameAsync(r.Username);
if (tu == null) return BadRequest(new FailedResponse("User not found!"));
if (u == tu) return BadRequest(new FailedResponse("Not able to update the role on self-own repository!"));
var rp = await dbContext.Repositories
.Include(repository => repository.Members)
.ThenInclude(repositoryMember => repositoryMember.User)
.FirstOrDefaultAsync(rp => rp.Name == repositoryName && u == rp.Owner);
if (rp == null) return BadRequest(new FailedResponse("Repository not found!"));
var m = rp.Members.FirstOrDefault(m => m.User == tu);
if (m == null) return BadRequest(new FailedResponse("User is not being granted to this repository!"));
rp.Members.Remove(m);
await dbContext.SaveChangesAsync();
return Ok();
}
}