Skip to content

Commit

Permalink
Merge pull request #133 from Security-Onion-Solutions/dev
Browse files Browse the repository at this point in the history
2.3.140
  • Loading branch information
TOoSmOotH authored Jul 18, 2022
2 parents 961500b + b6dd7ab commit 7ebf7e6
Show file tree
Hide file tree
Showing 17 changed files with 354 additions and 30 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/contrib.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: contrib
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened,closed,synchronize]

jobs:
CLAssistant:
runs-on: ubuntu-latest
steps:
- name: "Contributor Check"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
uses: cla-assistant/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }}
with:
path-to-signatures: 'signatures_v1.json'
path-to-document: 'https://securityonionsolutions.com/cla'
allowlist: dependabot[bot],jertel,dougburks,TOoSmOotH,weslambert,defensivedepth,m0duspwnens
remote-organization-name: Security-Onion-Solutions
remote-repository-name: licensing

2 changes: 1 addition & 1 deletion .github/workflows/leaktest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ jobs:
fetch-depth: '0'

- name: Gitleaks
uses: zricethezav/gitleaks-action@master
uses: gitleaks/gitleaks-action@v1.6.0
2 changes: 1 addition & 1 deletion Dockerfile.kratos
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
FROM ghcr.io/security-onion-solutions/golang:alpine AS builder

ARG OWNER=ory
ARG VERSION=v0.9.0-alpha.3
ARG VERSION=v0.10.1

