Skip to content
Merged

Dev #39

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
45b5aa9
add admin docs
JDTobin Mar 22, 2024
b3d15bc
Merge pull request #38 from OpenLXP/admindocs
KarenAJ Mar 25, 2024
d4021be
Upgraded Django/djangorestframework
Jul 24, 2024
87a4e5a
Updated PR branch in workflow
Jul 24, 2024
bdc5d4e
upgrading packages/CSRF_TRUSTED_ORIGINS
Jul 31, 2024
f2687e3
Merge pull request #40 from OpenLXP/django-upgrade
sammy-sandhu Jul 31, 2024
2601731
Readme updated
Sep 12, 2024
540ba53
workflow: docker compose command fixed
Sep 12, 2024
d61ab9e
README - fixed bullet numbering
Sep 12, 2024
927bc3f
Added Collectstatic
KarenAJ Sep 18, 2024
c54bef7
Update start-app.sh
KarenAJ Sep 18, 2024
368ccb9
adding migration
KarenAJ Oct 17, 2024
8abaa2e
correcting docker compose
KarenAJ Oct 17, 2024
f9a6e5a
Merge pull request #42 from OpenLXP/adding-migration
sammy-sandhu Oct 17, 2024
576d627
Adding health checks
Oct 21, 2024
4126f4f
Updated ECR tag
Oct 23, 2024
85651e4
startswith to istartswith
KarenAJ Dec 4, 2024
6db7f86
Merge pull request #47 from OpenLXP/bugfix_binaryexp
JDTobin Dec 4, 2024
7532337
Merge pull request #41 from OpenLXP/readme-docs
KarenAJ Dec 4, 2024
d496885
added new validation parameters
KarenAJ Jul 12, 2025
9283985
Correcting variable name
KarenAJ Jul 14, 2025
b6f7fb2
docker update
KarenAJ Jul 14, 2025
42c74ba
updating models
KarenAJ Jul 14, 2025
72f5fc0
fix test case
KarenAJ Jul 14, 2025
d5ad16b
lint fix
KarenAJ Jul 14, 2025
413d542
Remove learning type
KarenAJ Aug 7, 2025
424ed50
type code
KarenAJ Aug 7, 2025
8e2e8ca
Merge pull request #49 from OpenLXP/Schema_validation_update
KarenAJ Aug 11, 2025
4531995
Latest sync with P1 master branch
Aug 20, 2025
957812b
Adding HOSTS to docker-compose
Aug 21, 2025
71c77f3
adding formatting
KarenAJ Aug 25, 2025
d14d28f
added test cases
KarenAJ Aug 25, 2025
60d5712
Merge pull request #50 from OpenLXP/code-sync
sammy-sandhu Aug 25, 2025
19b28f1
Merge branch 'main' into dev
sammy-sandhu Aug 25, 2025
9fa0720
update to README and fix admin
JDTobin Feb 18, 2026
e404b0f
update link
JDTobin Feb 24, 2026
6404744
add wiki link
JDTobin Feb 24, 2026
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
47 changes: 2 additions & 45 deletions .github/workflows/cd-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- dev
pull_request:
branches:
- main
- dev
types: [opened, synchronize, reopened]

jobs:
Expand Down Expand Up @@ -46,47 +46,4 @@ jobs:
docker network create openlxp
echo "Docker network successfully created"
echo "Running coverage unit test"
docker-compose --env-file ./.env run app sh -c "python manage.py waitdb && coverage run manage.py test --tag=unit && flake8 && coverage report && coverage report --fail-under=80"

sonarcloud:
name: SonarCloud
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

build:
# require dependency from step above
needs: code-test
name: Build Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
with:
mask-password: 'true'
- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ secrets.ECR_REPO }}
IMAGE_TAG: xss
run: |
echo "Starting docker build"
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
echo "Pushing image to ECR..."
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker compose --env-file ./.env run app sh -c "python manage.py waitdb && coverage run manage.py test --tag=unit && flake8 && coverage report && coverage report --fail-under=80"
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Dockerfile

FROM python:3.7-buster
FROM python:3.9-bookworm

# install nginx
RUN apt-get update && apt-get install nginx vim libxml2-dev libxmlsec1-dev clamav-daemon clamav-freshclam clamav-unofficial-sigs -y --no-install-recommends
Expand Down
72 changes: 52 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

The Experience Schema Service (XSS) maintains referential representations of domain entities, as well as transformational mappings that describe how to convert an entity from one particular schema representation to another.

