Skip to content

Commit 0510df9

Browse files
authored
Merge branch 'master' into feat/347-responsive-app
2 parents 081343b + c6cc45d commit 0510df9

25 files changed

+918
-482
lines changed

.github/workflows/main.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ permissions:
1414

1515
jobs:
1616
build:
17+
if: github.repository == 'devsecopsmaturitymodel/DevSecOps-MaturityModel'
1718
runs-on: ubuntu-latest
1819
steps:
1920
- uses: actions/checkout@v3
@@ -73,11 +74,14 @@ jobs:
7374
echo "HEROKU_BRANCH=master" >> $GITHUB_ENV
7475
fi
7576
echo "HEROKU_BRANCH=master" >> $GITHUB_ENV
77+
- name: Install Heroku CLI
78+
run: |
79+
curl https://cli-assets.heroku.com/install.sh | sh
7680
- name: "Deploy ${{ github.ref }} to Heroku"
77-
uses: akhileshns/heroku-deploy@9fd0f9faae4aa93a38d6f5e25b9128589f1371b0 #v3.12.14
81+
uses: akhileshns/heroku-deploy@v3.13.15
7882
with:
7983
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
8084
heroku_app_name: "dsomm"
8185
heroku_email: timo.pagel@owasp.org
8286
branch: ${{ env.HEROKU_BRANCH }}
83-
usedocker: true
87+
usedocker: true

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ jobs:
1313
with:
1414
node-version: 16.0
1515
- name: Install dependencies
16-
run: npm install
16+
run: npm install --legacy-peer-deps
1717
- name: Test
1818
run: npm test -- --watch=false --browsers=ChromeHeadless

Development.md

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,72 @@
1-
# DSOMM
1+
# DevSecOps Maturity Model (DSOMM)
22

3-
## Development server
3+
## Introduction
44

