Skip to content

Commit

Permalink
Merge branch 'cisagov:master' into DarkMode
Browse files Browse the repository at this point in the history
  • Loading branch information
hawkishpolicy authored Mar 4, 2024
2 parents 60ed52f + 881b250 commit 7ae5f30
Show file tree
Hide file tree
Showing 20 changed files with 203 additions and 179 deletions.
2 changes: 1 addition & 1 deletion backend/env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ prod:
REACT_APP_RANDOM_PASSWORD: ${ssm:/crossfeed/prod/REACT_APP_RANDOM_PASSWORD}
MATOMO_URL: http://matomo.crossfeed.local
EXPORT_BUCKET_NAME: cisa-crossfeed-prod-exports
PE_API_URL: ${ssm:/crossfeed/staging/PE_API_URL}
PE_API_URL: ${ssm:/crossfeed/prod/PE_API_URL}
REPORTS_BUCKET_NAME: cisa-crossfeed-prod-reports
CLOUDWATCH_BUCKET_NAME: cisa-crossfeed-prod-cloudwatch
STAGE: prod
Expand Down
2 changes: 1 addition & 1 deletion backend/src/api/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ app.use(express.json({ strict: false }));

app.use(
cors({
origin: [/crossfeed\.cyber\.dhs\.gov$/, /localhost$/],
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
})
);
Expand Down
7 changes: 7 additions & 0 deletions backend/src/api/organizations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,13 +367,18 @@ export const create = wrapHandler(async (event) => {
* - Organizations
*/
export const list = wrapHandler(async (event) => {
console.log('list function called with event: ', event);

if (!isGlobalViewAdmin(event) && getOrgMemberships(event).length === 0) {
return {
//TODO: Should we return a 403?
statusCode: 200,
body: JSON.stringify([])
};
}
await connectToDatabase();
console.log('Database connected');

let where: any = { parent: null };
if (!isGlobalViewAdmin(event)) {
where = { id: In(getOrgMemberships(event)), parent: null };
Expand All @@ -384,6 +389,8 @@ export const list = wrapHandler(async (event) => {
order: { name: 'ASC' }
});

console.log('Organization.find result: ', result);

return {
statusCode: 200,
body: JSON.stringify(result)
Expand Down
62 changes: 33 additions & 29 deletions backend/src/tasks/vuln-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,35 +189,38 @@ export const handler = async (commandOptions: CommandOptions) => {
}

let serviceId;
try {
// Save discovered services to the Service table
[serviceId] = await saveServicesToDb([
plainToClass(Service, {
domain: { id: domainId },
discoveredBy: { id: commandOptions.scanId },
port: vuln.port,
lastSeen: new Date(vuln.last_seen),
banner:
vuln.banner == null ? null : sanitizeStringField(vuln.banner),
serviceSource: vuln.source,
shodanResults:
vuln.source === 'shodan'
? {
product: vuln.product,
version: vuln.version,
cpe: vuln.cpe
}
: {}
})
]);
console.log('Saved services.');
} catch (e) {
console.error(
'Could not save services. Continuing to next vulnerability.'
);
console.error(e);
continue;
if (vuln.port != null) {
try {
// Save discovered services to the Service table
[serviceId] = await saveServicesToDb([
plainToClass(Service, {
domain: { id: domainId },
discoveredBy: { id: commandOptions.scanId },
port: vuln.port,
lastSeen: new Date(vuln.last_seen),
banner:
vuln.banner == null ? null : sanitizeStringField(vuln.banner),
serviceSource: vuln.source,
shodanResults:
vuln.source === 'shodan'
? {
product: vuln.product,
version: vuln.version,
cpe: vuln.cpe
}
: {}
})
]);
console.log('Saved services.');
} catch (e) {
console.error(
'Could not save services. Continuing to next vulnerability.'
);
console.error(e);
continue;
}
}

try {
const vulns: Vulnerability[] = [];
vulns.push(
Expand All @@ -229,11 +232,12 @@ export const handler = async (commandOptions: CommandOptions) => {
cwe: vuln.cwe,
description: vuln.description,
cvss: vuln.cvss,
severity: vuln.severity,
state: vuln.state,
structuredData: vuln.structuredData,
source: vuln.source,
needsPopulation: vuln.needsPopulation,
service: { id: serviceId }
service: vuln.port == null ? null : { id: serviceId }
})
);
await saveVulnerabilitiesToDb(vulns, false);
Expand Down
2 changes: 1 addition & 1 deletion frontend/scripts/constants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
//CORS Options
export const ALLOW_ORIGIN = [/crossfeed\.cyber\.dhs\.gov$/, /localhost$/];
export const ALLOW_ORIGIN = '*';
export const ALLOW_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'];
20 changes: 10 additions & 10 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const App: React.FC = () => (
exact
path="/inventory"
component={SearchPage}
permissions={['globalView']}
permissions={['standard', 'globalView']}
/>
<RouteGuard
path="/inventory/domain/:domainId"
Expand All @@ -142,19 +142,19 @@ const App: React.FC = () => (
path="/inventory/vulnerabilities"
exact
component={Vulnerabilities}
permissions={['globalView']}
permissions={['standard', 'globalView']}
/>
<RouteGuard
path="/inventory/vulnerabilities/grouped"
component={(props) => (
<Vulnerabilities {...props} groupBy="title" />
)}
permissions={['globalView']}
permissions={['standard', 'globalView']}
/>
<RouteGuard
path="/inventory/vulnerability/:vulnerabilityId"
component={Vulnerability}
permissions={['globalView']}
permissions={['standard', 'globalView']}
/>
<RouteGuard
path="/feeds"
Expand All @@ -170,28 +170,28 @@ const App: React.FC = () => (
path="/scans"
exact
component={Scans}
permissions={['globalView']}
permissions={['standard', 'globalView']}
/>
<RouteGuard
path="/scans/history"
component={Scans}
exact
permissions={['globalView']}
permissions={['standard', 'globalView']}
/>
<RouteGuard
path="/scans/:scanId"
component={Scan}
permissions={['globalView']}
permissions={['standard', 'globalView']}
/>
<RouteGuard
path="/organizations/:organizationId"
component={Organization}
permissions={['standard', 'globalView']}
permissions={['globalView']}
/>
<RouteGuard
path="/organizations"
component={Organizations}
permissions={['globalView', 'regionalAdmin']}
permissions={['standard', 'globalView', 'regionalAdmin']}
/>
<RouteGuard
path="/users"
Expand All @@ -201,7 +201,7 @@ const App: React.FC = () => (
<RouteGuard
path="/settings"
component={Settings}
permissions={['globalView', 'regionalAdmin']}
permissions={['standard', 'globalView', 'regionalAdmin']}
/>
<RouteGuard
path="/region-admin-dashboard"
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const CrossfeedFooter: React.FC = (props) => {
<Link
className={footerClasses.footerNavLink}
href="https://docs.crossfeed.cyber.dhs.gov/"
target="_blank"
>
Documentation
</Link>
Expand All @@ -39,6 +40,7 @@ export const CrossfeedFooter: React.FC = (props) => {
<Link
className={footerClasses.footerNavLink}
href="https://www.cisa.gov"
target="_blank"
>
CISA Homepage
</Link>
Expand Down
26 changes: 13 additions & 13 deletions frontend/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ const HeaderNoCtx: React.FC<ContextType> = (props) => {

const fetchOrganizations = useCallback(async () => {
try {
const rows = await apiGet<Organization[]>('/organizations/');
const rows = await apiGet<Organization[]>('/v2/organizations/');
let tags: (OrganizationTag | Organization)[] = [];
if (userLevel === GLOBAL_ADMIN) {
tags = await apiGet<OrganizationTag[]>('/organizations/tags');
Expand Down Expand Up @@ -294,12 +294,12 @@ const HeaderNoCtx: React.FC<ContextType> = (props) => {
users: GLOBAL_ADMIN,
exact: true
},
{
title: 'My Organizations',
path: '/organizations',
users: STANDARD_USER,
exact: true
},
// {
// title: 'My Organizations',
// path: '/organizations',
// users: STANDARD_USER,
// exact: true
// },
{
title: 'Manage Users',
path: '/users',
Expand Down Expand Up @@ -335,12 +335,12 @@ const HeaderNoCtx: React.FC<ContextType> = (props) => {
users: GLOBAL_ADMIN,
exact: true
},
{
title: 'My Organizations',
path: '/organizations',
users: STANDARD_USER,
exact: true
},
// {
// title: 'My Organizations',
// path: '/organizations',
// users: STANDARD_USER,
// exact: true
// },
{
title: 'Manage Users',
path: '/users',
Expand Down
43 changes: 24 additions & 19 deletions frontend/src/components/OrganizationList/OrganizationList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useCallback } from 'react';
import EditNoteOutlinedIcon from '@mui/icons-material/EditNoteOutlined';
import { Organization } from 'types';
import { Box, Button, IconButton, Grid } from '@mui/material';
import { Alert, Box, Button, IconButton, Grid } from '@mui/material';
import { DataGrid, GridColDef, GridRenderCellParams } from '@mui/x-data-grid';
import { useHistory } from 'react-router-dom';
import { Add } from '@mui/icons-material';
Expand All @@ -16,13 +16,14 @@ export const OrganizationList: React.FC<{
const [organizations, setOrganizations] = useState<Organization[]>([]);
const [dialogOpen, setDialogOpen] = useState(false);
const history = useHistory();
const getOrgsURL = `/v2/organizations/`;

const orgCols: GridColDef[] = [
{ field: 'name', headerName: 'Organization', minWidth: 100, flex: 2 },
{ field: 'userCount', headerName: 'Members', minWidth: 100, flex: 1 },
// { field: 'userCount', headerName: 'Members', minWidth: 100, flex: 1 },
{ field: 'state', headerName: 'State', minWidth: 100, flex: 1 },
{ field: 'regionId', headerName: 'Region', minWidth: 100, flex: 1 },
{ field: 'tagNames', headerName: 'Tags', minWidth: 100, flex: 1 },
// { field: 'tagNames', headerName: 'Tags', minWidth: 100, flex: 1 },
{
field: 'view',
headerName: 'View/Edit',
Expand Down Expand Up @@ -61,16 +62,16 @@ export const OrganizationList: React.FC<{

const fetchOrganizations = useCallback(async () => {
try {
const rows = await apiGet<Organization[]>('/organizations/');
rows.forEach((obj) => {
obj.userCount = obj.userRoles.length;
obj.tagNames = obj.tags.map((tag) => tag.name);
});
const rows = await apiGet<Organization[]>(getOrgsURL);
// rows.forEach((obj) => {
// // obj.userCount = obj.userRoles.length;
// obj.tagNames = obj.tags.map((tag) => tag.name);
// });
setOrganizations(rows);
} catch (e) {
console.error(e);
}
}, [apiGet]);
}, [apiGet, getOrgsURL]);

React.useEffect(() => {
if (!parent) fetchOrganizations();
Expand All @@ -91,21 +92,25 @@ export const OrganizationList: React.FC<{
);

return (
<>
<Box mb={3}>
<Grid
container
spacing={2}
style={{ margin: '0 auto', marginTop: '1rem', maxWidth: '1000px' }}
></Grid>
<Box sx={{ backgroundColor: 'white' }}>
<DataGrid
rows={organizations}
columns={orgCols}
slots={{ toolbar: CustomToolbar }}
slotProps={{
toolbar: { children: addOrgButton }
}}
/>
{organizations?.length === 0 ? (
<Alert severity="warning">No organizations found.</Alert>
) : (
<DataGrid
rows={organizations}
columns={orgCols}
slots={{ toolbar: CustomToolbar }}
slotProps={{
toolbar: { children: addOrgButton }
}}
/>
)}
</Box>
<OrganizationForm
onSubmit={onSubmit}
Expand All @@ -114,6 +119,6 @@ export const OrganizationList: React.FC<{
type="create"
parent={parent}
></OrganizationForm>
</>
</Box>
);
};
18 changes: 9 additions & 9 deletions frontend/src/components/WarningBanner/Warning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ export const CrossfeedWarning: React.FC = (props) => {
Crossfeed is hosted by Department of Homeland Security (DHS)
Cybersecurity and Infrastructure Security Agency (CISA)
Cybersecurity Division (CSD) Vulnerability Management (VM) Attack
Attack Attack Surface Management (ASM) Automation is computer
systems systems may systems may be monitored for all unlawful
unlawful purposes, including to ensure their use is authorized,
for management of the system, to protection against security
procedures, survivability, and operational operational operational
operational security. All information, information, including
information, placed or sent this system may be monitored.
Monitoring includes actives attacks by authorized US Government
entities to test or verify the security of this system.
Surface Management (ASM) Automation is computer systems systems
may systems may be monitored for all unlawful unlawful purposes,
including to ensure their use is authorized, for management of the
system, to protection against security procedures, survivability,
and operational operational operational operational security. All
information, information, including information, placed or sent
this system may be monitored. Monitoring includes actives attacks
by authorized US Government entities to test or verify the
security of this system.
<br />
<br />
Use of the computer system, authorized or unauthorized,
Expand Down
Loading

0 comments on commit 7ae5f30

Please sign in to comment.