Skip to content

Commit

Permalink
Merge branch 'master' into word-card-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
imnasnainaec committed Oct 9, 2024
2 parents 8da5951 + 0dc83d0 commit 9c72680
Show file tree
Hide file tree
Showing 51 changed files with 1,884 additions and 4,122 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
objects.githubusercontent.com:443
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup dotnet
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # v4.0.1
with:
dotnet-version: ${{ matrix.dotnet }}
- name: Install ffmpeg
Expand Down Expand Up @@ -128,7 +128,7 @@ jobs:
# Manually install .NET to work around:
# https://github.com/github/codeql-action/issues/757
- name: Setup .NET
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # v4.0.1
with:
dotnet-version: "8.0.x"
- name: Initialize CodeQL
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/combine_deploy_image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ jobs:
security.ubuntu.com:80
sts.us-east-1.amazonaws.com:443
- name: Set up QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/commit_message_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ permissions: # added using https://github.com/step-security/secure-workflows

jobs:
commit-message-lint:
uses: sillsdev/FieldWorks/.github/workflows/CommitMessage.yml@9972c2aa3ad9fa768bd82714208152c4b6ce6b2c
uses: sillsdev/FieldWorks/.github/workflows/CommitMessage.yml@ba50e637df9593a2a972b29bf670226e89c0a21b
4 changes: 2 additions & 2 deletions .github/workflows/frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public/scripts/config.js
.eslintcache
Session.vim
scripts/*.js
!scripts/createBackendLicenses.js
!scripts/printVersion.js
!scripts/setRelease.js

Expand Down Expand Up @@ -58,6 +59,7 @@ mongo_database

# User Guide
docs/user_guide/site
backend_licenses.json

# Python
.tox
Expand Down
2 changes: 1 addition & 1 deletion Backend.Tests/Backend.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<NoWarn>$(NoWarn);CA1305;CA1859;CS1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="NUnit" Version="4.2.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="coverlet.collector" Version="6.0.2"/>
Expand Down
193 changes: 166 additions & 27 deletions Backend.Tests/Controllers/UserRoleControllerTests.cs

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Backend/BackendFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.3" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.5.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.1" />
<PackageReference Include="MailKit" Version="4.7.1.1" />
<PackageReference Include="MongoDB.Driver" Version="2.28.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.3" />
<PackageReference Include="MailKit" Version="4.8.0" />
<PackageReference Include="MongoDB.Driver" Version="2.29.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.8.1" />
<PackageReference Include="Xabe.FFmpeg" Version="5.2.6"/>

<!-- SIL Maintained Dependencies. -->
Expand Down
114 changes: 114 additions & 0 deletions Backend/Controllers/UserRoleController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BackendFramework.Helper;
using BackendFramework.Interfaces;
Expand Down Expand Up @@ -147,6 +148,13 @@ public async Task<IActionResult> CreateUserRole(string projectId, [FromBody, Bin
return NotFound(projectId);
}

// Prevent a second project owner
if (userRole.Role == Role.Owner
&& (await _userRoleRepo.GetAllUserRoles(projectId)).Any((role) => role.Role == Role.Owner))
{
return Forbid("This project already has an owner");
}

await _userRoleRepo.Create(userRole);
return Ok(userRole.Id);
}
Expand Down Expand Up @@ -183,6 +191,12 @@ public async Task<IActionResult> DeleteUserRole(string projectId, string userId)
return NotFound(userRoleId);
}

// Prevent deleting the project owner.
if (userRole.Role == Role.Owner)
{
return Forbid("Cannot use this function to remove the project owner's role");
}

// Prevent deleting role of another user who has more permissions than the actor.
if (!await _permissionService.ContainsProjectRole(HttpContext, userRole.Role, projectId))
{
Expand Down Expand Up @@ -212,6 +226,11 @@ public async Task<IActionResult> UpdateUserRole(
return Forbid();
}

// Prevent making a new project owner.
if (projectRole.Role == Role.Owner)
{
return Forbid("Cannot use this function to give a user the project owner role");
}
// Prevent upgrading another user to have more permissions than the actor.
if (!await _permissionService.ContainsProjectRole(HttpContext, projectRole.Role, projectId))
{
Expand Down Expand Up @@ -248,6 +267,11 @@ public async Task<IActionResult> UpdateUserRole(
return NotFound(userRoleId);
}

// Prevent downgrading the project owner.
if (userRole.Role == Role.Owner)
{
return Forbid("Cannot use this function to change the project owner's role");
}
// Prevent downgrading another user who has more permissions than the actor.
if (!await _permissionService.ContainsProjectRole(HttpContext, userRole.Role, projectId))
{
Expand All @@ -263,5 +287,95 @@ public async Task<IActionResult> UpdateUserRole(
_ => StatusCode(StatusCodes.Status304NotModified, userRoleId)
};
}

/// <summary>
/// Change project owner from user with first specified id to user with second specified id.
/// Can only be used by the project owner or a site admin.
/// </summary>
/// <returns> Id of updated UserRole </returns>
[HttpGet("changeowner/{oldUserId}/{newUserId}", Name = "ChangeOwner")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string))]
public async Task<IActionResult> ChangeOwner(string projectId, string oldUserId, string newUserId)
{
// Ensure the actor has sufficient permission to change project owner
if (!await _permissionService.ContainsProjectRole(HttpContext, Role.Owner, projectId))
{
return Forbid();
}

// Ensure that the old and new owners' ids are different
if (oldUserId.Equals(newUserId, System.StringComparison.OrdinalIgnoreCase))
{
return BadRequest($"the user ids for the old and new owners should be different");
}

// Ensure the project exists
var proj = await _projRepo.GetProject(projectId);
if (proj is null)
{
return NotFound(projectId);
}

// Fetch the users
var oldOwner = await _userRepo.GetUser(oldUserId, false);
if (oldOwner is null)
{
return NotFound(oldUserId);
}
var newOwner = await _userRepo.GetUser(newUserId, false);
if (newOwner is null)
{
return NotFound(newUserId);
}

// Ensure that the user from whom ownership is being moved is the owner
if (!oldOwner.ProjectRoles.TryGetValue(projectId, out var oldRoleId))
{
return BadRequest($"{oldUserId} is not a project user");
}
var oldUserRole = await _userRoleRepo.GetUserRole(projectId, oldRoleId);
if (oldUserRole is null || oldUserRole.Role != Role.Owner)
{
return BadRequest($"{oldUserId} is not the project owner");
}

// Add or update the role of the new owner
ResultOfUpdate newResult;
if (!newOwner.ProjectRoles.TryGetValue(projectId, out var newRoleId))
{
// Generate the userRole
var newUsersRole = new UserRole { ProjectId = projectId, Role = Role.Owner };
newUsersRole = await _userRoleRepo.Create(newUsersRole);
newRoleId = newUsersRole.Id;

// Update the user
newOwner.ProjectRoles.Add(projectId, newRoleId);
newResult = await _userRepo.Update(newOwner.Id, newOwner);
}
else
{
// Update the user role
var newUsersRole = await _userRoleRepo.GetUserRole(projectId, newRoleId);
if (newUsersRole is null)
{
return NotFound(newRoleId);
}
newUsersRole.Role = Role.Owner;
newResult = await _userRoleRepo.Update(newRoleId, newUsersRole);
}
if (newResult != ResultOfUpdate.Updated)
{
return StatusCode(StatusCodes.Status304NotModified, newRoleId);
};

// Change the old owner to a project admin
oldUserRole.Role = Role.Administrator;
var oldResult = await _userRoleRepo.Update(oldRoleId, oldUserRole);
return oldResult switch
{
ResultOfUpdate.Updated => Ok(oldUserRole),
_ => StatusCode(StatusCodes.Status304NotModified, oldUserRole)
};
}
}
}
2 changes: 1 addition & 1 deletion Backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
############################################################

# Docker multi-stage build
FROM mcr.microsoft.com/dotnet/sdk:8.0.401-jammy AS builder
FROM mcr.microsoft.com/dotnet/sdk:8.0.402-jammy AS builder
WORKDIR /app

# Copy csproj and restore (fetch dependencies) as distinct layers.
Expand Down
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,10 @@ A rapid word collection tool. See the [User Guide](https://sillsdev.github.io/Th
- If using [homebrew](https://formulae.brew.sh/formula/ffmpeg): `brew install ffmpeg`
- If manually installing from the FFmpeg website, install both `ffmpeg` and `ffprobe`

9. [dotnet-format](https://github.com/dotnet/format): `dotnet tool update --global dotnet-format --version 5.1.250801`
10. [dotnet-reportgenerator](https://github.com/danielpalme/ReportGenerator)
`dotnet tool update --global dotnet-reportgenerator-globaltool --version 5.0.4`
11. [dotnet-project-licenses](https://github.com/tomchavakis/nuget-license)
`dotnet tool update --global dotnet-project-licenses`
12. Tools for generating the self installer (Linux only):
9. [dotnet-reportgenerator](https://github.com/danielpalme/ReportGenerator)
`dotnet tool update --global dotnet-reportgenerator-globaltool --version 5.0.4`
10. [nuget-license](https://github.com/sensslen/nuget-license) `dotnet tool update --global nuget-project-license`
11. Tools for generating the self installer (Linux only):

- [makeself](https://makeself.io/) - a tool to make self-extracting archives in Unix
- [pandoc](https://pandoc.org/installing.html#linux) - a tool to convert Markdown documents to PDF.
Expand Down Expand Up @@ -589,8 +587,8 @@ When _Rancher Desktop_ is first run, you will be prompted to select a few initia
1. Verify that _Enable Kubernetes_ is checked.
2. Select the Kubernetes version marked as _stable, latest_.
3. Select your container runtime, either _containerd_ or _dockerd (moby)_:
- _containerd_ matches what is used on the NUC and uses the `k3s` Kubernetes engine. It requires that you run the
`build.py` script with the `--nerdctl` option.
- _containerd_ matches what is used on the NUC and uses the `k3s` Kubernetes engine. It requires that you set the
`CONTAINER_CLI` environment variable to `nerdctl` before running the `build.py` script.
- _dockerd_ uses the `k3d` (`k3s` in docker).
4. Select _Automatic_ or _Manual_ path setup.
5. Click _Accept_.
Expand Down Expand Up @@ -680,7 +678,7 @@ Notes:
export CONTAINER_CLI="nerdctl"
```

If you are using _Docker Desktop_ or _Rancher Desktop_ with the `dockerd` container runtime, clear this variable or
If you are using _Rancher Desktop_ with the `dockerd` container runtime or _Docker Desktop_, clear this variable or
set its value to `docker`.

- Run with the `--help` option to see all available options.
Expand Down
File renamed without changes.
File renamed without changes.
8 changes: 5 additions & 3 deletions deploy/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#
# pip-compile requirements.in
#
ansible==10.3.0
ansible==10.4.0
# via -r requirements.in
ansible-core==2.17.3
ansible-core==2.17.4
# via ansible
cachetools==5.5.0
# via google-auth
Expand All @@ -22,6 +22,8 @@ cryptography==43.0.1
# via
# ansible-core
# pyopenssl
durationpy==0.8
# via kubernetes
google-auth==2.34.0
# via kubernetes
idna==3.8
Expand All @@ -33,7 +35,7 @@ jinja2==3.1.4
# jinja2-base64-filters
jinja2-base64-filters==0.1.4
# via -r requirements.in
kubernetes==30.1.0
kubernetes==31.0.0
# via -r requirements.in
markupsafe==2.1.5
# via jinja2
Expand Down
2 changes: 1 addition & 1 deletion deploy/scripts/aws_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def list_aws_profiles() -> List[str]:
aws_ver = aws_version()
if aws_ver is not None and aws_ver == 2:
result = run_cmd(["aws", "configure", "list-profiles"], chomp=True)
return result.stdout.split("\n")
return [profile for profile in result.stdout.split("\n") if profile]
return []


Expand Down
Loading

0 comments on commit 9c72680

Please sign in to comment.