Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
* text=auto eol=lf
*.sh text eol=lf
Makefile text eol=lf
.husky/* text eol=lf
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,9 @@ jobs:
distribution: temurin
java-version: "25"
cache: maven
- name: Checkstyle
run: mvn -B checkstyle:check
- name: Check formatting
run: mvn -B spotless:check
- name: Run tests
run: mvn -B test
2 changes: 2 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:

- name: Install frontend deps
run: npm ci
- name: Check formatting
run: npm run format:check

- name: Run frontend checks
run: npm run check
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ Shashank Singh <shashanksgh3@gmail.com>
Jesper Pedersen <jesperpedersen.db@gmail.com>
Adnan Khan <adnan.kriaz@gmail.com>
Mohamed Hamed <alkmohamed40@gmail.com>
Mohammed Naser <mohammednaser2826@gmail.com>
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,4 @@ In your first pull request you need to add yourself to the `AUTHORS` file.

## Code Style

Please, follow the coding style of the project. The frontend is checked with ESLint (`npm run lint` in `src/frontend`), which also runs as a Husky `pre-commit` hook on staged files. Run the full lint and the tests with `make test`.
Please, follow the coding style of the project. Format with `make format` before committing; CI checks formatting of all files. Java is formatted with [google-java-format](https://github.com/google/google-java-format) (2-space indent, Spotless) and is additionally checked with Checkstyle (`make checkstyle`, rules in `checkstyle.xml`). The frontend is formatted with Prettier (the whole `src/frontend` folder) and checked with ESLint (`npm run lint` in `src/frontend`), which also runs as a Husky `pre-commit` hook on staged files. Run the frontend lint, the formatting and Checkstyle checks and the backend test cases with `make test`.
16 changes: 14 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: all clean run test lint check build docs platform-start platform-stop reset frontend setup full
.PHONY: all clean run test lint check build docs platform-start platform-stop reset frontend format format-check checkstyle setup full

all: clean lint run

Expand All @@ -18,6 +18,18 @@ lint: frontend
check: frontend
@npm --prefix src/frontend run check

# Reformats Java (google-java-format) and the frontend (Prettier).
format: frontend
@mvn -B spotless:apply && npm --prefix src/frontend run format

# Checks formatting of Java and the frontend; makes no changes, as CI does.
format-check: frontend
@mvn -B spotless:check && npm --prefix src/frontend run format:check

# Runs the minimal Checkstyle rules (see checkstyle.xml).
checkstyle:
@mvn -B checkstyle:check

build: frontend
@npm --prefix src/frontend run build

Expand All @@ -36,7 +48,7 @@ run: frontend
trap 'kill $$frontend_pid $$backend_pid 2>/dev/null; wait' EXIT INT TERM; \
wait $$backend_pid

test: lint
test: lint format-check checkstyle
@mvn test

docs:
Expand Down
17 changes: 17 additions & 0 deletions checkstyle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">

<!-- Complements google-java-format, which enforces indentation and import
order. Enabled rules: FileTabCharacter, UnusedImports, RedundantImport and
OneStatementPerLine. NeedBraces and AvoidStarImport are not enabled yet -->
<module name="Checker">
<property name="charset" value="UTF-8"/>
<module name="FileTabCharacter"/>
<module name="TreeWalker">
<module name="UnusedImports"/>
<module name="RedundantImport"/>
<module name="OneStatementPerLine"/>
</module>
</module>
5 changes: 4 additions & 1 deletion docs/BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,12 @@ The targets are
* `clean` - Clean
* `lint` - Run the frontend ESLint check
* `check` - Run the frontend checks (lint and build), as CI does
* `format` - Format the backend and the whole `src/frontend` folder (Prettier)
* `format-check` - Check formatting of all files without changing them, as CI does
* `checkstyle` - Run the minimal Checkstyle rules (see `checkstyle.xml`)
* `build` - Build the frontend
* `run` - Run the backend and the frontend in development mode
* `test` - Run the frontend lint and the backend test cases
* `test` - Run the frontend lint, the formatting and Checkstyle checks and the backend test cases
* `docs` - Generate the manual
* `platform-start` - Start compose services (PostgreSQL + Keycloak)
* `platform-stop` - Stop the compose services
Expand Down
1 change: 1 addition & 0 deletions docs/manual/en/97-acknowledgement.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Shashank Singh <shashanksgh3@gmail.com>
Jesper Pedersen <jesperpedersen.db@gmail.com>
Adnan Khan <adnan.kriaz@gmail.com>
Mohamed Hamed <alkmohamed40@gmail.com>
Mohammed Naser <mohammednaser2826@gmail.com>
```

## Contributing
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<dependency><groupId>io.rest-assured</groupId><artifactId>rest-assured</artifactId><scope>test</scope></dependency>
<dependency><groupId>io.quarkus</groupId><artifactId>quarkus-test-security-jwt</artifactId><scope>test</scope></dependency>
</dependencies>
<build><sourceDirectory>src/backend/main/java</sourceDirectory><testSourceDirectory>src/backend/test/java</testSourceDirectory><resources><resource><directory>src/backend/main/resources</directory></resource></resources><testResources><testResource><directory>src/backend/test/resources</directory></testResource></testResources><plugins><plugin><groupId>io.quarkus</groupId><artifactId>quarkus-maven-plugin</artifactId><version>${quarkus.platform.version}</version><extensions>true</extensions><executions><execution><goals><goal>build</goal><goal>generate-code</goal><goal>generate-code-tests</goal></goals></execution></executions></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.14.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>3.5.5</version><configuration><systemPropertyVariables><java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager></systemPropertyVariables></configuration></plugin></plugins></build>
<build><sourceDirectory>src/backend/main/java</sourceDirectory><testSourceDirectory>src/backend/test/java</testSourceDirectory><resources><resource><directory>src/backend/main/resources</directory></resource></resources><testResources><testResource><directory>src/backend/test/resources</directory></testResource></testResources><plugins><plugin><groupId>io.quarkus</groupId><artifactId>quarkus-maven-plugin</artifactId><version>${quarkus.platform.version}</version><extensions>true</extensions><executions><execution><goals><goal>build</goal><goal>generate-code</goal><goal>generate-code-tests</goal></goals></execution></executions></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.14.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>3.5.5</version><configuration><systemPropertyVariables><java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager></systemPropertyVariables></configuration></plugin><plugin><groupId>com.diffplug.spotless</groupId><artifactId>spotless-maven-plugin</artifactId><version>3.11.0</version><configuration><java><includes><include>src/backend/main/java/**/*.java</include><include>src/backend/test/java/**/*.java</include></includes><googleJavaFormat><version>2.0.0</version></googleJavaFormat></java></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-checkstyle-plugin</artifactId><version>3.6.0</version><dependencies><dependency><groupId>com.puppycrawl.tools</groupId><artifactId>checkstyle</artifactId><version>14.4.0</version></dependency></dependencies><configuration><configLocation>${project.basedir}/checkstyle.xml</configLocation><includeTestSourceDirectory>true</includeTestSourceDirectory><consoleOutput>true</consoleOutput><inputEncoding>UTF-8</inputEncoding><outputEncoding>UTF-8</outputEncoding></configuration></plugin></plugins></build>
<profiles>
<profile>
<id>manual-docs</id>
Expand Down
14 changes: 8 additions & 6 deletions src/backend/main/java/ai/mnemosyne/cisys/AllowedImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@
package ai.mnemosyne.cisys;