This component responsible for managing pertinent object/record metadata schemas, and the mappings for transforming records from a source metadata schema to a target metadata schema. This component will also be used to store and link vocabularies from stored schema.
This component is responsible for managing pertinent object/record metadata schemas, and the mappings for transforming records from a source metadata schema to a target metadata schema. This component will also be used to store and link vocabularies from stored schema.


## Prerequisites
Expand Down Expand Up @@ -31,28 +31,31 @@ Or copy it into one of these folders to install it system-wide:
## 1. Clone the project
Clone the Github repository
```
git clone https://github.com/OpenLXP/openlxp-xss.git
git clone https://github.com/adlnet/ecc-openlxp-xss.git
```

## 2. Set up your environment variables
- Create a `.env` file in the root directory
- The following environment variables are required:

| Environment Variable | Description |
| ------------------------- | ----------- |
| AWS_ACCESS_KEY_ID | The Access Key ID for AWS |
| AWS_SECRET_ACCESS_KEY | The Secret Access Key for AWS |
| AWS_DEFAULT_REGION | The region for AWS |
| DB_HOST | The host name, IP, or docker container name of the database |
| DB_NAME | The name to give the database |
| DB_PASSWORD | The password for the user to access the database |
| DB_ROOT_PASSWORD | The password for the root user to access the database, should be the same as `DB_PASSWORD` if using the root user |
| Environment Variable | Description |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| CORS_ALLOWED_ORIGINS | List of trusted origins that are allowed to make cross-origin requests to the server |
| CSRF_TRUSTED_ORIGINS | A trusted origin for unsafe requests |
| DB_HOST | The host name, IP, or docker container name of the database |
| DB_NAME | The name to give the database |
| DB_PASSWORD | The password for the user to access the database |
| DB_ROOT_PASSWORD | The password for the root user to access the database, should be the same as `DB_PASSWORD` if using the root user |
| DB_USER | The name of the user to use when connecting to the database. When testing use root to allow the creation of a test database |
| DJANGO_SUPERUSER_EMAIL | The email of the superuser that will be created in the application |
| DJANGO_SUPERUSER_PASSWORD | The password of the superuser that will be created in the application |
| DJANGO_SUPERUSER_USERNAME | The username of the superuser that will be created in the application |
| LOG_PATH | The path to the log file to use |
| SECRET_KEY_VAL | The Secret Key for Django |
| DJANGO_SUPERUSER_EMAIL | The email of the superuser that will be created in the application |
| DJANGO_SUPERUSER_PASSWORD | The password of the superuser that will be created in the application |
| DJANGO_SUPERUSER_USERNAME | The username of the superuser that will be created in the application |
| ENTITY_ID | The Entity ID used to identify this application to Identity Providers when using Single Sign On |
| HOSTS | A list of host names, separated by semicolons, that the application should accept requests for |
| LOG_PATH | The path to the log file to use |
| SECRET_KEY_VAL | The Secret Key for Django |
| SP_PRIVATE_KEY | The Private Key to use when this application communicates with Identity Providers to use Single Sign On |
| SP_PUBLIC_CERT | The Public Key to use when this application communicates with Identity Providers to use Single Sign On |

## 3. Deployment
1. Create the OpenLXP docker network. Open a terminal and run the following command in the root directory of the project
Expand Down Expand Up @@ -133,22 +136,39 @@ git clone https://github.com/OpenLXP/openlxp-xss.git

- `Name` Term title

- `Desciption` Term entity's description
- `Description` Term entity's description

- `Status` Select if the Term set is Published or Retired

- `Data Type` Term entity's corresponding data type

- `Use` Term entity's corresponding use case

- `Multiple Expected` Whether the Term should be a singular value or a list

- `Source` Term entity's corresponding source

- `term set` Select the reference to the parent term set from the drop down
- `Term Set` Select the reference to the parent term set from the drop down

- `Mapping` Add mappings between terms entity's of different parent term set

- `Updated by` User that creates/updates the term

