Skip to content

Commit

Permalink
Merge pull request #1 from polarityio/develop
Browse files Browse the repository at this point in the history
Initial Release
  • Loading branch information
penwoodjon authored Aug 3, 2022
2 parents 1acb448 + f613a47 commit 0e1f4d7
Show file tree
Hide file tree
Showing 33 changed files with 1,501 additions and 217 deletions.
90 changes: 90 additions & 0 deletions AddSlackAppToWorkspace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Create Polarity Slack App

1. Go to https://api.slack.com/apps/
2. Click on `Create New App`
<div>
<img alt="Click on Create New App" src="./assets/click-on-create-new-app.png">
</div>

3. Select `From an app manifest`
<div>
<img alt="Click on From App Manifest" src="./assets/click-from-an-app-manifest.png">
</div>

4. Select your workspace you would like the integration to run on via the dropdown, then Click `Next`
<div>
<img alt="Select Workspace" src="./assets/select-workspace-from-dropdown.png">
</div>

5. Delete the contents of the YAML App Manifest
<div>
<img alt="Delete App Manifest" src="./assets/delete-app-manifest.png">
</div>

6. Paste in ***this*** App Manifest in the empty input, then Click `Next`:
```yaml
display_information:
name: Polarity
description: Polarity's Slack Application for use in tandem with our Polarity Slack Integration.
background_color: "#53a13b"
features:
app_home:
home_tab_enabled: false
messages_tab_enabled: true
messages_tab_read_only_enabled: true
bot_user:
display_name: Polarity
always_online: true
oauth_config:
scopes:
user:
- search:read
bot:
- channels:read
- groups:read
- im:read
- mpim:read
- chat:write
- chat:write.customize
- chat:write.public

settings:
org_deploy_enabled: false
socket_mode_enabled: false
token_rotation_enabled: false
```
7. Click `Create`
<div>
<img alt="Click Create" src="./assets/click-create.png">
</div>

8. On the `Polarity` Slack app page it brings you to, click `Install to Workspace`
<div>
<img alt="Install to Workspace" src="./assets/install-to-workspace.png">
</div>

9. Click `Allow`
> ***NOTE:*** The user that clicks allow will determine which private channels can be searched. Creating a new user with access to the private channels you want to search and clicking `Allow` while logged into this user is recommended.
<div>
<img alt="Click Allow" src="./assets/click-allow.png">
</div>

10. Download the image found here: https://github.com/polarityio/slack/raw/develop/assets/app-profile-picture.png
<div>
<img width="75"style="border-radius: 49%" alt="App Profile Picture" src="./assets/app-profile-picture.png">
</div>

11. On the `Basic Information` tab
<div>
<img alt="Basic Information Tab" src="./assets/basic-info-tab.png">
</div>
- Scroll down to the `Display Information` section, click `+ Add App Icon`, and select the image from `Step 10`.
<div>
<img alt="Add Icon" src="./assets/add-icon.png">
</div>

12. Now you `User Token` and `Bot Token` can be found on the `OAuth & Permissions` tab
<div>
<img alt="Get User and Bot Token" src="./assets/get-tokens.png">
</div>
56 changes: 51 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,62 @@
# Polarity __TODO__ Integration
# Polarity Slack Integration