5-
- Clone the repo
5+
The DevSecOps Maturity Model (DSOMM) is an open-source framework designed to help organizations evaluate and improve their **DevSecOps** practices.
6+
It provides structured **security maturity levels**, recommendations, and automation insights to enable teams to build **secure, efficient, and scalable software**.
7+
8+
This guide walks you through **setting up the project locally**, making contributions, and submitting a pull request.
9+
10+
## **Project Setup**
11+
12+
### Development Server
13+
14+
The DSOMM is based [Angular](https://angular.dev/) and uses npm for package management.
15+
16+
- If you have not yet installed npm or the Angular command line tools, install them now. First [NodeJS](https://nodejs.org/en/download) (which provides npm), then Angular:
17+
18+
```bash
19+
npm install -g @angular/cli
620
```
21+
22+
- Clone the DSOMM repo
23+
24+
```bash
725
git clone https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel.git
826
```
27+
928
- Change directory to DSOMM
10-
```
29+
30+
```bash
1131
cd DevSecOps-MaturityModel
1232
```
33+
1334
- Install Dependencies
14-
```
35+
36+
```bash
1537
npm install
1638
```
17-
- Downloads the generated.yaml and put it in the required folder
18-
```
39+
40+
- **NB!** The DSOMM activities are maintained separately. Download the `generated.yaml` and put it in the required folder
41+
42+
```bash
1943
curl https://raw.githubusercontent.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/main/src/assets/YAML/generated/generated.yaml -o src/assets/YAML/generated/generated.yaml
2044
```
2145

2246
- Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
2347

24-
25-
## Code scaffolding
48+
## Code Scaffolding
2649

2750
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
2851

2952
## Build
3053

3154
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
3255

33-
## Running unit tests
56+
## Running Unit Tests
3457

3558
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
3659

3760
## Coding Style Conventions
3861

39-
- We follow the coding style defined by [ESLint](https://eslint.org/).
62+
- We follow the coding style defined by [ESLint](https://eslint.org/).
4063
- We also use [Prettier](https://prettier.io/docs/en/index.html) as our opinionated code formatter.
41-
- To validate the schemas of the DSOMM yaml files in the IDE, it is recommended to use the VS Code extension [redhat.vscode-yaml](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml). The schemas are stored in /src/assets/YAML/schemas
64+
- To validate the schemas of the DSOMM yaml files in the IDE, it is recommended to use the VS Code extension [redhat.vscode-yaml](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml). The schemas are stored in `/src/assets/YAML/schemas`
65+
66+
### Running Linter
67+
68+
Run `ng lint` to run the linter from the command line.
69+
If you want to lint only a specific component, use:
4270

71+
```bash
72+
ng lint --lint-file-patterns .\src\app\component\xxxxxx\

README.md

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ From a startup to a multinational corporation the software development industry
44

55
The OWASP DevSecOps Maturity Model provides opportunities to harden DevOps strategies and shows how these can be prioritized.
66

7-
With the help of DevOps strategies security can also be enhanced. For example, each component such as application libraries and operating system libraries in docker images can be tested for known vulnerabilities.
7+
With the help of DevOps strategies security can also be enhanced. For example, each component such as application libraries and operating system libraries in docker images can be tested for known vulnerabilities.
88

99
Attackers are intelligent and creative, equipped with new technologies and purpose. Under the guidance of the forward-looking DevSecOps Maturity Model, appropriate principles and measures are at hand implemented which counteract the attacks.
1010

@@ -63,9 +63,9 @@ In case you would like to perform a DevSecOps assessment, the following tools ar
6363
3. Browse to <http://localhost:8080> (on macOS and Windows browse to <http://192.168.99.100:8080> if you are using docker-machine instead
6464
of the native docker installation)
6565

66-
For customized DSOMM, take a look at https://github.com/wurstbrot/DevSecOps-MaturityModel-custom. In case you would like to have perform an assessment for multiple teams, iterate from port 8080 to 8XXX, depending of the size of your team.
66+
For customized DSOMM, take a look at https://github.com/wurstbrot/DevSecOps-MaturityModel-custom.
6767

68-
You can download your current state from the circular headmap and mount it again via
68+
You can download your current state from the circular heatmap and mount it again via
6969

7070
```bash
7171
wget https://raw.githubusercontent.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data/main/src/assets/YAML/generated/generated.yaml # or go to /circular-heatmap and download edited yaml (bottom right)
@@ -94,6 +94,29 @@ service docker start
9494
docker run -d -p 80:8080 wurstbrot/dsomm:latest
9595
```
9696

97+
## Generating the `generated.yaml` File
98+
99+
The `generated.yaml` file is dynamically created during the build process. If you don’t see this file after setup, follow these steps to generate it:
100+
101+
**1. Clone the Required Repository:**
102+
The `generated.yaml` file is built via the DevSecOps-MaturityModel-data repository. Make sure you have cloned and set it up correctly.
103+
104+
**2. Run the Build Command:**
105+
Navigate to the project directory and run the following command:
106+
- *Using npm:*
107+
108+
```sh
109+
npm run build
110+
````
111+
112+
- *Using yarn:*
113+
114+
```sh
115+
yarn build
116+
```
117+
118+
*If the file is missing, ensure all dependencies are installed and that you have the correct access to the `DevSecOps-MaturityModel-data` repository.*
119+
97120
## Activity Definitions
98121
The definition of the activities are in the [data-repository](https://github.com/devsecopsmaturitymodel/DevSecOps-MaturityModel-data).
99122

@@ -124,10 +147,18 @@ In the corresponding [dimension YAMLs](https://github.com/devsecopsmaturitymodel
124147
[...]
125148
teamsImplemented:
126149
Default: false
150+
B: true
127151
C: true
128-
evidence:
129-
B: Showed Jenkinsfile
152+
teamsEvidence:
153+
B: All team members completed OWASP Secure Coding Dojo training on 2025-01-11.
154+
C: |
155+
The pentest report from 2025 has been split into Jira tasks under
156+
[TODO-123](https://jira.example.com/issues/TODO-123).
157+
158+
_2025-04-01:_ All fixes of **critical** findings are deployed to production.
130159
```
160+
The `|` is yaml syntax to indicate that the evidence spans multiple lines. Markdown
161+
syntax can be used. The evidence is currently visible on the activity from the Matrix page.
131162
132163
# Back link
133164

package-lock.json

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/app-routing.module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ const routes: Routes = [
1515
{ path: 'matrix', component: MatrixComponent },
1616
{ path: 'activity-description', component: ActivityDescriptionComponent },
1717
{ path: 'mapping', component: MappingComponent },
18-
{ path: 'usage', component: UsageComponent },
18+
{ path: 'usage', redirectTo: 'usage/' },
19+
{ path: 'usage/:page', component: UsageComponent },
1920
{ path: 'teams', component: TeamsComponent },
2021
{ path: 'about', component: AboutUsComponent },
2122
{ path: 'userday', component: UserdayComponent },

src/app/app.module.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ import { AboutUsComponent } from './component/about-us/about-us.component';
2222
import { DependencyGraphComponent } from './component/dependency-graph/dependency-graph.component';
2323
import { TeamsComponent } from './component/teams/teams.component';
2424
import { ToStringValuePipe } from './pipe/to-string-value.pipe';
25+
import { ModalMessageComponent } from './component/modal-message/modal-message.component';
26+
import {
27+
MatDialogModule,
28+
MAT_DIALOG_DATA,
29+
MatDialogRef,
30+
} from '@angular/material/dialog';
2531

2632
@NgModule({
2733
declarations: [
@@ -40,16 +46,23 @@ import { ToStringValuePipe } from './pipe/to-string-value.pipe';
4046
TeamsComponent,
4147
ToStringValuePipe,
4248
UserdayComponent,
49+
ModalMessageComponent,
4350
],
4451
imports: [
4552
BrowserModule,
4653
AppRoutingModule,
4754
BrowserAnimationsModule,
4855
MaterialModule,
56+
MatDialogModule,
4957
ReactiveFormsModule,
5058
HttpClientModule,
5159
],
52-
providers: [ymlService],
60+
providers: [
61+
ymlService,
62+
ModalMessageComponent,
63+
{ provide: MAT_DIALOG_DATA, useValue: {} },
64+
{ provide: MatDialogRef, useValue: { close: (dialogResult: any) => {} } },
65+
],
5366
bootstrap: [AppComponent],
5467
})
5568
export class AppModule {}

src/app/component/circular-heatmap/circular-heatmap.component.spec.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,25 @@ import { ymlService } from 'src/app/service/yaml-parser/yaml-parser.service';
44
import { CircularHeatmapComponent } from './circular-heatmap.component';
55
import { RouterTestingModule } from '@angular/router/testing';
66
import { MatChip } from '@angular/material/chips';
7+
import { ModalMessageComponent } from '../modal-message/modal-message.component';
78

89
describe('CircularHeatmapComponent', () => {
910
let component: CircularHeatmapComponent;
1011
let fixture: ComponentFixture<CircularHeatmapComponent>;
1112

1213
beforeEach(async () => {
1314
await TestBed.configureTestingModule({
14-
providers: [ymlService, HttpClient, HttpHandler],
15+
declarations: [CircularHeatmapComponent, MatChip],
1516
imports: [RouterTestingModule],
16-
declarations: [CircularHeatmapComponent],
17+
providers: [
18+
ymlService,
19+
HttpClient,
20+
HttpHandler,
21+
{ provide: ModalMessageComponent, useValue: {} },
22+
],
1723
}).compileComponents();
18-
});
19-
beforeEach(async () => {
20-
TestBed.configureTestingModule({
21-
declarations: [MatChip],
22-
}).compileComponents();
23-
});
2424

25-
beforeEach(() => {
26-
fixture = TestBed.createComponent(CircularHeatmapComponent);
25+
fixture = TestBed.createComponent(CircularHeatmapComponent); // Create fixture and component here
2726
component = fixture.componentInstance;
2827
fixture.detectChanges();
2928
});

src/app/component/circular-heatmap/circular-heatmap.component.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import * as yaml from 'js-yaml';
1111
import { Router } from '@angular/router';
1212
import { MatChip } from '@angular/material/chips';
1313
import * as md from 'markdown-it';
14+
import {
15+
ModalMessageComponent,
16+
DialogInfo,
17+
} from '../modal-message/modal-message.component';
1418

1519
export interface activitySchema {
1620
uuid: string;
@@ -63,7 +67,7 @@ export class CircularHeatmapComponent implements OnInit {
6367
constructor(
6468
private yaml: ymlService,
6569
private router: Router,
66-
private changeDetector: ChangeDetectorRef
70+
public modal: ModalMessageComponent
6771
) {
6872
this.showOverlay = false;
6973
this.showFilters = true;
@@ -85,6 +89,14 @@ export class CircularHeatmapComponent implements OnInit {
8589
@ViewChildren(MatChip) chips!: QueryList<MatChip>;
8690
matChipsArray: MatChip[] = [];
8791

92+
displayMessage(dialogInfo: DialogInfo) {
93+
// Remove focus from the button that becomes aria unavailable (avoids ugly console error message)
94+
const buttonElement = document.activeElement as HTMLElement;
95+
buttonElement.blur();
96+
97+
this.modal.openDialog(dialogInfo);
98+
}
99+
88100
private LoadMaturityDataFromGeneratedYaml() {
89101
return new Promise<void>((resolve, reject) => {
90102
console.log(`${this.perfNow()}s: LoadMaturityData Fetch`);
@@ -826,9 +838,26 @@ export class CircularHeatmapComponent implements OnInit {
826838
}
827839
}
828840

829-
ResetIsImplemented() {
830-
localStorage.removeItem('dataset');
831-
this.loadDataset();
841+
deleteLocalTeamsProgress() {
842+
// Remove focus from the button that becomes aria unavailable (avoids ugly console error message)
843+
const buttonElement = document.activeElement as HTMLElement;
844+
buttonElement.blur();
845+
846+
let title: string = 'Delete local browser data';
847+
let message: string =
848+
'Do you want to delete all progress for each team?' +
849+
'\n\nThis deletes all progress stored in your local browser, but does ' +
850+
'not change any progress stored in the yaml file on the server.';
851+
let buttons: string[] = ['Cancel', 'Delete'];
852+
this.modal
853+
.openDialog({ title, message, buttons, template: '' })
854+
.afterClosed()
855+
.subscribe(data => {
856+
if (data === 'Delete') {
857+
localStorage.removeItem('dataset');
858+
location.reload(); // Make sure all load routines are initialized
859+
}
860+
});
832861
}
833862

834863
saveDataset() {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.dialog {
2+
margin: 0.5em;
3+
padding: 1em;
4+
}
5+
6+
.dialog-buttons {
7+
display: flex;
8+
justify-content: flex-end;
9+
}
10+
11+
button {
12+
min-width: 5rem;
13+
margin: 0 1rem;
14+
}

0 commit comments

Comments
 (0)