import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Column;

/** A container image that admins have allowed for builds. */
@Entity
public class AllowedImage extends PanacheEntityBase {
@Id @Column(length = 201) public String name;
@Id
@Column(length = 201)
public String name;

public static final String PATTERN = "[A-Za-z0-9][A-Za-z0-9_./:@-]{0,200}";
public static final String PATTERN = "[A-Za-z0-9][A-Za-z0-9_./:@-]{0,200}";

public static boolean isAllowed(String name) {
return name != null && findById(name) != null;
}
public static boolean isAllowed(String name) {
return name != null && findById(name) != null;
}
}
63 changes: 35 additions & 28 deletions src/backend/main/java/ai/mnemosyne/cisys/BranchResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,51 @@
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.jwt.JsonWebToken;

import java.util.List;
import java.util.Map;
import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/api/projects/{projectId}/branches")
@Produces(MediaType.APPLICATION_JSON)
@Authenticated
public class BranchResource {
@Inject SecurityIdentity identity;
@Inject GitRepositoryService repositories;
@Inject SecurityIdentity identity;
@Inject GitRepositoryService repositories;

public record Branches(List<String> branches, String reason) {}
public record Branches(List<String> branches, String reason) {}

private Project visible(Long id) {
if (!(identity.hasRole("member") || identity.hasRole("lead") || identity.hasRole("admin"))) throw new ForbiddenException();
if (!(identity.getPrincipal() instanceof JsonWebToken jwt) || jwt.getSubject() == null) throw new NotAuthorizedException("Bearer");
Project p = Project.findById(id);
if (p == null || (p.privateRepository && !identity.hasRole("admin") && !jwt.getSubject().equals(p.ownerSubject))) throw new NotFoundException();
return p;
}
private Project visible(Long id) {
if (!(identity.hasRole("member") || identity.hasRole("lead") || identity.hasRole("admin")))
throw new ForbiddenException();
if (!(identity.getPrincipal() instanceof JsonWebToken jwt) || jwt.getSubject() == null)
throw new NotAuthorizedException("Bearer");
Project p = Project.findById(id);
if (p == null
|| (p.privateRepository
&& !identity.hasRole("admin")
&& !jwt.getSubject().equals(p.ownerSubject))) throw new NotFoundException();
return p;
}

@GET
public Response list(@PathParam("projectId") Long projectId) {
Project project = visible(projectId);
if (project.privateRepository) {
return Response.ok(new Branches(List.of(), "private_repository")).build();
}
try {
return Response.ok(new Branches(repositories.listBranches(project), null)).build();
} catch (IllegalArgumentException e) {
return error(400, e.getMessage());
} catch (GitRepositoryService.BranchLookupException e) {
return error(502, e.getMessage());
}
@GET
public Response list(@PathParam("projectId") Long projectId) {
Project project = visible(projectId);
if (project.privateRepository) {
return Response.ok(new Branches(List.of(), "private_repository")).build();
}

private static Response error(int status, String message) {
return Response.status(status).type(MediaType.APPLICATION_JSON).entity(Map.of("error", message)).build();
try {
return Response.ok(new Branches(repositories.listBranches(project), null)).build();
} catch (IllegalArgumentException e) {
return error(400, e.getMessage());
} catch (GitRepositoryService.BranchLookupException e) {
return error(502, e.getMessage());
}
}

private static Response error(int status, String message) {
return Response.status(status)
.type(MediaType.APPLICATION_JSON)
.entity(Map.of("error", message))
.build();
}
}
26 changes: 19 additions & 7 deletions src/backend/main/java/ai/mnemosyne/cisys/Branding.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,23 @@

@Entity
public class Branding {
@Id public Long id = 1L;
@Column(nullable = false, length = 80) public String name = "cisys";
@Column(nullable = false, length = 7) public String headerColor = "#176a4a";
@Column(nullable = false, length = 7) public String headingColor = "#176a4a";
@Column(nullable = false, length = 7) public String buttonColor = "#176a4a";
@Column(length = 350000) public String logo;
@Column(length = 350000) public String background;
@Id public Long id = 1L;

@Column(nullable = false, length = 80)
public String name = "cisys";

@Column(nullable = false, length = 7)
public String headerColor = "#176a4a";

@Column(nullable = false, length = 7)
public String headingColor = "#176a4a";

@Column(nullable = false, length = 7)
public String buttonColor = "#176a4a";

@Column(length = 350000)
public String logo;

@Column(length = 350000)
public String background;
}
Loading
Loading