Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ configurations.configureEach {

dependencies {

// Required by Sharing Platform
implementation group: 'org.codeability', name: 'SharingPluginPlatformAPI', version: '1.2.1'
// Required by Spring cloud
implementation "org.apache.httpcomponents.client5:httpclient5:5.5.1"
implementation "org.apache.httpcomponents.core5:httpcore5:5.3.6"
Expand Down Expand Up @@ -506,7 +508,7 @@ dependencies {
testImplementation "org.junit.platform:junit-platform-launcher:${junit_platform_version}"
}

// we have to apply the test.gradle file after the dependencies block, otherwise we get the error Cannot change dependencies of dependency configuration ":mockitoAgent" after it has been resolved
// we have to apply the test.gradle file after the dependencies block, otherwise we get the error Cannot change dependencies of dependency configuration ':mockitoAgent' after it has been resolved
apply from: "gradle/test.gradle"
apply from: "gradle/openapi.gradle"

Expand Down
2 changes: 1 addition & 1 deletion docker/artemis/config/dev-local-vc-local-ci.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# https://docs.artemis.cit.tum.de/dev/setup.html#debugging-with-docker
_JAVA_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

SPRING_PROFILES_ACTIVE: artemis,scheduling,localci,localvc,buildagent,core,dev,docker
SPRING_PROFILES_ACTIVE: artemis,scheduling,localci,localvc,buildagent,core,dev,docker,sharing

# Integrated Code Lifecycle settings with Jira
ARTEMIS_USERMANAGEMENT_USEEXTERNAL="false"
Expand Down
1 change: 1 addition & 0 deletions docs/admin/extension-services.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ Other Extension Services
setup/hermes
setup/hyperion
setup/aeolus
setup/sharing
96 changes: 96 additions & 0 deletions docs/admin/setup/sharing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.. _sharing-setup:

.. |sharing_health1| image:: sharing/sharing_health1.png
.. |sharing_health2| image:: sharing/sharing_health2.png
.. |sharing_button1| image:: sharing/sharingButtonArtemis.png
.. |sharing_button2| image:: sharing/sharingButtonSharing.png

Setup Guide for Exchange with the Sharing Platform
==================================================

.. contents::
:local:

Background
----------

The `Sharing Platform <https://search.sharing-codeability.uibk.ac.at/>`_ is an open platform for sharing teaching materials related to programming. It is operated by the `University of Innsbruck <https://www.uibk.ac.at/en/>`_. While primarily designed as an open exchange platform, it also provides features such as private group exchanges and the ability to restrict public access to certain content, such as the solution repository of an Artemis exercise.

For more details, visit the `help menu <https://search.sharing-codeability.uibk.ac.at/>`_ of the sharing platform.

To facilitate the exchange of programming exercises among instructors, the sharing platform offers a connector to Artemis, enabling any Artemis instance to integrate with the platform for seamless sharing.

The `Sharing Platform` is open source. The source code can be found at https://sharing-codeability.uibk.ac.at/development/sharing/codeability-sharing-platform .

Prerequisites
-------------

To connect to the sharing platform, you need an API key. To request one, contact the platform maintainers at `[email protected]` and provide the URL of your active Artemis instance.

**Important:** Sharing only works if your Artemis instance is accessible on the internet. If making your instance publicly available is not an option, the maintainers can provide a list of required Artemis URLs that must be accessible to the sharing platform.

**Configuration**
~~~~~~~~~~~~~~~~~

Once you receive your API key, you should add it to the configuration file **``application-core.yml``** or your `.env` file:

**Option 1: application-artemis.yml**
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: yaml

artemis:
sharing:
enabled: true
# Shared common secret
apikey: <your API Key>
serverurl: https://search.sharing-codeability.uibk.ac.at/
actionname: Export to Artemis@myUniversity

**Option 2: .env file for Docker initialization**
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: bash

ARTEMIS_SHARING_ENABLED=true
ARTEMIS_SHARING_SERVERURL=https://search.sharing-codeability.uibk.ac.at/
ARTEMIS_SHARING_APIKEY=<Enter your API Key here>
ARTEMIS_SHARING_ACTIONNAME=Export to Artemis@<Enter an ID here>

Once configured, restart your Artemis instance.

**Instructor Access Requirements**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For instructors to exchange programming exercises, they need an account on the sharing platform. They can register using one of the following methods:

- **EduID Authentication**: The simplest way is through `EduID (Austria) <https://www.aco.net/federation.html>`_ or `EduID (Germany) <https://doku.tid.dfn.de/de:aai:eduid:start>`_. Forward the necessary connection details to the sharing platform maintainers.
- **GitLab-Based Registration**: If EduID is not an option, users can register via the sharing platform’s GitLab instance. However, for security reasons, self-registration is restricted to certain email domains. To enable access, forward the desired domains to the maintainers for approval.

Troubleshooting
---------------

To assist in troubleshooting, the **sharing profile** includes an additional health indicator, accessible via the **``Administration -> Health``** menu.

|sharing_health1|

Under **Details**, you will typically find the following entries:

|sharing_health2|

- The **first entry** is an initialization request sent after startup.
- The **second entry** reflects the subsequent receipt of the connector configuration from the sharing platform.
- Additional entries represent regular configuration polling requests from the sharing platform.

The **Details** log stores the last 10 entries.

If the health status is not **``up``**, check the error message in the details. If the issue is unclear, feel free to contact the sharing platform maintainers for support.

Conclusion
----------

Once everything is set up correctly, you should see the |sharing_button1| button in the **Programming Exercise Details** dialog in Artemis.

Similarly, the |sharing_button2| button should appear on the sharing platform for any programming exercise available there.

Before testing the import and export functionality, refer to the user documentation at :ref:`sharing` for further details.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/admin/setup/sharing/sharing_health1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/admin/setup/sharing/sharing_health2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ All these exercises are supposed to be run either live in the lecture with insta
user/markdown-support
user/integrated-code-lifecycle
user/exports
user/sharing
user/mobile-applications
user/lti

Expand Down
109 changes: 109 additions & 0 deletions docs/user/sharing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
.. |sharing_button1| image:: ../admin/setup/sharing/sharingButtonArtemis.png
.. |sharing_metadata| image:: sharing/sharing_metadata.png
:width: 50%
.. |sharing_metadata2| image:: sharing/sharing_metadata2.png
:width: 50%
.. |sharing_namespace| image:: sharing/sharing_namespace.png
:width: 50%
.. |sharing_success| image:: sharing/sharing_success.png
:width: 50%
.. |sharing_search| image:: sharing/sharing_search.png
:width: 50%
.. |sharing_export| image:: sharing/sharing_export.png
:width: 50%
.. |artemis_import| image:: sharing/artemis_import.png
:width: 50%
.. |artemis_import2| image:: sharing/artemis_import2.png
:width: 50%





.. _sharing:

Sharing
=======

Background
----------

The `Sharing Platform <https://search.sharing-codeability.uibk.ac.at/>`_ is an open sharing platform for teaching material for
teaching programming skills. It is operated by the `University of Innsbruck <https://www.uibk.ac.at/en/>`_. Although mainly an open exchange platform, it
additionally provides various features, like private exchange in a closed user group, or the non disclosure of certain content
like the solution repository of an artemis exercise to the public. Users can easily import and export single programming exercises via the Sharing Platform.

Your Artemis administrator may activate the `sharing`-profile. If this profile is enabled, you see an |sharing_button1|-Button in the exercise detail view.

Preliminaries
-------------

Exporting only possible, if you have also an account on the Sharing Platform. Please contact your administrator, whether you can log in
via `eduID <https://www.aco.net/technologien.html>`_ or use the `self-registration option of the sharing platform <https://sharing-codeability.uibk.ac.at/users/sign_in>`_.

To export an exercise, ensure you are already logged into the Sharing Platform in advance [1]_ .

.. [1] Due to a problem in the sharing platform, you must be logged in in the same tab/window as the artemis application. If you are not logged in, you may be requested to re-login and are forwarded to the main page of the sharing platform. In this case go back to artemis and repeat the export.

Export to the Sharing Platform
------------------------------

In the exercise detail view click on the |sharing_button1|-Button.
You are forwarded to the import functionality of the Sharing Platform. You may be asked to log in again in the current tab.

|sharing_metadata|

Here you should add/correct the relevant metadata. Most important is the description field, which should give other users a hint, what
the programming exercise is about. Also add further keywords as you like.

|sharing_metadata2|

Finally you should add the creators of the exercise. The first row should be prefilled with yourself. You can add additional rows.

The sharing platform distinguishes between creators/authors and publishers. The publishers are those that take care for publishing on the sharing platform, however
may not necessarily coincide with the creators/authors.

The full metadata is listed on `this page <https://search.sharing-codeability.uibk.ac.at/pages/en/publishers/howto>`_. fields than shown on this short page. You are welcome to add further data, however you have to edit it in the metadata.yaml file of your git repository.

If all required meta data is correct, you can import the exercise into the sharing platform by hitting the submit-Button.
Next you can select the GitLab namespace where your exercise should go:

|sharing_namespace|

This list contains GitLab namespaces you can submit to (i.e. where you have at least maintainer access).

After selection the correct namespace you should see:

|sharing_success|

The “Back to Artemis” button should forward you back to the Artemis application.

In case of an error you might see a corresponding message. Please correct the error, or contact the maintainers of the sharing platform.

Import from the Sharing Platform
--------------------------------

The import from the sharing platform starts on the sharing platform.
Please ensure that you are logged in, because exports only work for authorized users.

You can list all exercises by entering "artemis" into the format field. Of course you can also add further search parameters into the other fields:

|sharing_search|

After clicking on "More ..." you should see the details page, with an export option at the bottom:

|sharing_export|.

The click on the export button will forward you to the artemis import page:

|artemis_import|

Here you can select the course into which you want to import the exercise. The “Import …” button will finally forward you to
the exercise details page, where you can adapt the exercise to your needs.

|artemis_import2|





Binary file added docs/user/sharing/artemis_import.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/sharing/artemis_import2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/sharing/sharing_export.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/sharing/sharing_metadata.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/sharing/sharing_metadata2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/sharing/sharing_namespace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/sharing/sharing_search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/user/sharing/sharing_success.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import jakarta.validation.constraints.NotNull;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
Expand Down Expand Up @@ -63,6 +64,22 @@ public RestTemplate apollonRestTemplate() {
return createRestTemplate();
}

/**
* Creates a RestTemplate with short timeouts that can be used to communicate with the Sharing Platform.
* Just needed to have an independent rest template.
* Especially when mocked for tests.
*
* @return a RestTemplate with short timeouts for sharing platform integration
*/
@Bean
@ConditionalOnProperty(name = "artemis.sharing.enabled", // property key
havingValue = "true", // required value
matchIfMissing = false // default behavior if property is absent
)
public RestTemplate sharingRestTemplate() {
return createShortTimeoutRestTemplate();
}

/**
* Creates a RestTemplate that can be used to communicate with Aeolus
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http, SecurityProble
.requestMatchers("/.well-known/jwks.json").permitAll()
.requestMatchers("/.well-known/assetlinks.json").permitAll()
.requestMatchers("/.well-known/apple-app-site-association").permitAll()
// sharing export (to Sharing plattform) is protected by explicit security tokens, thus we can permitAll here
.requestMatchers("/api/programming/sharing/export/**").permitAll()
// sharing is protected by explicit security tokens, (or are non-critical) thus we can permitAll here
.requestMatchers("/api/core/sharing/**").permitAll()
// Prometheus endpoint protected by IP address.
.requestMatchers("/management/prometheus/**").access((authentication, context) -> new AuthorizationDecision(monitoringIpAddresses.contains(context.getRequest().getRemoteAddr())))
.requestMatchers(("/api-docs")).permitAll()
Expand All @@ -255,6 +259,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http, SecurityProble
// LocalVCFetchFilter/LocalVCPushFilter handle auth
.requestMatchers("/git/**").permitAll();


// All other requests must be authenticated. Additional authorization happens on the endpoints themselves.
requests.requestMatchers("/**").authenticated();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package de.tum.cit.aet.artemis.core.dto;

import java.util.Map;
import java.util.Objects;

import jakarta.validation.constraints.NotNull;

import org.codeability.sharing.plugins.api.util.SecretChecksumCalculator;

import com.fasterxml.jackson.annotation.JsonInclude;

/**
* the sharing info to request a specific exercise from the sharing platform.
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public record SharingInfoDTO(

@NotNull String basketToken,

@NotNull String returnURL,

@NotNull String apiBaseURL,

@NotNull String checksum,

int exercisePosition) {

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SharingInfoDTO that = (SharingInfoDTO) o;
return exercisePosition == that.exercisePosition && Objects.equals(basketToken, that.basketToken) && Objects.equals(returnURL, that.returnURL)
&& Objects.equals(apiBaseURL, that.apiBaseURL);
}

@Override
public int hashCode() {
return Objects.hash(basketToken, returnURL, apiBaseURL, exercisePosition);
}

/**
* verifies the checksum of returnURL and apiBaseURL with the secret key
*
* @param secretKey the secret key
* @return true, if checksum is correct
*/
public boolean checkChecksum(String secretKey) {
return SecretChecksumCalculator.checkChecksum(Map.of("returnURL", returnURL, "apiBaseURL", apiBaseURL), secretKey, checksum);
}
}
Loading
Loading