Skip to content

Commit

Permalink
Merge branch 'main' into BC-7995-node-22
Browse files Browse the repository at this point in the history
  • Loading branch information
dyedwiper authored Nov 8, 2024
2 parents ced8418 + 4061216 commit f0a7a74
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 33 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,17 @@ jobs:
security-events: write
steps:
- name: run trivy vulnerability scanner
uses: aquasecurity/trivy-action@1f6384b6ceecbbc6673526f865b818a2a06b07c9
uses: aquasecurity/trivy-action@915b19bbe73b92a6cf82a1bc12b087c9a19a5fe2
with:
image-ref: "ghcr.io/${{ github.repository }}-default:${{ needs.branch_meta.outputs.sha }}"
format: "sarif"
output: "trivy-results.sarif"
severity: "CRITICAL,HIGH"
ignore-unfixed: true
scan-type: 'image'
env:
TRIVY_SKIP_DB_UPDATE: true
TRIVY_SKIP_JAVA_DB_UPDATE: true
- name: upload trivy results
if: ${{ always() }}
uses: github/codeql-action/upload-sarif@v3
Expand Down
39 changes: 39 additions & 0 deletions .github/workflows/trivy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Note: This workflow only updates the cache. You should create a separate workflow for your actual Trivy scans.
# In your scan workflow, set TRIVY_SKIP_DB_UPDATE=true and TRIVY_SKIP_JAVA_DB_UPDATE=true.
name: Update Trivy Cache

on:
schedule:
- cron: '0 0 * * *' # Run daily at midnight UTC
workflow_dispatch: # Allow manual triggering

jobs:
update-trivy-db:
runs-on: ubuntu-latest
steps:
- name: Setup oras
uses: oras-project/setup-oras@v1

- name: Get current date
id: date
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT

