Skip to content

Commit

Permalink
Fixes #257 - Update JavaDoc
Browse files Browse the repository at this point in the history
  • Loading branch information
mnriem committed Feb 2, 2025
1 parent 55ab156 commit 7d7607f
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 43 deletions.
39 changes: 15 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

[![build](https://github.com/manorrock/aegean/actions/workflows/build.yml/badge.svg)](https://github.com/manorrock/aegean/actions/workflows/build.yml)

This project delivers a HTTP-based Git repository server.
This project delivers an HTTP-based Git repository server.

## Start the server

In an empty directory of your choice use the following command line to start
In an empty directory of your choice, use the following command line to start
Manorrock Aegean:

```shell
Expand All @@ -15,57 +15,52 @@ Manorrock Aegean:

## Verify the server is up and running

To verify the container is up and running execute the command below:
To verify the container is up and running, execute the command below:

```
```shell
git clone http://localhost:8080/aegean/repositories/test.git
```

You should see output similar to below:
You should see output similar to the below:

```
```shell
Cloning into 'test'...
warning: You appear to have cloned an empty repository.
```

Congratulations you are now running Manorrock Aegean!
Congratulations, you are now running Manorrock Aegean!

## How do I prevent anonymous users from creating new repositories?

To prevent anonymous users from creating new repositories you can set the AEGEAN_ADMIN_USERNAME and AEGEAN_ADMIN_PASSWORD environment variables. See the example below:
To prevent anonymous users from creating new repositories, set the `AEGEAN_ADMIN_USERNAME` and `AEGEAN_ADMIN_PASSWORD` environment variables. See the example below:

```shell
docker run --rm -d -it -p 8080:8080 -v $PWD:/mnt -e AEGEAN_ADMIN_USERNAME=admin -e AEGEAN_ADMIN_PASSWORD=adminadmin ghcr.io/manorrock/aegean
```

Note that if you want to create a new repository you will need to use the -c extraHeader option with the git clone command to provide the admin credentials
as illustrated below:
If you want to create a new repository, use the `-c extraHeader` option with the git clone command to provide the admin credentials, as illustrated below:

```shell
git clone -c http.extraHeader="Authorization: Basic $(echo -n 'admin:adminadmin' | base64)" http://localhost:8080/aegean/repositories/test.git
```

Once you have done this the repository is created and available for any user to clone.
Once you have done this, the repository is created and available for any user to clone.

## Can I disable anonymous access to the server?

Yes, you can disable anonymous access to the server by setting the AEGEAN_ANONYMOUS_DISABLED environment variable to true. Note that if you do so you will also need to provide the admin credentials as described above to be able to interact with the server.
Yes, you can disable anonymous access to the server by setting the `AEGEAN_ANONYMOUS_DISABLED` environment variable to `true`. If you do so, you will also need to provide the admin credentials as described above to interact with the server.

```shell
docker run --rm -d -it -p 8080:8080 -v $PWD:/mnt -e AEGEAN_ANONYMOUS_DISABLED=true ghcr.io/manorrock/aegean
```

## What is the future of this project?

This project will not be developed into a full blown code hosting platform,
but rather keep it simple and focus on delivering simple Git repository
hosting for personal use. If you need more than that we recommend you look at
GitHub, GitLab, Bitbucket, Gitea, GitBucket or any of the other code
hosting platforms available.
This project will not be developed into a full-blown code hosting platform. It will keep it simple and focus on delivering a Git repository hosting for personal use. If you need more than that, we recommend you look at GitHub, GitLab, Bitbucket, Gitea, GitBucket, or any of the other code hosting platforms available.

## Technologies used

The following technologies where used to deliver this project:
The following technologies were used to deliver this project:

1. [Eclipse JGit](https://www.eclipse.org/jgit/)
2. [Jakarta CDI](https://jakarta.ee/specifications/cdi/)
Expand All @@ -78,14 +73,10 @@ The following technologies where used to deliver this project:

See [Contributing](CONTRIBUTING.md)

## Our code of Conduct
## Our Code of Conduct

See [Code of Conduct](CODE_OF_CONDUCT.md)


## Important notice

Note if you file issues or answer questions on the issue tracker and/or issue
pull requests you agree that those contributions will be owned by Manorrock.com
and that Manorrock.com can use those contributions in any manner Manorrock.com
so desires.
Note that if you file issues or answer questions on the issue tracker and/or issue pull requests, you agree that those contributions will be owned by Manorrock.com. Manorrock.com can use those contributions in any manner Manorrock.com desires.
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
</organization>
<properties>
<!-- dependencies -->
<glassfish.version>7.0.21</glassfish.version>
<jakarta.jakartaee-web-api.version>10.0.0</jakarta.jakartaee-web-api.version>
<jgit.version>7.1.0.202411261347-r</jgit.version>
<junit.version>5.11.4</junit.version>
Expand Down Expand Up @@ -105,6 +106,9 @@
</buildx>
<contextDir>${basedir}</contextDir>
<dockerFile>src/main/docker/Dockerfile</dockerFile>
<args>
<GLASSFISH_VERSION>${glassfish.version}</GLASSFISH_VERSION>
</args>
</build>
<run>
<ports>
Expand Down
2 changes: 1 addition & 1 deletion src/main/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM eclipse-temurin:21
ARG GLASSFISH_VERSION
RUN apt-get update && apt-get install -y unzip && \
cd /opt && \
export GLASSFISH_VERSION=7.0.21 && \
curl --insecure -L -O https://download.eclipse.org/ee4j/glassfish/glassfish-${GLASSFISH_VERSION}.zip && \
unzip glassfish-${GLASSFISH_VERSION}.zip && \
mv glassfish7 glassfish && \
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/com/manorrock/aegean/GitApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import jakarta.enterprise.context.ApplicationScoped;

/**
* The one and only application bean.
* The one and only application.
*
* @author Manfred Riem ([email protected])
*/
Expand All @@ -50,7 +50,14 @@ public class GitApplication {
private File repositoriesDirectory;

/**
* Initialize.
* Initialize the application.
*
* This method is called once after the application is constructed. It sets
* up the repositories directory where Git repositories will be stored. The
* directory path is determined by the "ROOT_DIRECTORY" environment variable
* or system property. If neither is set, it defaults to a directory under
* the user's home directory. If the repositories directory does not exist,
* it is created.
*/
@PostConstruct
public void initialize() {
Expand Down
31 changes: 30 additions & 1 deletion src/main/java/com/manorrock/aegean/GitHttpServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import org.eclipse.jgit.http.server.GitFilter;

/**
* The Git HTTP servlet.
* The Git HttpServlet.
*
* @author Manfred Riem ([email protected])
*/
Expand Down Expand Up @@ -81,6 +81,18 @@ public void destroy() {
filter.destroy();
}

/**
* Initialize the servlet.
*
* This method is called once when the servlet is first loaded into memory.
* It initializes the Git filter and sets up the repository resolver and
* upload size limit based on the servlet configuration.
*
* @param config the ServletConfig object that contains
* configuration information for this servlet.
* @throws ServletException if an exception occurs that interrupts
* the servlet's normal operation.
*/
@Override
public void init(final ServletConfig config) throws ServletException {

Expand Down Expand Up @@ -132,6 +144,23 @@ public ServletContext getServletContext() {
});
}

/**
* Process an HTTP request.
*
* This method is called for each HTTP request to the servlet. It uses the
* Git filter to handle the request. If the request is not an HTTP-based
* request that the Git filter can process, it sends a 404 error indicating
* that the requested resource is not found.
*
* @param request the HttpServletRequest object that contains
* the request the client has made of the servlet.
* @param response the HttpServletResponse object that contains
* the response the servlet sends to the client.
* @throws ServletException if an exception occurs that interferes
* with the servlet's normal operation.
* @throws IOException if an input or output error is detected
* when the servlet handles the request.
*/
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/com/manorrock/aegean/GitRepositoryResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ public GitRepositoryResolver(File gitDirectory) {
/**
* Open the repository.
*
* This method attempts to open an existing Git repository. If the repository
* does not exist, it will create a new one if the user has the appropriate
* permissions.
*
* @param request the HTTP servlet request.
* @param name the repository name.
* @return the repository.
Expand Down Expand Up @@ -111,8 +115,10 @@ public Repository open(HttpServletRequest request, String name)
}

/**
* Create the repository
*
* Create the repository.
*
* This method creates a new Git repository in the specified directory.
*
* @param directory the repository directory.
* @param directoryName the repository directory name.
* @throws RepositoryNotFoundException if the repository cannot be created.
Expand Down
32 changes: 31 additions & 1 deletion src/main/java/com/manorrock/aegean/SecurityFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
import java.util.Base64;

/**
* The "admin" filter.
* The Security Filter.
*
* @author Manfred Riem ([email protected])
*/
public class SecurityFilter implements Filter {

Expand All @@ -53,10 +55,35 @@ public class SecurityFilter implements Filter {
@Inject
private IdentityStore identityStore;

/**
* Initialize the filter.
*
* @param filterConfig the filter configuration
* @throws ServletException if an error occurs during initialization
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}

/**
* Perform filtering on the request and response.
*
* This method checks if anonymous access is disabled by reading the "anonymousDisabled"
* context parameter. If anonymous access is disabled, it sends a 403 Forbidden response.
*
* If the "Authorization" header is present and starts with "Basic ", it decodes the
* Base64-encoded credentials, extracts the username and password, and validates them
* using the IdentityStore. If the credentials are valid, it wraps the HttpServletRequest
* to provide the authenticated user's principal, roles, and remote user.
*
* Finally, it passes the request and response to the next filter in the chain.
*
* @param request the servlet request
* @param response the servlet response
* @param chain the filter chain
* @throws IOException if an I/O error occurs
* @throws ServletException if a servlet error occurs
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
Expand Down Expand Up @@ -104,6 +131,9 @@ public String getRemoteUser() {
chain.doFilter(httpRequest, httpResponse);
}

/**
* Destroy the filter.
*/
@Override
public void destroy() {
}
Expand Down
22 changes: 19 additions & 3 deletions src/main/java/com/manorrock/aegean/SecurityIdentityStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
import java.util.logging.Logger;

/**
* The "admin" identity store.
* The Security IdentityStore.
*
* @author Manfred Riem ([email protected])
*/
@ApplicationScoped
public class SecurityIdentityStore implements IdentityStore {
Expand Down Expand Up @@ -66,19 +68,33 @@ public class SecurityIdentityStore implements IdentityStore {

/**
* Initialize the identity store.
* <p>
* This method is called after the bean's properties have been initialized.
* It retrieves the admin username and password from the servlet context's
* initialization parameters and logs the initialization status.
*/
@PostConstruct
public void init() {
adminUsername = servletContext.getInitParameter("adminUsername");
adminPassword = servletContext.getInitParameter("adminPassword");
if (adminUsername != null && !adminUsername.isEmpty()) {
LOGGER.info("AdminIdentityStore initialized with adminUsername: " + adminUsername);
LOGGER.info("SecurityIdentityStore initialized with adminUsername: " + adminUsername);
}
if (adminPassword != null && !adminPassword.isEmpty()) {
LOGGER.info("AdminIdentityStore initialized with adminPassword: " + "********");
LOGGER.info("SecurityIdentityStore initialized with adminPassword: " + "********");
}
}

/**
* Validate the provided credential.
* <p>
* This method checks if the provided credential matches the admin username
* and password. If they match, it returns a valid CredentialValidationResult
* with the admin role. Otherwise, it returns a not validated result.
*
* @param credential the credential to validate
* @return the result of the credential validation
*/
@Override
public CredentialValidationResult validate(Credential credential) {
if (adminUsername == null || adminUsername.isEmpty() || adminPassword == null || adminPassword.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
import java.util.logging.Logger;

/**
* The Admin Servlet Container Initializer.
*
* This initializer sets the admin username and password context parameters
* based on the environment variables or system properties AEGEAN_ADMIN_USERNAME and AEGEAN_ADMIN_PASSWORD.
* The Security ServletContainerInitializer.
*
* @author Manfred Riem ([email protected])
*/
Expand All @@ -21,8 +18,19 @@ public class SecurityServletContainerInitializer implements ServletContainerInit
*/
private static final Logger LOGGER = Logger.getLogger(SecurityServletContainerInitializer.class.getName());

/**
* Called when the application is starting up.
* <p>
* This method sets the context parameters for admin username, admin password,
* and anonymous access disabled based on environment variables or system
* properties when found.
*
* @param classes the set of classes
* @param servletContext the servlet context
* @throws ServletException when a servlet error occurs
*/
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
public void onStartup(Set<Class<?>> classes, ServletContext servletContext) throws ServletException {
String adminUsername = System.getenv("AEGEAN_ADMIN_USERNAME");
if (adminUsername != null) {
LOGGER.info("Admin username obtained from environment variable AEGEAN_ADMIN_USERNAME");
Expand All @@ -34,7 +42,7 @@ public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletExcepti
}

if (adminUsername != null) {
ctx.setInitParameter("adminUsername", adminUsername);
servletContext.setInitParameter("adminUsername", adminUsername);
}

String adminPassword = System.getenv("AEGEAN_ADMIN_PASSWORD");
Expand All @@ -48,7 +56,7 @@ public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletExcepti
}

if (adminPassword != null) {
ctx.setInitParameter("adminPassword", adminPassword);
servletContext.setInitParameter("adminPassword", adminPassword);
}

String anonymousDisabled = System.getenv("AEGEAN_ANONYMOUS_DISABLED");
Expand All @@ -57,12 +65,13 @@ public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletExcepti
} else {
anonymousDisabled = System.getProperty("com.manorrock.aegean.anonymousDisabled");
if (anonymousDisabled != null) {
LOGGER.info("Anonymous access disabled obtained from system property com.manorrock.aegean.anonymousDisabled");
LOGGER.info(
"Anonymous access disabled obtained from system property com.manorrock.aegean.anonymousDisabled");
}
}

if (anonymousDisabled != null) {
ctx.setInitParameter("anonymousDisabled", anonymousDisabled);
servletContext.setInitParameter("anonymousDisabled", anonymousDisabled);
}
}
}

0 comments on commit 7d7607f

Please sign in to comment.