RUN addgroup -S ory; \
adduser -S ory -G ory -D -H -s /bin/nologin
Expand Down
8 changes: 7 additions & 1 deletion agent/modules/analyze/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,13 @@ func (analyze *Analyze) ProcessJob(job *model.Job, reader io.ReadCloser) (io.Rea
} else {
input := "{}"
if val, ok := job.Filter.Parameters["artifact"]; ok {
bytes, err := json.WriteJson(val)
var bytes []byte
switch val.(type) {
case string:
bytes, err = json.WriteJson(strings.TrimSpace(val.(string)))
default:
bytes, err = json.WriteJson(val)
}
if err != nil {
log.WithError(err).Error("Unable to convert artifact parameter to JSON string")
} else {
Expand Down
4 changes: 3 additions & 1 deletion agent/modules/analyze/analyze_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ func TestAnalyzersExecuted(tester *testing.T) {

job := model.NewJob()
job.Kind = "analyze"
job.Filter.Parameters["foo"] = "bar"
job.Filter.Parameters["artifact"] = " bar\n"
reader, err := sq.ProcessJob(job, nil)
assert.Nil(tester, reader)
assert.Nil(tester, err)
assert.Len(tester, job.Results, 1)
assert.Equal(tester, "whois", job.Results[0].Id)
assert.Equal(tester, "something here that is so long it will need to be ...", job.Results[0].Summary)
data := job.Results[0].Data.(map[string]interface{})
assert.Equal(tester, "bar", data["input"])
}

func TestCreateResult(tester *testing.T) {
Expand Down
5 changes: 4 additions & 1 deletion agent/modules/analyze/test-resources/whois/whois.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import sys

def main():
print('{"result":{ "requestId": "something-generated-by-whois", "someother_field": "more data" }, "summary": "something here that is so long it will need to be shortened"}')
input = sys.argv[1]
print('{"input": %s, "result":{ "requestId": "something-generated-by-whois", "someother_field": "more data"}, "summary": "something here that is so long it will need to be shortened"}' % (input))

if __name__ == "__main__":
main()
14 changes: 14 additions & 0 deletions html/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,17 @@ td {
.case.markdown-icon:hover i {
color: var(--v-primary-base);
}

.maximized {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: calc(100vh - 100px);
background-color: var(--v-background-base);
z-index: 1;
}

.maximized-bg {
overflow: hidden;
}
24 changes: 17 additions & 7 deletions html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@
</template>
{{ tipMessage }}
</v-snackbar>
<router-view></router-view>
<router-view id="main-view"></router-view>
<textarea id="clipboardBuffer"></textarea>
</v-main>
<v-footer app>
Expand Down Expand Up @@ -502,16 +502,22 @@ <h4 v-if="loaded">{{ i18n.eventTotal }} {{ totalEvents.toLocaleString() }}</h4>
<router-link class="mx-1" :to="buildToggleLegendRoute(group, groupIdx)" :title="i18n.toggleLegend" style="text-decoration: none; cursor: 'pointer'">
<v-icon>fa-list</v-icon>
</router-link>
<router-link class="mx-1" :to="buildMaximizeRoute(group, groupIdx)" :title="i18n.maximize" style="text-decoration: none; cursor: 'pointer'">
<v-icon>fa-expand</v-icon>
</router-link>
<v-btn icon class="mx-1" @click="removeGroupBy(groupIdx, -1)" :title="i18n.remove">
<v-icon>fa-trash</v-icon>
</v-btn>
<pie-chart v-if="group.chart_type == 'pie'" :chartdata="group.chart_data" :options="group.chart_options"/>
<bar-chart v-if="group.chart_type == 'bar'" :chartdata="group.chart_data" :options="group.chart_options"/>
<sankey-chart v-if="group.chart_type == 'sankey'" :chartdata="group.chart_data" :options="group.chart_options"/>
<pie-chart v-if="group.chart_type == 'pie'" :id="'group-' + groupIdx" :chartdata="group.chart_data" :options="group.chart_options"/>
<bar-chart v-if="group.chart_type == 'bar'" :id="'group-' + groupIdx" :chartdata="group.chart_data" :options="group.chart_options"/>
<sankey-chart v-if="group.chart_type == 'sankey'" :id="'group-' + groupIdx" :chartdata="group.chart_data" :options="group.chart_options"/>
</div>
<v-data-table v-if="!group.chart_type" class="elevation-1" :search="groupByFilter" dense :footer-props="groupByFooters" sort-by="count" sort-desc="true"
<v-data-table v-if="!group.chart_type" :id="'group-' + groupIdx" class="elevation-1"
:search="groupByFilter" dense
:footer-props="groupByFooters" :sort-by.sync="group.sortBy" :sort-desc.sync="group.sortDesc"
@update:sort-by="updateGroupBySort" @update:sort-desc="updateGroupBySort"
:items-per-page.sync="groupByItemsPerPage" must-sort :headers="group.headers" :items="group.data" :custom-sort="sortEvents">
<template v-for="(header, headerIdx) in group.headers" v-slot:["header." + header.value]="{ props }">
<template v-if="!group.maximized" v-for="(header, headerIdx) in group.headers" v-slot:["header." + header.value]="{ props }">
{{ header.text }}
<span class="table-header-actions mx-2">
<router-link v-if="header.value == 'count' && isAdvanced()" :to="buildGroupOptionRoute(groupIdx, [], 'pie')" :title="i18n.showPieChart" style="text-decoration: none; cursor: 'pointer'">
Expand All @@ -523,12 +529,15 @@ <h4 v-if="loaded">{{ i18n.eventTotal }} {{ totalEvents.toLocaleString() }}</h4>
<router-link v-if="header.value == 'count' && isAdvanced() && isGroupSankeyCapable(group, groupIdx)" icon x-small :to="buildGroupOptionRoute(groupIdx, [], 'sankey')" :title="i18n.showSankeyChart" style="text-decoration: none; cursor: 'pointer'">
<v-icon>fa-diagram-project</v-icon>
</router-link>
<router-link v-if="header.value == 'count' && isAdvanced()" class="mx-1" :to="buildMaximizeRoute(group, groupIdx)" :title="i18n.maximize" style="text-decoration: none; cursor: 'pointer'">
<v-icon>fa-expand</v-icon>
</router-link>
<v-btn v-if="header.value != 'count' && header.value != ''" icon x-small @click.stop="removeGroupBy(groupIdx,headerIdx - getGroupByFieldStartIndex())" :title="i18n.remove">
<v-icon>fa-trash</v-icon>
</v-btn>
</span>
</template>
<template v-slot:item="{ item, index }">
<template v-if="!group.maximized" v-slot:item="{ item, index }">
<tr>
<td v-if="aggregationActionsEnabled">
<v-btn id="alertButton" v-if="ackEnabled && item['event.severity_label']" class="mx-2" icon x-small
Expand Down Expand Up @@ -1717,6 +1726,7 @@ <h3 class="text--primary">{{ i18n.evidenceAdd }}</h3>
<v-combobox id="evidence-type" v-if="isPresetCustomEnabled('artifactType')" v-model="associatedForms['evidence'].artifactType" :items="selectList('artifactType')" persistent-hint :hint="i18n.artifactTypeHelp"/>
<v-file-input id="evidence-value" v-if="associatedForms['evidence'].artifactType == 'file'" show-size v-model="attachment" persistent-hint :hint="getAttachmentHelp()" :rules="[rules.fileSizeLimit, rules.fileNotEmpty, rules.fileRequired]"/>
<v-textarea id="evidence-value" v-if="associatedForms['evidence'].artifactType != 'file'" rows="2" :value="associatedForms['evidence'].value" @change="val => associatedForms['evidence'].value = val" :rules="[rules.required]" :placeholder="i18n.artifactValue" persistent-hint :hint="i18n.artifactValueHelp"/>
<v-checkbox v-if="isEvidenceBulkCapable()" id="evidence-bulk" v-model="associatedForms['evidence'].bulk" persistent-hint :hint="i18n.artifactBulkHelp"/>
<v-textarea id="evidence-description" rows="2" :value="associatedForms['evidence'].description" @change="val => associatedForms['evidence'].description = val" :placeholder="i18n.artifactDescription" persistent-hint :hint="i18n.artifactDescriptionHelp"/>
<v-checkbox id="evidence-ioc" v-model="associatedForms['evidence'].ioc" persistent-hint :hint="i18n.artifactIocHelp"/>
<v-select id="evidence-tlp" v-if="!isPresetCustomEnabled('tlp')" v-model="associatedForms['evidence'].tlp" :items="selectList('tlp')" persistent-hint :hint="i18n.caseTlpHelp"/>
Expand Down
56 changes: 55 additions & 1 deletion html/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,14 @@ $(document).ready(function() {
loadServerSettingsTime: 0,
user: null,
username: '',
maximizedParent: null,
maximizedOrigWidth: null,
maximizedOrigHeight: null,
maximizedCancelFn: null,
},
watch: {
'$vuetify.theme.dark': 'saveLocalSettings',
'toolbar': 'saveLocalSettings',
},
methods: {
formatActionContent(content, event, field, value, uriEncode = true) {
Expand Down Expand Up @@ -532,11 +537,15 @@ $(document).ready(function() {
},
saveLocalSettings() {
localStorage['settings.app.dark'] = this.$vuetify.theme.dark;
localStorage['settings.app.navbar'] = this.toolbar;
},
loadLocalSettings() {
if (localStorage['settings.app.dark'] != undefined) {
this.$vuetify.theme.dark = localStorage['settings.app.dark'] == "true";
}
if (localStorage['settings.app.navbar'] != undefined) {
this.toolbar = localStorage['settings.app.navbar'] == "true";
}
},
subscribe(kind, fn) {
this.ensureConnected();
Expand Down Expand Up @@ -744,6 +753,10 @@ $(document).ready(function() {
}
return this.i18n.na;
},
async getActiveUsers() {
const users = await this.getUsers();
return users.filter(user => user.status != 'locked');
},
async getUsers() {
try {
const response = await this.papi.get('users/');
Expand Down Expand Up @@ -796,7 +809,48 @@ $(document).ready(function() {
},
isAttentionNeeded() {
return this.isNewAlert() || this.isGridUnhealthy() || !this.connected || this.reconnecting;
}
},
isMaximized() {
return this.maximizedTarget != null;
},
maximizeById(targetId, escapeFn=null) {
const target = document.getElementById(targetId);
if (target) {
return this.maximize(target, escapeFn);
}
return false;
},
maximize(target, escapeFn=null) {
this.unmaximize();
this.maximizedTarget = target;
this.maximizedOrigWidth = target.style.width;
this.maximizedOrigHeight = target.style.height;
target.classList.add("maximized");
document.documentElement.classList.add("maximized-bg");
window.scrollTo(0,0);
this.maximizedCancelFn = escapeFn;
document.addEventListener('keydown', this.unmaximizeEscapeListener);
return true;
},
unmaximize(userInitiated=false) {
if (!this.maximizedTarget) return;
if (userInitiated && this.maximizedCancelFn) {
if (this.maximizedCancelFn(this.maximizeTarget)) return;
}
this.maximizedTarget.classList.remove("maximized");
document.documentElement.classList.remove("maximized-bg");
this.maximizedTarget.style.width = this.maximizedOrigWidth;
this.maximizedTarget.style.height = this.maximizedOrigHeight;
this.maximizedTarget = null;
this.maximizedCancelFn = null;
document.removeEventListener('keydown', this.unmaximizeEscapeListener);
},
unmaximizeEscapeListener(event) {
if (event.code == "Escape") {
this.unmaximize(true);
}
event.cancel();
},
},
created() {
this.log("Initializing application components");
Expand Down
70 changes: 69 additions & 1 deletion html/js/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,72 @@ test('truncate', () => {
expect(app.truncate("atthelimit!!", 10)).toBe("atthelimit!!");
expect(app.truncate("atthelimit!!!", 10)).toBe("atthelimit!!!");
expect(app.truncate("much longer value", 10)).toBe("much...value");
});
});

test('localSettings', () => {
app.toolbar = true;
app.saveLocalSettings();
app.toolbar = null;
app.loadLocalSettings();
expect(app.toolbar).toBe(true);
});

test('maximize', () => {
const element = document.createElement('div');
element.style.width = '12px';
element.style.height = '13px';

const cancelMock = jest.fn();
expect(app.isMaximized()).toBe(false);

app.maximize(element, cancelMock);

expect(app.isMaximized()).toBe(true);
expect(app.maximizedOrigWidth).toBe("12px");
expect(app.maximizedOrigHeight).toBe("13px");
expect(element.classList).toContain('maximized');
expect(document.documentElement.classList).toContain('maximized-bg');

app.unmaximize(true);

expect(app.isMaximized()).toBe(false);
expect(app.maximizedCancelFn).toBeNull();
expect(cancelMock).toHaveBeenCalledTimes(1);
expect(element.classList).not.toContain('maximized');
expect(document.documentElement.classList).not.toContain('maximized-bg');

// Maximize again
app.maximize(element);

expect(app.isMaximized()).toBe(true);

app.unmaximize(false);

expect(app.isMaximized()).toBe(false);

// should still only have been called once
expect(cancelMock).toHaveBeenCalledTimes(1);

expect(app.maximizedCancelFn).toBeNull();
expect(element.classList).not.toContain('maximized');
expect(document.documentElement.classList).not.toContain('maximized-bg');
});

test('getUsers', async () => {
const fakeUsers = [{ status: ''}, {status: 'locked'}];
var mock = mockPapi("get", {data: fakeUsers});
const showErrorMock = mockShowError(true);

const users = await app.getUsers();

expect(mock).toHaveBeenCalledWith('users/');
expect(showErrorMock).toHaveBeenCalledTimes(0);
expect(users.length).toBe(2);

mock = mockPapi("get", {data: fakeUsers});
const activeUsers = await app.getActiveUsers();

expect(mock).toHaveBeenCalledTimes(2);
expect(showErrorMock).toHaveBeenCalledTimes(0);
expect(activeUsers.length).toBe(1);
});
4 changes: 3 additions & 1 deletion html/js/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ const i18n = {
analyzer_urlhaus_invalid_url: 'Invalid URL',
analyzer_urlhaus_malware_download: 'Malware download',


artifactBulk: 'Bulk Add',
artifactBulkHelp: 'Enable this checkbox to have a separate observable added for each line of the provided value above',
artifactDescription: 'Description',
artifactDescriptionHelp: 'Provide an optional description',
artifactIoc: 'IOC',
Expand Down Expand Up @@ -328,6 +329,7 @@ const i18n = {
logout: 'Logout',
logoutFailure: 'Unable to initiate logout. Ensure server is accessible.',
markdownFormattingSupported: 'Markdown formatting supported',
maximize: 'Maximize View (ESC to cancel)',
md5: 'MD5',
message: 'Message',
minutes: 'minutes',
Expand Down
Loading

0 comments on commit 7ebf7e6

Please sign in to comment.