- name: Download and extract the vulnerability DB
run: |
mkdir -p $GITHUB_WORKSPACE/.cache/trivy/db
oras pull ghcr.io/aquasecurity/trivy-db:2
tar -xzf db.tar.gz -C $GITHUB_WORKSPACE/.cache/trivy/db
rm db.tar.gz
- name: Download and extract the Java DB
run: |
mkdir -p $GITHUB_WORKSPACE/.cache/trivy/java-db
oras pull ghcr.io/aquasecurity/trivy-java-db:1
tar -xzf javadb.tar.gz -C $GITHUB_WORKSPACE/.cache/trivy/java-db
rm javadb.tar.gz
- name: Cache DBs
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/.cache/trivy
key: cache-trivy-${{ steps.date.outputs.date }}
10 changes: 6 additions & 4 deletions src/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ export default {
"feature-board-file-element.placeholder.uploadFile": "Datei hochladen",
"feature-course-sync.EndCourseSyncDialog.title": "Synchronisation beenden",
"feature-course-sync.EndCourseSyncDialog.description":
"Soll die Synchronization der Nutzendengruppe {groupName} im Kurs {courseName} wirklich beendet werden?",
"Soll die Synchronisation des Kurses {courseName} mit der Nutzendengruppe {groupName} wirklich beendet werden?",
"feature-course-sync.EndCourseSyncDialog.success":
"Synchronisation erfolgreich beendet",
"feature-course-sync.GroupSelectionDialog.title": "Nutzendengruppe auswählen",
Expand All @@ -840,10 +840,12 @@ export default {
"Die gewählte Nutzendengruppe wird im nächsten Schritt mit dem neu erstellten Kurs synchronisiert.",
"feature-course-sync.StartExistingCourseSyncDialog.text":
"Die gewählte Nutzendengruppe wird im nächsten Schritt mit dem ausgewählten Kurs synchronisiert.",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.warning":
"Eine Synchronisation mit {systemName} überschreibt die Personen des Kurses (Lehrkräfte und Schüler*innen).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userInGroupWarning":
"Eine Synchronisation überschreibt die Kursteilnehmenden (zugeordnete Lehrkräfte und Schüler:innen).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userNotInGroupWarning":
"Eine Synchronisation überschreibt die Kursteilnehmenden (zugeordnete Schüler:innen).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.text":
"Soll die Synchronisation der Nutzendengruppe {groupName} im Kurs {courseName} wirklich gestartet werden?",
"Soll der Kurs {courseName} mit der Nutzendengruppe {groupName} wirklich synchronisiert werden?",
"feature-course-sync.StartExistingCourseSyncDialog.success":
"Nutzendengruppe erfolgreich synchronisiert",
"feature-course-sync.startRoomSyncDialog.title": "Synchronisation starten",
Expand Down
10 changes: 6 additions & 4 deletions src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ export default {
"feature-board-file-element.placeholder.uploadFile": "Upload file",
"feature-course-sync.EndCourseSyncDialog.title": "End synchronization",
"feature-course-sync.EndCourseSyncDialog.description":
"Should the synchronization of the user group {groupName} in the course {courseName} really be ended?",
"Should the synchronization of the course {courseName} with the user group {groupName} really be stopped?",
"feature-course-sync.EndCourseSyncDialog.success":
"Synchronization completed successfully",
"feature-course-sync.GroupSelectionDialog.title": "Select user group",
Expand All @@ -834,10 +834,12 @@ export default {
"In the next step, the selected user group will be synchronized with the newly created course.",
"feature-course-sync.StartExistingCourseSyncDialog.text":
"The selected user group will be synchronized with the selected course in the next step.",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.warning":
"A synchronization with {systemName} overwrites the members in the course (teachers and students).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userInGroupWarning":
"A synchronization overwrites the course participants (assigned teachers and students).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userNotInGroupWarning":
"A synchronization overwrites the course participants (assigned students).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.text":
"Should the synchronization of the user group {groupName} in the course {courseName} really be started?",
"Should the course {courseName} really be synchronized with the user group {groupName}?",
"feature-course-sync.StartExistingCourseSyncDialog.success":
"User group successfully synchronized",
"feature-course-sync.startRoomSyncDialog.title": "Start synchronization",
Expand Down
10 changes: 6 additions & 4 deletions src/locales/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ export default {
"feature-board-file-element.placeholder.uploadFile": "Cargar archivo",
"feature-course-sync.EndCourseSyncDialog.title": "Finalizar sincronización",
"feature-course-sync.EndCourseSyncDialog.description":
"¿Debería realmente finalizarse la sincronización del grupo de usuarios {groupName} en el curso {courseName}?",
"¿Debería realmente detenerse la sincronización del curso {courseName} con el grupo de usuarios {groupName}?",
"feature-course-sync.EndCourseSyncDialog.success":
"Sincronización completada exitosamente",
"feature-course-sync.GroupSelectionDialog.title":
Expand All @@ -858,10 +858,12 @@ export default {
"En el siguiente paso, el grupo de usuarios seleccionado se sincronizará con el curso recién creado.",
"feature-course-sync.StartExistingCourseSyncDialog.text":
"El grupo de usuarios seleccionado se sincronizará con el curso seleccionado en el siguiente paso.",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.warning":
"Una sincronización con {systemName} sobrescribe a las personas del curso (profesores y estudiantes).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userInGroupWarning":
"Una sincronización sobrescribe a los participantes del curso (profesores y estudiantes asignados).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userNotInGroupWarning":
"Una sincronización sobrescribe a los participantes del curso (estudiantes asignados).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.text":
"¿Debería realmente iniciarse la sincronización del grupo de usuarios {groupName} en el curso {courseName}?",
"¿Debería realmente sincronizarse el curso {courseName} con el grupo de usuarios {groupName}?",
"feature-course-sync.StartExistingCourseSyncDialog.success":
"Grupo de usuarios sincronizado exitosamente",
"feature-course-sync.startRoomSyncDialog.title": "Iniciar sincronización",
Expand Down
10 changes: 6 additions & 4 deletions src/locales/uk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ export default {
"feature-board-file-element.placeholder.uploadFile": "Cargar archivo",
"feature-course-sync.EndCourseSyncDialog.title": "Завершити синхронізацію",
"feature-course-sync.EndCourseSyncDialog.description":
"Чи дійсно слід завершити синхронізацію групи користувачів {groupName} у курсі {courseName}?",
"Чи дійсно слід припинити синхронізацію курсу {courseName} із групою користувачів {groupName}?",
"feature-course-sync.EndCourseSyncDialog.success":
"Синхронізацію успішно завершено",
"feature-course-sync.GroupSelectionDialog.title":
Expand All @@ -847,10 +847,12 @@ export default {
"На наступному кроці вибрана група користувачів буде синхронізована з новоствореним курсом.",
"feature-course-sync.StartExistingCourseSyncDialog.text":
"Вибрана група користувачів буде синхронізована з вибраним курсом на наступному кроці.",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.warning":
"Синхронізація з {systemName} перезаписує людей у курсі (викладачі та студенти).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userInGroupWarning":
"Синхронізація перезаписує учасників курсу (призначених викладачів і студентів).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userNotInGroupWarning":
"Синхронізація перезаписує учасників курсу (призначених студентів).",
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.text":
"Чи дійсно слід починати синхронізацію групи користувачів {groupName} у курсі {courseName}?",
"Чи справді курс {courseName} потрібно синхронізувати з групою користувачів {groupName}?",
"feature-course-sync.StartExistingCourseSyncDialog.success":
"Групу користувачів успішно синхронізовано",
"feature-course-sync.startRoomSyncDialog.title": "Почніть синхронізацію",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import vCustomDialog from "@/components/organisms/vCustomDialog.vue";
import { RoleName } from "@/serverApi/v3";
import AuthModule from "@/store/auth";
import NotifierModule from "@/store/notifier";
import { NOTIFIER_MODULE_KEY } from "@/utils/inject";
import { AUTH_MODULE_KEY, NOTIFIER_MODULE_KEY } from "@/utils/inject";
import { createModuleMocks } from "@@/tests/test-utils/mock-store-module";
import { groupResponseFactory } from "@@/tests/test-utils";
import { groupResponseFactory, meResponseFactory } from "@@/tests/test-utils";
import {
createTestingI18n,
createTestingVuetify,
Expand All @@ -28,7 +30,12 @@ describe("StartExistingCourseSyncDialog", () => {
courseName: "courseName",
}
) => {
const me = meResponseFactory.build();

const notifierModule = createModuleMocks(NotifierModule);
const authModule = createModuleMocks(AuthModule, {
getMe: me,
});

const wrapper = mount(StartExistingCourseSyncDialog, {
global: {
Expand All @@ -39,9 +46,11 @@ describe("StartExistingCourseSyncDialog", () => {
],
stubs: {
GroupSelectionDialog: true,
VDialog: true,
},
provide: {
[NOTIFIER_MODULE_KEY.valueOf()]: notifierModule,
[AUTH_MODULE_KEY.valueOf()]: authModule,
},
},
props,
Expand All @@ -50,6 +59,7 @@ describe("StartExistingCourseSyncDialog", () => {
return {
wrapper,
notifierModule,
me,
};
};

Expand Down Expand Up @@ -252,4 +262,76 @@ describe("StartExistingCourseSyncDialog", () => {
expect(wrapper.emitted("success")).toBeUndefined();
});
});

describe("when the user is part of the selected group", () => {
const setup = async () => {
const { wrapper, notifierModule, me } = getWrapper();

const group = groupResponseFactory.build({
users: [
{
id: me.user.id,
firstName: me.user.firstName,
lastName: me.user.lastName,
role: RoleName.Teacher,
},
],
});

wrapper.getComponent(GroupSelectionDialog).vm.$emit("confirm", group);
await nextTick();

return {
wrapper,
notifierModule,
group,
};
};

it("should display the correct warning in the confirmation dialog", async () => {
const { wrapper } = await setup();

const text = wrapper.find("[data-testid=no-teacher-warning-text]");

expect(text.text()).toEqual(
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userInGroupWarning"
);
});
});

describe("when the user is not part of the selected group", () => {
const setup = async () => {
const { wrapper, notifierModule } = getWrapper();

const group = groupResponseFactory.build({
users: [
{
id: "otherUserId",
firstName: "firstname",
lastName: "lastname",
role: RoleName.Teacher,
},
],
});

wrapper.getComponent(GroupSelectionDialog).vm.$emit("confirm", group);
await nextTick();

return {
wrapper,
notifierModule,
group,
};
};

it("should display the correct warning in the confirmation dialog", async () => {
const { wrapper } = await setup();

const text = wrapper.find("[data-testid=no-teacher-warning-text]");

expect(text.text()).toEqual(
"feature-course-sync.StartExistingCourseSyncDialog.confirmation.userNotInGroupWarning"
);
});
});
});
42 changes: 28 additions & 14 deletions src/modules/feature/course-sync/StartExistingCourseSyncDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,15 @@

<template #content>
<WarningAlert data-testid="no-teacher-warning">
<RenderHTML
component="span"
:html="
<span data-testid="no-teacher-warning-text">
{{
$t(
'feature-course-sync.StartExistingCourseSyncDialog.confirmation.warning',
{
systemName: 'moin.schule',
}
isUserInGroup
? "feature-course-sync.StartExistingCourseSyncDialog.confirmation.userInGroupWarning"
: "feature-course-sync.StartExistingCourseSyncDialog.confirmation.userNotInGroupWarning"
)
"
data-testid="no-teacher-warning-text"
/>
}}
</span>
</WarningAlert>
<p class="text-md mt-2" data-testid="group-dialog-info-text">
{{
Expand All @@ -49,12 +46,16 @@

<script setup lang="ts">
import VCustomDialog from "@/components/organisms/vCustomDialog.vue";
import { GroupResponse } from "@/serverApi/v3";
import { injectStrict, NOTIFIER_MODULE_KEY } from "@/utils/inject";
import { GroupResponse, GroupUserResponse, MeResponse } from "@/serverApi/v3";
import type AuthModule from "@/store/auth";
import {
AUTH_MODULE_KEY,
injectStrict,
NOTIFIER_MODULE_KEY,
} from "@/utils/inject";
import { useCourseApi } from "@data-room";
import { RenderHTML } from "@feature-render-html";
import { WarningAlert } from "@ui-alert";
import { ModelRef, Ref, ref } from "vue";
import { computed, ModelRef, Ref, ref } from "vue";
import { useI18n } from "vue-i18n";
import GroupSelectionDialog from "./GroupSelectionDialog.vue";
Expand Down Expand Up @@ -88,6 +89,19 @@ const onConfirmGroupSelection = async (group: GroupResponse) => {
};
const { startSynchronization } = useCourseApi();
const authModule: AuthModule = injectStrict(AUTH_MODULE_KEY);
const isUserInGroup = computed(() => {
const me: MeResponse | undefined = authModule.getMe;
if (!me || !selectedGroup.value) {
return false;
}
return selectedGroup.value.users.some(
(user: GroupUserResponse) => user.id === me.user.id
);
});
const onConfirmWarning = async () => {
if (!selectedGroup.value || !props.courseId) {
Expand Down

0 comments on commit f0a7a74

Please sign in to comment.