3. <u>[OPENLXP AUTHENTICATION](https://pypi.org/project/openlxp-authentication/)</u>
- Saml configurations: Configure Security Assertion Markup Language (SAML)
1. Click on `Saml configurations` > `Add Saml configuration`
- Enter configurations below:

- `Name`: The name that will be used to identify the IdP in the URL.

- `Entity id`: The unique name provided by the IdP.

- `Url`: The connection URL to connect to the IdP at.

- `Cert`: The public cert used to connect to the IdP.

- `Attribute mapping`: The JSON formatted mapping to convert attributes provided by the IdP, to a User in this system.

## 5. Removing Deployment
To destroy the created resources, simply run the command below in your terminal:

Expand All @@ -164,7 +184,7 @@ Query string parameter: `name` `version` `iri`



**Note:This API fetches the required schema from the repository using the Name and Version or IRI parameters**
*Note:This API fetches the required schema from the repository using the Name and Version or IRI parameters*

Query string parameter: `sourceName` `sourceVersion` `sourceIRI` `targetName` `targetVersion` `targetIRI`

Expand All @@ -183,7 +203,19 @@ Test coverage information will be stored in an htmlcov directory
docker-compose --env-file .env run app sh -c "coverage run manage.py test && coverage html && flake8"
```

## Authentication

While XSS supports authentication and authorization, the schema and mapping APIs do not require authentication to use, as it is believed that they should be easily accessible shared resources.

The Django settings `SP_PUBLIC_CERT`, `SP_PRIVATE_KEY` , and `SP_ENTITY_ID` must be defined (if using docker-compose the variables can be passed through).

Information on the settings for the authentication module can be found on the [OpenLXP-Authentication repo](https://github.com/adlnet/openlxp-authentication).

## Additional Info

Additional information about ECC can be found in our [ECC wiki](https://github.com/adlnet/ecc-openlxp-xds-ui/wiki)

## License

This project uses the [MIT](http://www.apache.org/licenses/LICENSE-2.0) license.
This project uses the [Apache](http://www.apache.org/licenses/LICENSE-2.0) license.

6 changes: 4 additions & 2 deletions app/core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ class TermAdmin(admin.ModelAdmin):
'modified', )
fieldsets = (
(None, {'fields': ('iri', 'name', 'uuid', 'description', 'status',)}),
('Info', {'fields': ('data_type', 'use', 'source',)}),
('Info', {'fields': ('data_type', 'use',
'multiple_expected',
'source',)}),
('Connections', {'fields': ('term_set', 'mapping',)}),
('Updated', {'fields': ('updated_by',), })
)
Expand All @@ -108,5 +110,5 @@ def get_form(self, request, obj=None, **kwargs):
form = super(TermAdmin, self).get_form(request, obj, **kwargs)
if obj is not None:
form.base_fields['mapping'].queryset = Term.objects.exclude(
iri__startswith=obj.root_term_set())
iri__istartswith=obj.root_term_set())
return form
18 changes: 18 additions & 0 deletions app/core/migrations/0007_alter_term_mapping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.16 on 2024-10-17 16:01

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0006_auto_20230901_1454'),
]

operations = [
migrations.AlterField(
model_name='term',
name='mapping',
field=models.ManyToManyField(blank=True, to='core.term'),
),
]
24 changes: 24 additions & 0 deletions app/core/migrations/0008_term_multiple_expected_term_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 4.2.23 on 2025-07-14 17:49

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0007_alter_term_mapping'),
]

operations = [
migrations.AddField(
model_name='term',
name='multiple_expected',
field=models.BooleanField(default=False, help_text='Whether multiple values are expected for this Term'),
),
migrations.AddField(
model_name='term',
name='type',
field=models.CharField(choices=[('Learning Resource', 'Learning Resource'), ('Learning Event', 'Learning Event'), ('Both', 'Both')], default='', max_length=255),
preserve_default=False,
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 4.2.23 on 2025-07-14 17:49

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0008_term_multiple_expected_term_type'),
]

operations = [
migrations.RemoveField(
model_name='term',
name='type',
),
migrations.AddField(
model_name='term',
name='learning_type',
field=models.CharField(blank=True, choices=[('Learning Resource', 'Learning Resource'), ('Learning Event', 'Learning Event'), ('Both', 'Both')], default=None, max_length=255, null=True),
),
migrations.AlterField(
model_name='term',
name='multiple_expected',
field=models.BooleanField(default=True, help_text='Whether multiple values are expected for this Term'),
),
]
17 changes: 17 additions & 0 deletions app/core/migrations/0010_remove_term_learning_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.23 on 2025-08-07 16:15

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('core', '0009_remove_term_type_term_learning_type_and_more'),
]

operations = [
migrations.RemoveField(
model_name='term',
name='learning_type',
),
]
Loading
Loading