![image](https://img.shields.io/badge/status-beta-green.svg)

TODO: desc
The Polarity Slack Integration allows you to ***Send Messages to Channels in Slack*** directly from the Overlay , and ***Search Entities in Slack Channel Messages*** for all entity types.


> ***NOTE:*** You must go through the process of creating your `Polarity Slack App` in your Slack instance. Instructions on how to do this can be found in the [**Polarity App Installation Guide**](./AddSlackAppToWorkspace.md).
To learn more about __TODO__, visit the [official website](__TODO__).
<div style="display:flex; justify-content:center; align-items: flex-start;">
<img width="300" alt="Integration Example Search" src="./assets/int-example-search.png">
<img width="300" alt="Integration Example Message Channels" src="./assets/int-example-message-channels.png">
</div>
To learn more about Slack, visit the [official website](https://slack.com/).

## Private Channels
- ***Searching:*** To search private channels, make sure the user that clicked `Allow` in `Step 9` in the [**Polarity App Installation Guide**](./AddSlackAppToWorkspace.md) is in that private channel you want to search.
- ***Messaging:*** To allow messaging in private channels, you must first send a `@Polarity` message in the private channel, and invite the app to the channel.

## __TODO__ Integration Options
__TODO__

## Slack Integration Options
### Slack API URL
The URL of the Slack API you would like to connect to.

### User Token
The API User Token associated with the your Polarity Slack App. Your User Token should start with "xoxp-###...". Optional if you don't wish to search.

### Bot Token
The API Bot Token associated with the your Polarity Slack App. Your User Token should start with "xoxb-###...".

### Ignore Entity Types
When checked, strings searched that are one of our predefined entity types (IPv4, IPv6, IPv4CIDR, MD5, SHA1, SHA256, MAC, string, email, domain, url, and cve) will not be displayed in the overlay.

> ***NOTE:*** By default commented out in the `./config/config.js` file.
### Minimum Input Length
The minimum text input length for a string to be considered Input. (default: 5)

### Maximum Input Length
The maximum text input length for a string to be considered Input. (default: 256)

### Allow Searching Slack Messages
If checked, all entities will be search in Slack.
> ***NOTE:*** This option must be set to "Users can view only" or "Users can view and edit"
### Sort Message Search Results By
Return the search results in a particular order. Options are `Best Search Match First`, `Most Recent Search Match First`, and `Oldest Search Match First`

### Allow Sending Slack Messages
If checked, a prompt will show for every entity searched, regardless of Search Results, allowing you to send a message to any Channels listed below.
> ***NOTE:*** This option must be set to "Users can view only" or "Users can view and edit"
### Slack Channel Names for Messages
A comma separated list of Channels Names anyone using the Integration can send a messages to. If you want to send messages to a private channel, you must send a message in the channel containing "@Polarity" in it first.

### Slack Messaging Display Name
The name you wish to use when Posting Messages on Slack Channels. If left empty the default display name will just be "Polarity".

### Add Entity Value to Message By Default
If checked, the entity value will be added to the Slack Messaging Box in the Overlay by Default

## Installation Instructions

Expand Down
Binary file added assets/add-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/app-profile-picture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/basic-info-tab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/click-allow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/click-create.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/click-from-an-app-manifest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/click-on-create-new-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/delete-app-manifest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/get-tokens.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/install-to-workspace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/int-example-message-channels.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/int-example-search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/select-workspace-from-dropdown.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
134 changes: 106 additions & 28 deletions components/block.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,136 @@
polarity.export = PolarityComponent.extend({
details: Ember.computed.alias('block.data.details'),
timezone: Ember.computed('Intl', function () {
return Intl.DateTimeFormat().resolvedOptions().timeZone;
}),
availableChannelsToMessage: [],
messageValue: '',
sendingMessage: false,
messagingToast: '',
errorMessagingToast: '',
sendingMessage: '',
selectedChannel: {},
foundMessageSearchResultsOpen: false,
loadingMoreMessages: false,
init() {
//TODO: Change or delete
const availableChannelsToMessage = this.get('block.userOptions.messagingChannelNames')
.split(',')
.map((channelName) =>
this.get('details.channels').find(
({ name }) => name == channelName.trim().toLowerCase().replace(/ /g, '-')
)
)
.filter((x) => x);

this.set('availableChannelsToMessage', availableChannelsToMessage);
this.set('selectedChannel', availableChannelsToMessage[0]);
this.set(
'messageValue',
this.get('block.userOptions.addEntityToMessageByDefault')
? this.get('block.entity.value')
: ''
);

this._super(...arguments);
},
observer: Ember.on(
'willUpdate',
Ember.observer('details.maxUniqueKeyNumber', function () {
if (this.get('maxUniqueKeyNumber') !== this.get('_maxUniqueKeyNumber')) {
this.set('_maxUniqueKeyNumber', this.get('maxUniqueKeyNumber'));

//TODO: Change or delete
}
})
),
actions: {
toggleOwnershipMessage: function () {
this.toggleProperty('change or delete');
toggleShowingFoundMessages: function () {
this.toggleProperty('foundMessageSearchResultsOpen');
},
showMoreOfMessage: function (index) {
this.set(
`details.foundMessagesFromSearch.${index}.displayMessage`,
this.get(`details.foundMessagesFromSearch.${index}.message`)
);
this.set(`details.foundMessagesFromSearch.${index}.shouldShowMoreMessage`, false);
},
selectChannel: function (selectedChannelId) {
this.set(
'selectedChannel',
this.get('details.channels').find(({ id }) => id == selectedChannelId)
);
},
loadMoreSearchMessages: function () {
if(this.get('loadingMoreMessages')) return;
const outerThis = this;
outerThis.set('loadingMoreMessages', true);
outerThis.get('block').notifyPropertyChange('data');

outerThis
.sendIntegrationMessage({
action: 'loadMoreSearchMessages',
data: {
entity: this.get('block.entity'),
channels: this.get('details.channels'),
currentSearchResultsPage: this.get('details.currentSearchResultsPage')
}
})
.then(
({
foundMessagesFromSearch,
currentSearchResultsPage,
totalNumberOfSearchResultPages
}) => {
this.set(
'details.foundMessagesFromSearch',
this.get('details.foundMessagesFromSearch').concat(foundMessagesFromSearch)
);
this.set('details.currentSearchResultsPage', currentSearchResultsPage);
this.set(
'details.totalNumberOfSearchResultPages',
totalNumberOfSearchResultPages
);
}
)
.catch((err) => {
// Remove the `... Load More` button
this.set(
'details.currentSearchResultsPage',
this.get('details.totalNumberOfSearchResultPages')
);
})
.finally(() => {
outerThis.set('loadingMoreMessages', false);
outerThis.get('block').notifyPropertyChange('data');
});
},
onMessageExample: function () {
sendMessage: function () {
const outerThis = this;
outerThis.set('asdfMessage', '');
outerThis.set('asdfErrorMessage', '');
outerThis.set('asdfIsRunning', true);
outerThis.set('messagingToast', '');
outerThis.set('errorMessagingToast', '');
outerThis.set('sendingMessage', true);
outerThis.get('block').notifyPropertyChange('data');

outerThis
.sendIntegrationMessage({
action: 'onMessageExample',
action: 'sendMessage',
data: {
entity: outerThis.get('entity'),
text: this.get('messageValue'),
channel: this.get('selectedChannel').id
}
})
.then(({ result }) => {
outerThis.set('change or delete', result);
outerThis.set('asdfMessage', 'Successfully asdf IOC');
.then(() => {
outerThis.set('messageValue', '');
outerThis.set('messagingToast', 'Successfully Sent Message');
})
.catch((err) => {
outerThis.set(
'asdfErrorMessage',
'Failed to asdf IOC: ' +
'errorMessagingToast',
'Failed to Send Message: ' +
(err &&
(err.detail || err.err || err.message || err.title || err.description)) ||
'Unknown Reason'
);
})
.finally(() => {
outerThis.set('asdfIsRunning', false);
outerThis.set('sendingMessage', false);
outerThis.get('block').notifyPropertyChange('data');
setTimeout(() => {
outerThis.set('asdfMessage', '');
outerThis.set('asdfErrorMessage', '');
outerThis.set('messagingToast', '');
outerThis.set('errorMessagingToast', '');
outerThis.get('block').notifyPropertyChange('data');
}, 5000);
});
},
}
}
});
Loading

0 comments on commit 0e1f4d7

Please sign in to comment.