Skip to content

Commit bfaf296

Browse files
committed
feat: updat general solution for backend
1 parent 0d9d642 commit bfaf296

File tree

14 files changed

+280
-142
lines changed

14 files changed

+280
-142
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2023-2025 Trustify Dependency Analytics Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
*
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package io.github.guacsec.trustifyda.integration.report;
19+
20+
import io.smallrye.config.ConfigMapping;
21+
22+
@ConfigMapping(prefix = "branding")
23+
public interface BrandingConfig {
24+
String displayName();
25+
26+
String exploreUrl();
27+
28+
String exploreTitle();
29+
30+
String exploreDescription();
31+
}

src/main/java/io/github/guacsec/trustifyda/integration/report/ReportTemplate.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ public class ReportTemplate {
5858
@ConfigProperty(name = "telemetry.disabled", defaultValue = "false")
5959
Boolean disabled;
6060

61+
// Branding configuration
62+
@Inject Optional<BrandingConfig> brandingConfig;
63+
6164
@Inject ObjectMapper mapper;
6265

6366
public Map<String, Object> setVariables(
@@ -74,6 +77,8 @@ public Map<String, Object> setVariables(
7477
params.put("cveIssueTemplate", cveIssuePathRegex);
7578
params.put("imageMapping", getImageMapping());
7679
params.put("rhdaSource", rhdaSource);
80+
// Only include branding config if it's present
81+
brandingConfig.ifPresent(config -> params.put("brandingConfig", getBrandingConfigMap(config)));
7782
if (!disabled && writeKey.isPresent()) {
7883
params.put("userId", userId);
7984
params.put("anonymousId", anonymousId);
@@ -108,6 +113,15 @@ private String getImageMapping() throws JsonProcessingException {
108113
return objectWriter.writeValueAsString(urlMapping);
109114
}
110115

116+
private Map<String, String> getBrandingConfigMap(BrandingConfig config) {
117+
Map<String, String> branding = new HashMap<>();
118+
branding.put("displayName", config.displayName());
119+
branding.put("exploreUrl", config.exploreUrl());
120+
branding.put("exploreTitle", config.exploreTitle());
121+
branding.put("exploreDescription", config.exploreDescription());
122+
return branding;
123+
}
124+
111125
@RegisterForReflection
112126
public static record IssueLinkFormatter(String issuePathRegex) {
113127

src/main/resources/application.properties

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,13 @@ quarkus.hibernate-orm.sql-load-script=no-file
6262
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://${db.postgres.host}:${db.postgres.port}/${db.postgres.database}?sslmode=${db.postgres.sslmode}
6363
%prod.quarkus.datasource.username=${db.postgres.user}
6464
%prod.quarkus.datasource.password=${db.postgres.password}
65+
66+
# ====================================================================
67+
# Branding Configuration Profiles
68+
# ====================================================================
69+
70+
# Default branding configuration (Community/Trustify) Example:
71+
#branding.display.name=Trustify
72+
#branding.explore.url=https://guac.sh/trustify/
73+
#branding.explore.title=Learn more about Trustify
74+
#branding.explore.description=The Trustify project is a collection of software components that enables you to store and retrieve Software Bill of Materials (SBOMs), and advisory documents.

src/main/resources/freemarker/templates/generated/main.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/resources/freemarker/templates/generated/vendor.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ui/.env

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
GENERATE_SOURCEMAP=false
2-
3-
# Default branding mode when no specific profile is used
4-
# Options: community, redhat
5-
REACT_APP_BRANDING_MODE=community
1+
GENERATE_SOURCEMAP=false

ui/.env.community

Lines changed: 0 additions & 8 deletions
This file was deleted.

ui/.env.redhat

Lines changed: 0 additions & 8 deletions
This file was deleted.

ui/BRANDING.md

Lines changed: 189 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,215 @@
11
# Branding Configuration
22

3-
This project supports two branding modes: **Red Hat** (enterprise) and **Community** (Trustify).
3+
This project supports flexible branding through backend environment variables. The system uses **default** branding and allows you to override specific elements as needed.
44

55
## Quick Start
66

7-
### Prerequisites
8-
Install the `env-cmd` package to enable environment-specific builds:
7+
### Using Predefined Profiles
8+
9+
**Default branding:**
910
```bash
10-
npm install --save-dev env-cmd
11+
# Default profile - no additional flags needed
12+
./mvnw quarkus:dev
1113
```
1214

13-
### Development
15+
**Custom organization branding:**
1416
```bash
15-
# Start development server with Community branding (default)
16-
npm run start:community
17+
# Example using a custom profile (e.g., myorg)
18+
./mvnw quarkus:dev -Dquarkus.profile=myorg
19+
```
1720

18-
# Start development server with Red Hat branding
19-
npm run start:redhat
21+
### Using Environment Variables (Alternative)
22+
```bash
23+
# Start development server (branding controlled by backend environment variables)
24+
npm start
2025
```
2126

2227
### Production Build
2328
```bash
24-
# Build Community version
25-
npm run build:community
29+
# Build for production (branding controlled by backend environment variables)
30+
npm run build
31+
```
32+
33+
## How It Works
34+
35+
1. **Backend Configuration**: Java backend reads `BRANDING_XXX` environment variables
36+
2. **Runtime Injection**: Branding configuration is passed to the React app through `appData`
37+
3. **Component Usage**: React components read branding configuration from the app context
38+
4. **Default-First**: All defaults are set to standard values, specific brands override as needed
39+
40+
## Available Environment Variables
41+
42+
Configure branding by setting these environment variables for the Java backend:
43+
44+
```bash
45+
# Brand identity
46+
BRANDING_DISPLAY_NAME=Your Brand Name # Used for conditional logic and remediation title
2647

27-
# Build Red Hat version
28-
npm run build:redhat
48+
# Explore section
49+
BRANDING_EXPLORE_URL=https://your-url.com # URL for "Take me there" button
50+
BRANDING_EXPLORE_TITLE=Your Explore Title # Title for explore section
51+
BRANDING_EXPLORE_DESCRIPTION=Your description text # Description text
2952
```
3053

31-
## Configuration Files
54+
## Branding Logic
3255

33-
### `.env.community` - Community/Trustify Version
34-
- Uses Trustify branding
35-
- Points to https://guac.sh/trustify/
36-
- Shows "Trustify Overview of security issues"
37-
- Uses Trustify icon for remediations
56+
The system uses `displayName` for all branding decisions:
3857

39-
### `.env.redhat` - Red Hat Enterprise Version
40-
- Uses Red Hat branding
41-
- Points to Red Hat developer portal
42-
- Shows "Red Hat Overview of security Issues"
43-
- Uses Red Hat icon for remediations
44-
- Includes "from Red Hat" in remediation text
58+
- **Custom organization branding**: Uses the provided `displayName` (e.g., "MyOrg" shows "MyOrg Remediations")
59+
- **Default branding**: Used when no custom branding is configured
4560

46-
## How It Works
61+
## Icon System
62+
63+
The system uses a CSS-based icon override approach:
64+
65+
- **Default icon**: Built-in Trustify logo (PNG)
66+
- **Custom icons**: Organizations can override the default icon using CSS in their private projects
67+
68+
## Examples
69+
70+
### Method 1: Using Predefined Profile
71+
72+
**Default branding:**
73+
```bash
74+
# Default behavior (no profile needed)
75+
./mvnw quarkus:dev
76+
```
77+
78+
**Custom organization branding:**
79+
```bash
80+
# Example using a custom profile
81+
./mvnw quarkus:dev -Dquarkus.profile=myorg
82+
```
83+
84+
**Production builds with profiles:**
85+
```bash
86+
# Default production build
87+
./mvnw clean package
88+
89+
# Custom organization production build
90+
./mvnw clean package -Dquarkus.profile=myorg
91+
```
92+
93+
### Method 2: Using Environment Variables
94+
95+
**Default Configuration (no environment variables needed):**
96+
```bash
97+
# No environment variables needed - uses default Trustify branding
98+
./mvnw quarkus:dev
99+
```
100+
101+
**Custom Organization Configuration:**
102+
```bash
103+
export BRANDING_DISPLAY_NAME="MyOrg"
104+
export BRANDING_EXPLORE_URL="https://example.com/security-tools"
105+
export BRANDING_EXPLORE_TITLE="Learn about MyOrg Security"
106+
export BRANDING_EXPLORE_DESCRIPTION="Explore our comprehensive security analysis tools and vulnerability management platform."
107+
108+
./mvnw quarkus:dev
109+
```
110+
111+
## Backend Integration
112+
113+
The branding configuration is handled using Quarkus `@ConfigMapping`:
114+
115+
**BrandingConfig.java:**
116+
```java
117+
@ConfigMapping(prefix = "branding")
118+
public interface BrandingConfig {
119+
String displayName();
120+
String exploreUrl();
121+
String exploreTitle();
122+
String exploreDescription();
123+
}
124+
```
125+
126+
**ReportTemplate.java:**
127+
```java
128+
@Inject Optional<BrandingConfig> brandingConfig;
129+
130+
// Only include branding config if it's present
131+
brandingConfig.ifPresent(config -> params.put("brandingConfig", getBrandingConfigMap(config)));
132+
```
133+
134+
The configuration is then passed to the frontend via the `appData` object in the Freemarker template.
135+
136+
## Profile Configuration
137+
138+
The branding profiles are defined in `src/main/resources/application.properties`:
139+
140+
```properties
141+
# Default branding configuration (Community/Trustify)
142+
branding.display.name=Trustify
143+
branding.explore.url=https://guac.sh/trustify/
144+
branding.explore.title=Learn more about Trustify
145+
branding.explore.description=The Trustify project is a collection of software components that enables you to store and retrieve Software Bill of Materials (SBOMs), and advisory documents.
146+
147+
# Example: Custom organization branding profile
148+
%myorg.branding.display.name=MyOrg
149+
%myorg.branding.explore.url=https://example.com/security-tools
150+
%myorg.branding.explore.title=Learn about MyOrg Security
151+
%myorg.branding.explore.description=Explore our comprehensive security analysis tools and vulnerability management platform.
152+
```
47153

48-
1. **Environment Variables**: Different `.env` files define branding configuration
49-
2. **Branding Config**: `src/config/branding.ts` reads environment variables and provides typed configuration
50-
3. **Conditional Rendering**: Components use `getBrandingConfig()` to conditionally render content based on branding mode
154+
## Creating Custom Branding Profiles
51155

52-
## Customizing Branding
156+
To create a new branding profile for your organization:
53157

54-
To modify branding, edit the respective `.env` file:
158+
1. **Add profile configuration** to `src/main/resources/application.properties`:
159+
```properties
160+
# Replace 'myorg' with your organization identifier
161+
%myorg.branding.display.name=Your Organization Name
162+
%myorg.branding.explore.url=https://your-org.com/security
163+
%myorg.branding.explore.title=Learn about Your Org Security
164+
%myorg.branding.explore.description=Your custom description here.
165+
```
166+
167+
2. **Use the profile** when running the application:
168+
```bash
169+
./mvnw quarkus:dev -Dquarkus.profile=myorg
170+
```
171+
172+
3. **Override icons in private projects** using CSS to provide custom organization icons
173+
174+
Environment variables will override profile settings if both are provided.
175+
176+
## Custom Icon Implementation
177+
178+
To implement a completely custom icon for your organization, follow this step-by-step guide:
179+
180+
**Step 1: Add your custom icon**
181+
```bash
182+
# Copy your organization's icon to the UI assets directory
183+
cp /path/to/myorg.png /path/to/trustify-dependency-analytics/ui/src/images/myorg.png
184+
```
185+
186+
**Step 2: Create CSS override**
187+
Add the following CSS to `/ui/src/index.css`:
188+
```css
189+
/* Custom icon override - Replace Trustify icon with MyOrg icon */
190+
img[alt="My Org Icon"] {
191+
content: url('./images/myorg.png') !important;
192+
width: 16px !important;
193+
height: 16px !important;
194+
}
195+
```
196+
197+
**Step 3: Configure organization branding**
198+
Add to `/src/main/resources/application.properties`:
199+
```properties
200+
# MyOrg custom branding profile
201+
%myorg.branding.display.name=MyOrg
202+
%myorg.branding.explore.url=https://myorg.com/security
203+
%myorg.branding.explore.title=Learn about MyOrg Security
204+
%myorg.branding.explore.description=Explore our comprehensive security analysis tools and vulnerability management platform.
205+
```
206+
207+
**Step 4: Build with your changes**
208+
```bash
209+
cd ui && npm run build
210+
```
55211

212+
**Step 5: Run with your branding**
56213
```bash
57-
REACT_APP_BRANDING_MODE=community|redhat
58-
REACT_APP_BRAND_NAME=Your Brand Name
59-
REACT_APP_BRAND_TITLE=Your Overview Title
60-
REACT_APP_REMEDIATION_TITLE=Your Remediation Title
61-
REACT_APP_BRAND_ICON=icon_name
62-
REACT_APP_BRAND_URL=https://your-url.com
63-
REACT_APP_EXPLORE_TITLE=Your Explore Title
64-
REACT_APP_EXPLORE_DESCRIPTION=Your description text
214+
./mvnw quarkus:dev -Dquarkus.profile=myorg
65215
```

ui/package.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@
2626
},
2727
"scripts": {
2828
"start": "craco start",
29-
"start:community": "env-cmd -f .env.community craco start",
30-
"start:redhat": "env-cmd -f .env.redhat craco start",
3129
"build": "craco build && yarn copy:js:main && yarn copy:js:vendor && yarn copy:css:main && yarn copy:css:vendor",
32-
"build:community": "env-cmd -f .env.community craco build && yarn copy:js:main && yarn copy:js:vendor && yarn copy:css:main && yarn copy:css:vendor",
33-
"build:redhat": "env-cmd -f .env.redhat craco build && yarn copy:js:main && yarn copy:js:vendor && yarn copy:css:main && yarn copy:css:vendor",
3430
"test": "react-scripts test",
3531
"eject": "react-scripts eject",
3632
"copy:js:main": "cp build/static/js/main.js ../src/main/resources/freemarker/templates/generated/main.js",
@@ -64,7 +60,6 @@
6460
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
6561
"@babel/plugin-transform-destructuring": "^7.25.9",
6662
"@craco/craco": "^7.1.0",
67-
"env-cmd": "^10.1.0",
6863
"prettier": "^3.0.1"
6964
}
7065
}

0 commit comments

Comments
 (0)