Merge pull request #206 from CIRCL/tags

Addition of tagging system
pull/207/head
Sami Mokaddem 2018-06-01 16:37:50 +02:00 committed by GitHub
commit 6704c4806b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 4273 additions and 57 deletions

13
.gitignore vendored
View File

@ -7,10 +7,15 @@
AILENV
redis-leveldb
redis
ardb
faup
tlsh
Blooms
LEVEL_DB_DATA
PASTES
bin/indexdir/
BASE64
DATA_ARDB
indexdir/
logs/
# Webstuff
@ -20,7 +25,7 @@ var/www/static/
!var/www/static/js/moduleTrending.js
!var/www/static/js/plot-graph.js
!var/www/static/js/trendingchart.js
var/www/templates/header.html # auto-generated
var/www/templates/header.html
# Local config
bin/packages/config.cfg
@ -28,4 +33,6 @@ bin/packages/config.cfg
# installed files
nltk_data/
doc/all_modules.txt
doc/module-data-flow.png # auto-generated
# auto generated
doc/module-data-flow.png
doc/data-flow.png

View File

@ -35,6 +35,7 @@ Features
* Detect Amazon AWS and Google API keys
* Detect Bitcoin address and Bitcoin private keys
* Detect private keys and certificate
* Tagging system with [MISP Galaxy](https://github.com/MISP/misp-galaxy) and [MISP Taxonomies](https://github.com/MISP/misp-taxonomies) tags
Installation
------------
@ -144,6 +145,11 @@ Browsing
![Browse-Pastes](./doc/screenshots/browse-important.png?raw=true "AIL framework browseImportantPastes")
Tagging system
--------
![Tags](./doc/screenshots/tags.png?raw=true "AIL framework tags")
Sentiment analysis
------------------

View File

@ -41,6 +41,8 @@ def search_api_key(message):
print(to_print)
publisher.warning('{}Checked {} found Google API Key;{}'.format(
to_print, len(google_api_key), paste.p_path))
msg = 'infoleak:automatic-detection="google-api-key";{}'.format(filename)
p.populate_set_out(msg, 'Tags')
if(len(aws_access_key) > 0 or len(aws_secret_key) > 0):
print('found AWS key')
@ -48,8 +50,13 @@ def search_api_key(message):
total = len(aws_access_key) + len(aws_secret_key)
publisher.warning('{}Checked {} found AWS Key;{}'.format(
to_print, total, paste.p_path))
msg = 'infoleak:automatic-detection="aws-key";{}'.format(filename)
p.populate_set_out(msg, 'Tags')
msg = 'infoleak:automatic-detection="api-key";{}'.format(filename)
p.populate_set_out(msg, 'Tags')
msg = 'apikey;{}'.format(filename)
p.populate_set_out(msg, 'alertHandler')
#Send to duplicate

View File

@ -65,6 +65,9 @@ def search_base64(content, message):
msg = ('base64;{}'.format(message))
p.populate_set_out( msg, 'alertHandler')
msg = 'infoleak:automatic-detection="base64";{}'.format(message)
p.populate_set_out(msg, 'Tags')
def save_base64_as_file(decode, type, hash, json_data):
filename_b64 = os.path.join(os.environ['AIL_HOME'],

View File

@ -63,7 +63,14 @@ def search_key(content, message, paste):
publisher.warning(to_print)
msg = ('bitcoin;{}'.format(message))
p.populate_set_out( msg, 'alertHandler')
msg = 'infoleak:automatic-detection="bitcoin-address";{}'.format(message)
p.populate_set_out(msg, 'Tags')
if(key):
msg = 'infoleak:automatic-detection="bitcoin-private-key";{}'.format(message)
p.populate_set_out(msg, 'Tags')
to_print = 'Bitcoin;{};{};{};'.format(paste.p_source, paste.p_date,
paste.p_name)
publisher.warning('{}Detected {} Bitcoin private key;{}'.format(

View File

@ -105,6 +105,9 @@ if __name__ == "__main__":
msg = 'credential;{}'.format(filepath)
p.populate_set_out(msg, 'alertHandler')
msg = 'infoleak:automatic-detection="credential";{}'.format(filepath)
p.populate_set_out(msg, 'Tags')
#Put in form, count occurences, then send to moduleStats
creds_sites = {}
site_occurence = re.findall(regex_site_for_stats, content)

View File

@ -85,6 +85,9 @@ if __name__ == "__main__":
#send to Browse_warning_paste
msg = 'creditcard;{}'.format(filename)
p.populate_set_out(msg, 'alertHandler')
msg = 'infoleak:automatic-detection="credit-card";{}'.format(filename)
p.populate_set_out(msg, 'Tags')
else:
publisher.info('{}CreditCard related;{}'.format(to_print, paste.p_path))
else:

View File

@ -34,6 +34,9 @@ def search_cve(message):
#send to Browse_warning_paste
msg = 'cve;{}'.format(filepath)
p.populate_set_out(msg, 'alertHandler')
msg = 'infoleak:automatic-detection="cve";{}'.format(filepath)
p.populate_set_out(msg, 'Tags')
#Send to duplicate
p.populate_set_out(filepath, 'Duplicate')

View File

@ -28,47 +28,76 @@ def search_key(paste):
if '-----BEGIN PGP MESSAGE-----' in content:
publisher.warning('{} has a PGP enc message'.format(paste.p_name))
msg = 'infoleak:automatic-detection="pgp-message";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if '-----BEGIN CERTIFICATE-----' in content:
publisher.warning('{} has a certificate message'.format(paste.p_name))
msg = 'infoleak:automatic-detection="certificate";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if '-----BEGIN RSA PRIVATE KEY-----' in content:
publisher.warning('{} has a RSA private key message'.format(paste.p_name))
print('rsa private key message found')
msg = 'infoleak:automatic-detection="rsa-private-key";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if '-----BEGIN PRIVATE KEY-----' in content:
publisher.warning('{} has a private key message'.format(paste.p_name))
print('private key message found')
msg = 'infoleak:automatic-detection="private-key";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if '-----BEGIN ENCRYPTED PRIVATE KEY-----' in content:
publisher.warning('{} has an encrypted private key message'.format(paste.p_name))
print('encrypted private key message found')
msg = 'infoleak:automatic-detection="encrypted-private-key";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if '-----BEGIN OPENSSH PRIVATE KEY-----' in content:
publisher.warning('{} has an openssh private key message'.format(paste.p_name))
print('openssh private key message found')
msg = 'infoleak:automatic-detection="private-ssh-key";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if '-----BEGIN OpenVPN Static key V1-----' in content:
publisher.warning('{} has an openssh private key message'.format(paste.p_name))
print('OpenVPN Static key message found')
msg = 'infoleak:automatic-detection="vpn-static-key";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if '-----BEGIN DSA PRIVATE KEY-----' in content:
publisher.warning('{} has a dsa private key message'.format(paste.p_name))
msg = 'infoleak:automatic-detection="dsa-private-key";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if '-----BEGIN EC PRIVATE KEY-----' in content:
publisher.warning('{} has an ec private key message'.format(paste.p_name))
msg = 'infoleak:automatic-detection="ec-private-key";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if '-----BEGIN PGP PRIVATE KEY BLOCK-----' in content:
publisher.warning('{} has a pgp private key block message'.format(paste.p_name))
msg = 'infoleak:automatic-detection="pgp-private-key";{}'.format(message)
p.populate_set_out(msg, 'Tags')
find = True
if find :

View File

@ -160,6 +160,8 @@ function launching_scripts {
sleep 0.1
screen -S "Script_AIL" -X screen -t "alertHandler" bash -c './alertHandler.py; read x'
sleep 0.1
screen -S "Script_AIL" -X screen -t "Tags" bash -c './Tags.py; read x'
sleep 0.1
screen -S "Script_AIL" -X screen -t "SentimentAnalysis" bash -c './SentimentAnalysis.py; read x'
}
@ -228,7 +230,7 @@ islogged=`screen -ls | egrep '[0-9]+.Logging_AIL' | cut -d. -f1`
isqueued=`screen -ls | egrep '[0-9]+.Queue_AIL' | cut -d. -f1`
isscripted=`screen -ls | egrep '[0-9]+.Script_AIL' | cut -d. -f1`
options=("Redis" "Ardb" "Logs" "Queues" "Scripts" "Killall" "Shutdown" "Update-config")
options=("Redis" "Ardb" "Logs" "Queues" "Scripts" "Killall" "Shutdown" "Update-config" "Update-thirdparty")
menu() {
echo "What do you want to Launch?:"
@ -328,6 +330,17 @@ for i in ${!options[@]}; do
echo -e $GREEN"\t* Configuration up-to-date"$DEFAULT
fi
;;
Update-thirdparty)
echo -e "\t* Updating thirdparty..."
bash -c "(cd ../var/www && ./update_thirdparty.sh)"
exitStatus=$?
if [ $exitStatus -ge 1 ]; then
echo -e $RED"\t* Configuration not up-to-date"$DEFAULT
exit
else
echo -e $GREEN"\t* Configuration up-to-date"$DEFAULT
fi
;;
esac
fi
done

View File

@ -76,6 +76,9 @@ if __name__ == "__main__":
p.populate_set_out(filename, 'Duplicate')
p.populate_set_out('mail;{}'.format(filename), 'alertHandler')
msg = 'infoleak:automatic-detection="mail";{}'.format(filename)
p.populate_set_out(msg, 'Tags')
else:
publisher.info(to_print)
#Send to ModuleStats

View File

@ -152,6 +152,9 @@ if __name__ == "__main__":
for url in fetch(p, r_cache, urls, domains_list, path):
publisher.info('{}Checked {};{}'.format(to_print, url, PST.p_path))
p.populate_set_out('onion;{}'.format(PST.p_path), 'alertHandler')
msg = 'infoleak:automatic-detection="onion";{}'.format(PST.p_path)
p.populate_set_out(msg, 'Tags')
else:
publisher.info('{}Onion related;{}'.format(to_print, PST.p_path))

View File

@ -36,6 +36,10 @@ def search_phone(message):
msg = 'phone;{}'.format(message)
p.populate_set_out(msg, 'alertHandler')
#Send to duplicate
msg = 'infoleak:automatic-detection="phone-number";{}'.format(message)
p.populate_set_out(msg, 'Tags')
p.populate_set_out(message, 'Duplicate')
stats = {}
for phone_number in results:

View File

@ -82,6 +82,9 @@ def analyse(url, path):
p.populate_set_out(path, 'Duplicate')
#send to Browse_warning_paste
p.populate_set_out('sqlinjection;{}'.format(path), 'alertHandler')
msg = 'infoleak:automatic-detection="sql-injection";{}'.format(path)
p.populate_set_out(msg, 'Tags')
else:
print("Potential SQL injection:")
print(urllib.request.unquote(url))

68
bin/Tags.py Executable file
View File

@ -0,0 +1,68 @@
#!/usr/bin/env python3
# -*-coding:UTF-8 -*
"""
The Tags Module
================================
This module create tags.
"""
import redis
import time
from pubsublogger import publisher
from Helper import Process
from packages import Paste
if __name__ == '__main__':
# Port of the redis instance used by pubsublogger
publisher.port = 6380
# Script is the default channel used for the modules.
publisher.channel = 'Script'
# Section name in bin/packages/modules.cfg
config_section = 'Tags'
# Setup the I/O queues
p = Process(config_section)
server = redis.StrictRedis(
host=p.config.get("ARDB_Tags", "host"),
port=p.config.get("ARDB_Tags", "port"),
db=p.config.get("ARDB_Tags", "db"),
decode_responses=True)
server_metadata = redis.StrictRedis(
host=p.config.get("ARDB_Metadata", "host"),
port=p.config.get("ARDB_Metadata", "port"),
db=p.config.get("ARDB_Metadata", "db"),
decode_responses=True)
# Sent to the logging a description of the module
publisher.info("Tags module started")
# Endless loop getting messages from the input queue
while True:
# Get one message from the input queue
message = p.get_from_set()
if message is None:
publisher.debug("{} queue is empty, waiting 10s".format(config_section))
time.sleep(10)
continue
else:
tag, path = message.split(';')
# add the tag to the tags word_list
res = server.sadd('list_tags', tag)
if res == 1:
print("new tags added : {}".format(tag))
# add the path to the tag set
res = server.sadd(tag, path)
if res == 1:
print("new paste: {}".format(path))
print(" tagged: {}".format(tag))
server_metadata.sadd('tag:'+path, tag)

View File

@ -340,7 +340,7 @@ class Paste(object):
Save a new duplicate on others pastes
"""
for hash_type, path, percent, date in list_value:
to_add = [hash_type, self.p_path, percent, date]
to_add = (hash_type, self.p_path, percent, date)
self.store_duplicate.sadd('dup:'+path,to_add)
def _get_from_redis(self, r_serv):

View File

@ -49,15 +49,15 @@ publish = Redis_CreditCards,Redis_Mail,Redis_Onion,Redis_Web,Redis_Credential,Re
[CreditCards]
subscribe = Redis_CreditCards
publish = Redis_Duplicate,Redis_ModuleStats,Redis_alertHandler
publish = Redis_Duplicate,Redis_ModuleStats,Redis_alertHandler,Redis_Tags
[Mail]
subscribe = Redis_Mail
publish = Redis_Duplicate,Redis_ModuleStats,Redis_alertHandler
publish = Redis_Duplicate,Redis_ModuleStats,Redis_alertHandler,Redis_Tags
[Onion]
subscribe = Redis_Onion
publish = Redis_ValidOnion,ZMQ_FetchedOnion,Redis_alertHandler
publish = Redis_ValidOnion,ZMQ_FetchedOnion,Redis_alertHandler,Redis_Tags
#publish = Redis_Global,Redis_ValidOnion,ZMQ_FetchedOnion,Redis_alertHandler
[DumpValidOnion]
@ -72,7 +72,7 @@ subscribe = Redis_Url
[SQLInjectionDetection]
subscribe = Redis_Url
publish = Redis_alertHandler,Redis_Duplicate
publish = Redis_alertHandler,Redis_Duplicate,Redis_Tags
[ModuleStats]
subscribe = Redis_ModuleStats
@ -80,9 +80,12 @@ subscribe = Redis_ModuleStats
[alertHandler]
subscribe = Redis_alertHandler
[Tags]
subscribe = Redis_Tags
#[send_to_queue]
#subscribe = Redis_Cve
#publish = Redis_alertHandler
#publish = Redis_alertHandler,Redis_Tags
[SentimentAnalysis]
subscribe = Redis_Global
@ -92,28 +95,28 @@ subscribe = Redis_Global
[Credential]
subscribe = Redis_Credential
publish = Redis_Duplicate,Redis_ModuleStats,Redis_alertHandler
publish = Redis_Duplicate,Redis_ModuleStats,Redis_alertHandler,Redis_Tags
[Cve]
subscribe = Redis_Cve
publish = Redis_alertHandler,Redis_Duplicate
publish = Redis_alertHandler,Redis_Duplicate,Redis_Tags
[Phone]
subscribe = Redis_Global
publish = Redis_Duplicate,Redis_alertHandler
publish = Redis_Duplicate,Redis_alertHandler,Redis_Tags
[Keys]
subscribe = Redis_Global
publish = Redis_Duplicate,Redis_alertHandler
publish = Redis_Duplicate,Redis_alertHandler,Redis_Tags
[ApiKey]
subscribe = Redis_ApiKey
publish = Redis_Duplicate,Redis_alertHandler
publish = Redis_Duplicate,Redis_alertHandler,Redis_Tags
[Base64]
subscribe = Redis_Global
publish = Redis_Duplicate,Redis_alertHandler
publish = Redis_Duplicate,Redis_alertHandler,Redis_Tags
[Bitcoin]
subscribe = Redis_Global
publish = Redis_Duplicate,Redis_alertHandler
publish = Redis_Duplicate,Redis_alertHandler,Redis_Tags

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
doc/screenshots/tags.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
doc/screenshots/tags2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -26,10 +26,11 @@ sudo apt-get install libev-dev libgmp-dev -y
#Need for generate-data-flow graph
sudo apt-get install graphviz -y
#needed for mathplotlib
sudo easy_install -U distribute
# install nosetests
sudo pip install nose -y
# ssdeep
sudo apt-get install libfuzzy-dev
sudo apt-get install libfuzzy-dev -y
sudo apt-get install build-essential libffi-dev automake autoconf libtool -y
# REDIS #
@ -70,10 +71,6 @@ if [ ! -f bin/packages/config.cfg ]; then
cp bin/packages/config.cfg.sample bin/packages/config.cfg
fi
pushd var/www/
sudo ./update_thirdparty.sh
popd
if [ -z "$VIRTUAL_ENV" ]; then
virtualenv -p python3 AILENV
@ -88,6 +85,10 @@ if [ -z "$VIRTUAL_ENV" ]; then
fi
pushd var/www/
./update_thirdparty.sh
popd
year1=20`date +%y`
year2=20`date --date='-1 year' +%y`
mkdir -p $AIL_HOME/{PASTES,Blooms,dumps}
@ -102,8 +103,6 @@ popd
# Py tlsh
pushd tlsh/py_ext
#python setup.py build
#python setup.py install
python3 setup.py build
python3 setup.py install
@ -112,8 +111,5 @@ HOME=$(pwd) python3 -m textblob.download_corpora
python3 -m nltk.downloader vader_lexicon
python3 -m nltk.downloader punkt
# install nosetests
sudo pip install nose
#Create the file all_module and update the graph in doc
$AIL_HOME/doc/generate_modules_data_flow_graph.sh

View File

@ -18,6 +18,8 @@ sys.path.append('./modules/')
import Paste
from Date import Date
from pytaxonomies import Taxonomies
# Import config
import Flask_config
@ -113,6 +115,25 @@ def searchbox():
return render_template("searchbox.html")
# ========== INITIAL taxonomies ============
r_serv_tags = redis.StrictRedis(
host=cfg.get("ARDB_Tags", "host"),
port=cfg.getint("ARDB_Tags", "port"),
db=cfg.getint("ARDB_Tags", "db"),
decode_responses=True)
# add default ail taxonomies
r_serv_tags.sadd('active_taxonomies', 'infoleak')
r_serv_tags.sadd('active_taxonomies', 'gdpr')
r_serv_tags.sadd('active_taxonomies', 'fpf')
# add default tags
taxonomies = Taxonomies()
for tag in taxonomies.get('infoleak').machinetags():
r_serv_tags.sadd('active_tag_infoleak', tag)
for tag in taxonomies.get('gdpr').machinetags():
r_serv_tags.sadd('active_tag_infoleak', tag)
for tag in taxonomies.get('fpf').machinetags():
r_serv_tags.sadd('active_tag_infoleak', tag)
# ============ MAIN ============
if __name__ == "__main__":

View File

@ -82,3 +82,5 @@ max_preview_char = int(cfg.get("Flask", "max_preview_char")) # Maximum number of
max_preview_modal = int(cfg.get("Flask", "max_preview_modal")) # Maximum number of character to display in the modal
DiffMaxLineLength = int(cfg.get("Flask", "DiffMaxLineLength"))#Use to display the estimated percentage instead of a raw value
bootstrap_label = ['primary', 'success', 'danger', 'warning', 'info']

View File

@ -0,0 +1,845 @@
#!/usr/bin/env python3
# -*-coding:UTF-8 -*
'''
Flask functions and routes for the trending modules page
'''
import redis
from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for
import json
from datetime import datetime
import Paste
from pytaxonomies import Taxonomies
from pymispgalaxies import Galaxies, Clusters
# ============ VARIABLES ============
import Flask_config
app = Flask_config.app
cfg = Flask_config.cfg
r_serv_tags = Flask_config.r_serv_tags
r_serv_metadata = Flask_config.r_serv_metadata
max_preview_char = Flask_config.max_preview_char
max_preview_modal = Flask_config.max_preview_modal
bootstrap_label = Flask_config.bootstrap_label
Tags = Blueprint('Tags', __name__, template_folder='templates')
galaxies = Galaxies()
clusters = Clusters(skip_duplicates=True)
list_all_tags = {}
for name, c in clusters.items(): #galaxy name + tags
list_all_tags[name] = c
list_galaxies = []
for g in galaxies.values():
list_galaxies.append(g.to_json())
list_clusters = []
for c in clusters.values():
list_clusters.append(c.to_json())
# tags numbers in galaxies
total_tags = {}
for name, tags in clusters.items(): #galaxie name + tags
total_tags[name] = len(tags)
# ============ FUNCTIONS ============
def one():
return 1
def get_tags_with_synonyms(tag):
str_synonyms = ' - synonyms: '
synonyms = r_serv_tags.smembers('synonym_tag_' + tag)
# synonyms to display
for synonym in synonyms:
str_synonyms = str_synonyms + synonym + ', '
# add real tag
if str_synonyms != ' - synonyms: ':
return {'name':tag + str_synonyms,'id':tag}
else:
return {'name':tag,'id':tag}
# ============= ROUTES ==============
@Tags.route("/Tags/", methods=['GET'])
def Tags_page():
return render_template("Tags.html")
@Tags.route("/Tags/get_all_tags")
def get_all_tags():
all_tags = r_serv_tags.smembers('list_tags')
list_tags = []
for tag in all_tags:
t = tag.split(':')[0]
# add synonym
str_synonyms = ' - synonyms: '
if t == 'misp-galaxy':
synonyms = r_serv_tags.smembers('synonym_tag_' + tag)
for synonym in synonyms:
str_synonyms = str_synonyms + synonym + ', '
# add real tag
if str_synonyms != ' - synonyms: ':
list_tags.append({'name':tag + str_synonyms,'id':tag})
else:
list_tags.append({'name':tag,'id':tag})
return jsonify(list_tags)
@Tags.route("/Tags/get_all_tags_taxonomies")
def get_all_tags_taxonomies():
taxonomies = Taxonomies()
list_taxonomies = list(taxonomies.keys())
active_taxonomie = r_serv_tags.smembers('active_taxonomies')
list_tags = []
for taxonomie in active_taxonomie:
#l_tags = taxonomies.get(taxonomie).machinetags()
l_tags = r_serv_tags.smembers('active_tag_' + taxonomie)
for tag in l_tags:
list_tags.append( tag )
return jsonify(list_tags)
@Tags.route("/Tags/get_all_tags_galaxies")
def get_all_tags_galaxy():
active_galaxies = r_serv_tags.smembers('active_galaxies')
list_tags = []
for galaxy in active_galaxies:
l_tags = r_serv_tags.smembers('active_tag_galaxies_' + galaxy)
for tag in l_tags:
list_tags.append(get_tags_with_synonyms(tag))
return jsonify(list_tags)
@Tags.route("/Tags/get_tags_taxonomie")
def get_tags_taxonomie():
taxonomie = request.args.get('taxonomie')
taxonomies = Taxonomies()
list_taxonomies = list(taxonomies.keys())
active_taxonomie = r_serv_tags.smembers('active_taxonomies')
#verify input
if taxonomie in list_taxonomies:
if taxonomie in active_taxonomie:
list_tags = []
l_tags = r_serv_tags.smembers('active_tag_' + taxonomie)
for tag in l_tags:
list_tags.append( tag )
return jsonify(list_tags)
else:
return 'this taxonomie is disable'
else:
return 'INCORRECT INPUT'
@Tags.route("/Tags/get_tags_galaxy")
def get_tags_galaxy():
galaxy = request.args.get('galaxy')
active_galaxies = r_serv_tags.smembers('active_galaxies')
#verify input
if galaxy in active_galaxies:
list_tags = []
l_tags = r_serv_tags.smembers('active_tag_galaxies_' + galaxy)
for tag in l_tags:
list_tags.append(get_tags_with_synonyms(tag))
return jsonify(list_tags)
else:
return 'this galaxy is disable'
@Tags.route("/Tags/get_tagged_paste")
def get_tagged_paste():
tags = request.args.get('ltags')
list_tags = tags.split(',')
list_tag = []
for tag in list_tags:
list_tag.append(tag.replace('"','\"'))
# TODO verify input
if(type(list_tags) is list):
# no tag
if list_tags is False:
print('empty')
# 1 tag
elif len(list_tags) < 2:
tagged_pastes = r_serv_tags.smembers(list_tags[0])
# 2 tags or more
else:
tagged_pastes = r_serv_tags.sinter(list_tags[0], *list_tags[1:])
else :
return 'INCORRECT INPUT'
#TODO FIXME
currentSelectYear = int(datetime.now().year)
all_content = []
paste_date = []
paste_linenum = []
all_path = []
allPastes = list(tagged_pastes)
paste_tags = []
for path in allPastes[0:50]: ######################moduleName
all_path.append(path)
paste = Paste.Paste(path)
content = paste.get_p_content()
content_range = max_preview_char if len(content)>max_preview_char else len(content)-1
all_content.append(content[0:content_range].replace("\"", "\'").replace("\r", " ").replace("\n", " "))
curr_date = str(paste._get_p_date())
curr_date = curr_date[0:4]+'/'+curr_date[4:6]+'/'+curr_date[6:]
paste_date.append(curr_date)
paste_linenum.append(paste.get_lines_info()[0])
p_tags = r_serv_metadata.smembers('tag:'+path)
complete_tags = []
l_tags = []
for tag in p_tags:
complete_tag = tag
tag = tag.split('=')
if len(tag) > 1:
if tag[1] != '':
tag = tag[1][1:-1]
# no value
else:
tag = tag[0][1:-1]
# use for custom tags
else:
tag = tag[0]
l_tags.append( (tag,complete_tag) )
paste_tags.append(l_tags)
if len(allPastes) > 10:
finished = False
else:
finished = True
return render_template("tagged.html",
year=currentSelectYear,
all_path=all_path,
tags=tags,
list_tag = list_tag,
paste_tags=paste_tags,
bootstrap_label=bootstrap_label,
content=all_content,
paste_date=paste_date,
paste_linenum=paste_linenum,
char_to_display=max_preview_modal,
finished=finished)
@Tags.route("/Tags/remove_tag")
def remove_tag():
#TODO verify input
path = request.args.get('paste')
tag = request.args.get('tag')
#remove tag
r_serv_metadata.srem('tag:'+path, tag)
r_serv_tags.srem(tag, path)
if r_serv_tags.scard(tag) == 0:
r_serv_tags.srem('list_tags', tag)
return redirect(url_for('showsavedpastes.showsavedpaste', paste=path))
@Tags.route("/Tags/confirm_tag")
def confirm_tag():
#TODO verify input
path = request.args.get('paste')
tag = request.args.get('tag')
if(tag[9:28] == 'automatic-detection'):
#remove automatic tag
r_serv_metadata.srem('tag:'+path, tag)
r_serv_tags.srem(tag, path)
tag = tag.replace('automatic-detection','analyst-detection', 1)
#add analyst tag
r_serv_metadata.sadd('tag:'+path, tag)
r_serv_tags.sadd(tag, path)
#add new tag in list of all used tags
r_serv_tags.sadd('list_tags', tag)
return redirect(url_for('showsavedpastes.showsavedpaste', paste=path))
return 'incompatible tag'
@Tags.route("/Tags/addTags")
def addTags():
tags = request.args.get('tags')
tagsgalaxies = request.args.get('tagsgalaxies')
path = request.args.get('path')
list_tag = tags.split(',')
list_tag_galaxies = tagsgalaxies.split(',')
taxonomies = Taxonomies()
active_taxonomies = r_serv_tags.smembers('active_taxonomies')
active_galaxies = r_serv_tags.smembers('active_galaxies')
if not path:
return 'INCORRECT INPUT0'
if list_tag != ['']:
for tag in list_tag:
# verify input
tax = tag.split(':')[0]
if tax in active_taxonomies:
if tag in r_serv_tags.smembers('active_tag_' + tax):
#add tag
r_serv_metadata.sadd('tag:'+path, tag)
r_serv_tags.sadd(tag, path)
#add new tag in list of all used tags
r_serv_tags.sadd('list_tags', tag)
else:
return 'INCORRECT INPUT1'
else:
return 'INCORRECT INPUT2'
if list_tag_galaxies != ['']:
for tag in list_tag_galaxies:
# verify input
gal = tag.split(':')[1]
gal = gal.split('=')[0]
if gal in active_galaxies:
if tag in r_serv_tags.smembers('active_tag_galaxies_' + gal):
#add tag
r_serv_metadata.sadd('tag:'+path, tag)
r_serv_tags.sadd(tag, path)
#add new tag in list of all used tags
r_serv_tags.sadd('list_tags', tag)
else:
return 'INCORRECT INPUT3'
else:
return 'INCORRECT INPUT4'
return redirect(url_for('showsavedpastes.showsavedpaste', paste=path))
@Tags.route("/Tags/taxonomies")
def taxonomies():
active_taxonomies = r_serv_tags.smembers('active_taxonomies')
taxonomies = Taxonomies()
list_taxonomies = list(taxonomies.keys())
id = []
name = []
description = []
version = []
enabled = []
n_tags = []
for taxonomie in list_taxonomies:
id.append(taxonomie)
name.append(taxonomies.get(taxonomie).name)
description.append(taxonomies.get(taxonomie).description)
version.append(taxonomies.get(taxonomie).version)
if taxonomie in active_taxonomies:
enabled.append(True)
else:
enabled.append(False)
n = str(r_serv_tags.scard('active_tag_' + taxonomie))
n_tags.append(n + '/' + str(len(taxonomies.get(taxonomie).machinetags())) )
return render_template("taxonomies.html",
id=id,
all_name = name,
description = description,
version = version,
enabled = enabled,
n_tags=n_tags)
@Tags.route("/Tags/edit_taxonomie")
def edit_taxonomie():
taxonomies = Taxonomies()
list_taxonomies = list(taxonomies.keys())
id = request.args.get('taxonomie')
#verify input
if id in list(taxonomies.keys()):
active_tag = r_serv_tags.smembers('active_tag_' + id)
list_tag = taxonomies.get(id).machinetags()
list_tag_desc = taxonomies.get(id).machinetags_expanded()
active_taxonomies = r_serv_tags.smembers('active_taxonomies')
if id in active_taxonomies:
active = True
else:
active = False
n = str(r_serv_tags.scard('active_tag_' + id))
badge = n + '/' + str(len(taxonomies.get(id).machinetags()))
name = taxonomies.get(id).name
description = taxonomies.get(id).description
version = taxonomies.get(id).version
status = []
for tag in list_tag:
if tag in active_tag:
status.append(True)
else:
status.append(False)
return render_template("edit_taxonomie.html",
id=id,
name=name,
badge = badge,
description = description,
version = version,
active=active,
all_tags = list_tag,
list_tag_desc=list_tag_desc,
status = status)
else:
return 'INVALID TAXONOMIE'
@Tags.route("/Tags/disable_taxonomie")
def disable_taxonomie():
taxonomies = Taxonomies()
list_taxonomies = list(taxonomies.keys())
id = request.args.get('taxonomie')
if id in list_taxonomies:
r_serv_tags.srem('active_taxonomies', id)
for tag in taxonomies.get(id).machinetags():
r_serv_tags.srem('active_tag_' + id, tag)
return redirect(url_for('Tags.taxonomies'))
else:
return "INCORRECT INPUT"
@Tags.route("/Tags/active_taxonomie")
def active_taxonomie():
taxonomies = Taxonomies()
list_taxonomies = list(taxonomies.keys())
id = request.args.get('taxonomie')
# verify input
if id in list_taxonomies:
r_serv_tags.sadd('active_taxonomies', id)
for tag in taxonomies.get(id).machinetags():
r_serv_tags.sadd('active_tag_' + id, tag)
return redirect(url_for('Tags.taxonomies'))
else:
return "INCORRECT INPUT"
@Tags.route("/Tags/edit_taxonomie_tag")
def edit_taxonomie_tag():
taxonomies = Taxonomies()
list_taxonomies = list(taxonomies.keys())
arg1 = request.args.getlist('tag_enabled')
arg2 = request.args.getlist('tag_disabled')
id = request.args.get('taxonomie')
#verify input
if id in list_taxonomies:
list_tag = taxonomies.get(id).machinetags()
#check tags validity
if ( all(elem in list_tag for elem in arg1) or (len(arg1) == 0) ) and ( all(elem in list_tag for elem in arg2) or (len(arg2) == 0) ):
active_tag = r_serv_tags.smembers('active_tag_' + id)
diff = list(set(arg1) ^ set(list_tag))
#remove tags
for tag in diff:
r_serv_tags.srem('active_tag_' + id, tag)
#all tags unchecked
if len(arg1) == 0 and len(arg2) == 0:
r_serv_tags.srem('active_taxonomies', id)
#add new tags
for tag in arg2:
r_serv_tags.sadd('active_taxonomies', id)
r_serv_tags.sadd('active_tag_' + id, tag)
return redirect(url_for('Tags.taxonomies'))
else:
return "INCORRECT INPUT"
else:
return "INCORRECT INPUT"
@Tags.route("/Tags/galaxies")
def galaxies():
active_galaxies = r_serv_tags.smembers('active_galaxies')
name = []
icon = []
version = []
all_type = []
namespace = []
description = []
enabled = []
n_tags = []
for galaxie_json in list_galaxies:
galaxie = json.loads(galaxie_json)
name.append(galaxie['name'])
icon.append(galaxie['icon'])
version.append(galaxie['version'])
type = galaxie['type']
all_type.append(type)
namespace.append(galaxie['namespace'])
description.append(galaxie['description'])
if type in active_galaxies:
enabled.append(True)
else:
enabled.append(False)
n = str(r_serv_tags.scard('active_tag_galaxies_' + type))
n_tags.append(n + '/' + str(total_tags[type]) )
return render_template("galaxies.html",
name=name,
icon = icon,
version = version,
description = description,
namespace = namespace,
all_type = all_type,
enabled = enabled,
n_tags=n_tags)
@Tags.route("/Tags/edit_galaxy")
def edit_galaxy():
id = request.args.get('galaxy')
for clusters_json in list_clusters:
#get clusters
cluster = json.loads(clusters_json)
if cluster['type'] == id:
type = id
active_tag = r_serv_tags.smembers('active_tag_galaxies_' + type)
n = str(r_serv_tags.scard('active_tag_galaxies_' + type))
badge = n + '/' + str(total_tags[type])
name = cluster['name']
description = cluster['description']
version = cluster['version']
source = cluster['source']
val = cluster['values']
tags = []
for data in val:
try:
meta = data['meta']
except KeyError:
meta = []
tag_name = data['value']
tag_name = 'misp-galaxy:{}="{}"'.format(type, tag_name)
try:
tag_description = data['description']
except KeyError:
tag_description = ''
tags.append( (tag_name, tag_description, meta) )
status = []
for tag in tags:
if tag[0] in active_tag:
status.append(True)
else:
status.append(False)
active_galaxies = r_serv_tags.smembers('active_galaxies')
if id in active_galaxies:
active = True
else:
active = False
return render_template("edit_galaxy.html",
id = type,
name = name,
badge = badge,
description = description,
version = version,
active = active,
tags = tags,
status = status)
return 'INVALID GALAXY'
@Tags.route("/Tags/active_galaxy")
def active_galaxy():
id = request.args.get('galaxy')
# verify input
try:
l_tags = list_all_tags[id]
except KeyError:
return "INCORRECT INPUT"
r_serv_tags.sadd('active_galaxies', id)
for tag in l_tags:
r_serv_tags.sadd('active_tag_galaxies_' + id, 'misp-galaxy:{}="{}"'.format(id, tag))
#save synonyms
for clusters_json in list_clusters:
#get clusters
cluster = json.loads(clusters_json)
if cluster['type'] == id:
val = cluster['values']
tags = []
for data in val:
try:
meta = data['meta']
synonyms = meta['synonyms']
tag_name = data['value']
tag_name = 'misp-galaxy:{}="{}"'.format(id, tag_name)
#save synonyms
for synonym in synonyms:
r_serv_tags.sadd('synonym_tag_' + tag_name, synonym)
except KeyError:
pass
break
return redirect(url_for('Tags.galaxies'))
@Tags.route("/Tags/disable_galaxy")
def disable_galaxy():
id = request.args.get('galaxy')
# verify input
try:
l_tags = list_all_tags[id]
except KeyError:
return "INCORRECT INPUT"
r_serv_tags.srem('active_galaxies', id)
for tag in l_tags:
tag_name = 'misp-galaxy:{}="{}"'.format(id, tag)
r_serv_tags.srem('active_tag_galaxies_' + id, tag_name)
r_serv_tags.delete('synonym_tag_' + tag_name)
return redirect(url_for('Tags.galaxies'))
@Tags.route("/Tags/edit_galaxy_tag")
def edit_galaxy_tag():
arg1 = request.args.getlist('tag_enabled')
arg2 = request.args.getlist('tag_disabled')
id = request.args.get('galaxy')
#verify input
try:
l_tags = list_all_tags[id]
except KeyError:
return "INCORRECT INPUT"
#get full tags
list_tag = []
for tag in l_tags:
list_tag.append('misp-galaxy:{}="{}"'.format(id, tag))
#check tags validity
if ( all(elem in list_tag for elem in arg1) or (len(arg1) == 0) ) and ( all(elem in list_tag for elem in arg2) or (len(arg2) == 0) ):
active_tag = r_serv_tags.smembers('active_tag_galaxies_' + id)
diff = list(set(arg1) ^ set(list_tag))
#remove tags
for tag in diff:
r_serv_tags.srem('active_tag_galaxies_' + id, tag)
r_serv_tags.delete('synonym_tag_' + tag)
#all tags unchecked
if len(arg1) == 0 and len(arg2) == 0:
r_serv_tags.srem('active_galaxies', id)
#add new tags
for tag in arg2:
r_serv_tags.sadd('active_galaxies', id)
r_serv_tags.sadd('active_tag_galaxies_' + id, tag)
#get tags synonyms
for clusters_json in list_clusters:
#get clusters
cluster = json.loads(clusters_json)
if cluster['type'] == id:
val = cluster['values']
tags = []
for data in val:
try:
meta = data['meta']
synonyms = meta['synonyms']
tag_name = data['value']
tag_name = 'misp-galaxy:{}="{}"'.format(id, tag_name)
if tag_name in arg2:
#save synonyms
for synonym in synonyms:
r_serv_tags.sadd('synonym_tag_' + tag_name, synonym)
except KeyError:
pass
break
return redirect(url_for('Tags.galaxies'))
else:
return "INCORRECT INPUT"
@Tags.route("/Tags/tag_galaxy_info")
def tag_galaxy_info():
galaxy = request.args.get('galaxy')
tag = request.args.get('tag')
full_tag = tag
title = tag.split(':')[1]
tag = tag.split('=')[1]
tag = tag[1:-1]
#get clusters
for clusters_json in list_clusters:
cluster = json.loads(clusters_json)
if cluster['type'] == galaxy:
val = cluster['values']
source = cluster['source']
for data in val:
if tag == data['value']:
try:
description = data['description']
except KeyError:
description = ''
if r_serv_tags.sismember('active_tag_galaxies_' + galaxy, full_tag):
active = True
else:
active = False
synonyms = []
metadata = []
list_metadata = []
try:
meta = data['meta']
for key in meta:
if key != 'synonyms':
if type(meta[key]) is list:
for item in meta[key]:
list_metadata.append(key + ' : ' + item)
else:
list_metadata.append(key + ' : ' + meta[key])
try:
synonyms = meta['synonyms']
bool_synonyms = True
except KeyError:
synonyms = []
bool_synonyms = False
except KeyError:
pass
if synonyms:
bool_synonyms = True
else:
bool_synonyms = False
if list_metadata:
metadata = True
else:
metadata = False
return render_template("tag_galaxy_info.html",
title = title,
description = description,
source = source,
active = active,
synonyms = synonyms,
bool_synonyms = bool_synonyms,
metadata = metadata,
list_metadata = list_metadata)
return 'INVALID INPUT'
# ========= REGISTRATION =========
app.register_blueprint(Tags)

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Analysis Information Leak framework Dashboard</title>
<!-- Core CSS -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='font-awesome/css/font-awesome.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/sb-admin-2.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/dygraph_gallery.css') }}" rel="stylesheet" type="text/css" />
<link href="{{ url_for('static', filename='css/tags.css') }}" rel="stylesheet" type="text/css" />
<!-- JS -->
<script type="text/javascript" src="{{ url_for('static', filename='js/dygraph-combined.js') }}"></script>
<script language="javascript" src="{{ url_for('static', filename='js/jquery.js')}}"></script>
<script src="{{ url_for('static', filename='js/jquery.flot.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.flot.pie.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.flot.time.js') }}"></script>
<script src="{{ url_for('static', filename='js/tags.js') }}"></script>
</head>
<body>
{% include 'navbar.html' %}
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header" data-page="page-tags" >Tags</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="form-group input-group" >
<input id="ltags" style="width:100%;" type="text" name="ltags" autocomplete="off">
<div class="input-group-btn">
<button type="button" class="btn btn-search btn-primary btn-tags" onclick="searchTags()"<button class="btn btn-primary" onclick="emptyTags()">
<span class="glyphicon glyphicon-search "></span>
<span class="label-icon">Search Tags</span>
</button>
</div>
</div>
<button class="btn btn-primary" onclick="emptyTags()" style="margin-bottom: 30px;">
<span class="glyphicon glyphicon-remove"></span>
<span class="label-icon">Clear Tags</span>
</button>
<div>
<br></br>
<a class="btn btn-tags" href="{{ url_for('Tags.taxonomies') }}" target="_blank">
<i class="fa fa-wrench fa-2x"></i>
<br></br>
<span class="label-icon">Edit Taxonomies List </span>
</a>
<a class="btn btn-tags" href="{{ url_for('Tags.galaxies') }}" target="_blank">
<i class="fa fa-rocket fa-2x"></i>
<br></br>
<span class="label-icon">Edit Galaxies List</span>
</a>
</div>
</div>
<!-- /#page-wrapper -->
<script>
var ltags
$(document).ready(function(){
activePage = "page-Tags"
$("#"+activePage).addClass("active");
$.getJSON('/Tags/get_all_tags',
function(data) {
ltags = $('#ltags').tagSuggest({
data: data,
sortOrder: 'name',
maxDropHeight: 200,
name: 'ltags'
});
});
});
</script>
<script>
function searchTags() {
var data = ltags.getValue();
window.location.replace("{{ url_for('Tags.get_tagged_paste') }}?ltags=" + data);
}
function emptyTags() {
console.log('b');
ltags.clear();
}
</script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
</body>
</html>

View File

@ -0,0 +1,174 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Analysis Information Leak framework Dashboard</title>
<!-- Core CSS -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='font-awesome/css/font-awesome.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/sb-admin-2.css') }}" rel="stylesheet">
<link href="/static//css/dataTables.bootstrap.css" rel="stylesheet" type="text/css" />
<!-- JS -->
<script type="text/javascript" src="{{ url_for('static', filename='js/dygraph-combined.js') }}"></script>
<script language="javascript" src="{{ url_for('static', filename='js/jquery.js')}}"></script>
<script src="/static//js/bootstrap.min.js"></script>
<script src="/static//js/jquery.dataTables.min.js"></script>
<script src="/static//js/dataTables.bootstrap.js"></script>
<style>
.tooltip-inner {
text-align: left;
height: 200%;
width: 200%;
max-width: 500px;
max-height: 500px;
font-size: 13px;
}
xmp {
white-space:pre-wrap;
word-wrap:break-word;
}
.test thead{
background: #d91f2d;
color: #fff;
}
</style>
</head>
<body>
{% include 'navbar.html' %}
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<a href="/Tags/galaxies" class="btn btn-light pull-left">
<i class="fa fa-arrow-left fa"></i> List Galaxies
</a>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="panel panel-primary">
<div class="panel-heading">{{ name }}
{% if active %}
<span class="label label-success pull-right"> Enabled</span>
<span class="pull-right">&nbsp;&nbsp;&nbsp;</span>
<span class="badge badge-light pull-right">{{ badge }}</span>
{% endif %}
{% if not active %}
<span class="label label-danger pull-right"> Disabled</span>
{% endif %}
</div>
<div class="panel-body">
{{ description }}
<br><br>
Version: {{ version }}
{% if active %}
<a href="{{ url_for('Tags.disable_galaxy') }}?galaxy={{ id }}" class="btn btn-danger pull-right">
<i class="fa fa-times fa"></i> Disable Galaxy
</a>
{% endif %}
{% if not active %}
<a href="{{ url_for('Tags.active_galaxy') }}?galaxy={{ id }}" class="btn btn-success pull-right">
<i class="fa fa-check-square-o fa"></i> Enable Galaxy
</a>
{% endif %}
</div>
</div>
<form action="/Tags/edit_galaxy_tag" id="checkboxForm">
<input type="hidden" value="{{ id }}" name="galaxy" />
<table class="test table table-striped table-bordered table-hover table-responsive " id="myTable_">
<thead>
<tr>
<th></th>
<th style="max-width: 800px;">Tag</th>
<th style="max-width: 800px;">Description</th>
<th>Enabled</th>
</tr>
</thead>
<tbody>
{% for tag in tags %}
<tr>
<td>
{% if status[loop.index0] %}
<div style="display:none;">Enabled</div>
<input type="checkbox" value="{{ tag[0] }}" id="{{ tag[0] }}" name="tag_enabled" checked>
{% endif %}
{% if not status[loop.index0] %}
<div style="display:none;">Disabled</div>
<input type="checkbox" value="{{ tag[0] }}" id="{{ tag[0] }}" name="tag_disabled" >
{% endif %}
</td>
<td>
<a href="{{ url_for('Tags.tag_galaxy_info') }}?galaxy={{ request.args.get('galaxy') }}&tag={{ tag[0] }}">{{ tag[0] }}</a>
</td>
<td>{{ tag[1] }}</td>
<td style="text-align: center;">
{% if status[loop.index0] %}
<div style="display:none;">Enabled</div>
<div style="color:Green; display:inline-block"><i class="fa fa-check-circle fa-2x"></i></div>
{% endif %}
{% if not status[loop.index0] %}
<div style="display:none;">Disabled</div>
<div style="color:Red; display:inline-block"><i class="fa fa-times-circle fa-2x"></i></div>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="input-group-btn">
<button class="btn btn-primary btn-lg" onclick="submitActiveTags()">
<i class="fa fa-check-square-o fa"></i>
Update Tags
</button>
</div>
</form>
</div>
<!-- /#page-wrapper -->
</body>
<script>
var table
$(document).ready(function(){
table = $('#myTable_').DataTable(
{
"aLengthMenu": [[5, 10, 15, 20, -1], [5, 10, 15, 20, "All"]],
"iDisplayLength": 10,
"order": [[ 3, "desc" ]]
}
);
});
</script>
<script>
function submitActiveTags(){
table.destroy()
table = $('#myTable_').DataTable(
{
"iDisplayLength": -1,
}
);
}
</script>
</html>

View File

@ -0,0 +1,172 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Analysis Information Leak framework Dashboard</title>
<!-- Core CSS -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='font-awesome/css/font-awesome.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/sb-admin-2.css') }}" rel="stylesheet">
<link href="/static//css/dataTables.bootstrap.css" rel="stylesheet" type="text/css" />
<!-- JS -->
<script type="text/javascript" src="{{ url_for('static', filename='js/dygraph-combined.js') }}"></script>
<script language="javascript" src="{{ url_for('static', filename='js/jquery.js')}}"></script>
<script src="/static//js/bootstrap.min.js"></script>
<script src="/static//js/jquery.dataTables.min.js"></script>
<script src="/static//js/dataTables.bootstrap.js"></script>
<style>
.tooltip-inner {
text-align: left;
height: 200%;
width: 200%;
max-width: 500px;
max-height: 500px;
font-size: 13px;
}
xmp {
white-space:pre-wrap;
word-wrap:break-word;
}
.test thead{
background: #d91f2d;
color: #fff;
}
</style>
</head>
<body>
{% include 'navbar.html' %}
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<a href="/Tags/taxonomies" class="btn btn-light pull-left">
<i class="fa fa-arrow-left fa"></i> List Taxonomies
</a>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="panel panel-primary">
<div class="panel-heading">{{ name }}
{% if active %}
<span class="label label-success pull-right"> Enabled</span>
<span class="pull-right">&nbsp;&nbsp;&nbsp;</span>
<span class="badge badge-light pull-right">{{ badge }}</span>
{% endif %}
{% if not active %}
<span class="label label-danger pull-right"> Disabled</span>
{% endif %}
</div>
<div class="panel-body">
{{ description }}
<br><br>
Version: {{ version }}
{% if active %}
<a href="{{ url_for('Tags.disable_taxonomie') }}?taxonomie={{ id }}" class="btn btn-danger pull-right">
<i class="fa fa-times fa"></i> Disable Taxonomie
</a>
{% endif %}
{% if not active %}
<a href="{{ url_for('Tags.active_taxonomie') }}?taxonomie={{ id }}" class="btn btn-success pull-right">
<i class="fa fa-check-square-o fa"></i> Enable Taxonomie
</a>
{% endif %}
</div>
</div>
<form action="/Tags/edit_taxonomie_tag" id="checkboxForm">
<input type="hidden" value="{{ id }}" name="taxonomie" />
<table class="test table table-striped table-bordered table-hover table-responsive " id="myTable_">
<thead>
<tr>
<th></th>
<th style="max-width: 800px;">Tag</th>
<th style="max-width: 800px;">Description</th>
<th>Enabled</th>
</tr>
</thead>
<tbody>
{% for tag in all_tags %}
<tr>
<td>
{% if status[loop.index0] %}
<div style="display:none;">Enabled</div>
<input type="checkbox" value="{{ tag }}" id="{{ tag }}" name="tag_enabled" checked>
{% endif %}
{% if not status[loop.index0] %}
<div style="display:none;">Disabled</div>
<input type="checkbox" value="{{ tag }}" id="{{ tag }}" name="tag_disabled" >
{% endif %}
</td>
<td>{{ tag }}</td>
<td>{{ list_tag_desc[loop.index0] }}</td>
<td style="text-align: center;">
{% if status[loop.index0] %}
<div style="display:none;">Enabled</div>
<div style="color:Green; display:inline-block"><i class="fa fa-check-circle fa-2x"></i></div>
{% endif %}
{% if not status[loop.index0] %}
<div style="display:none;">Disabled</div>
<div style="color:Red; display:inline-block"><i class="fa fa-times-circle fa-2x"></i></div>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="input-group-btn">
<button class="btn btn-primary btn-lg" onclick="submitActiveTags()">
<i class="fa fa-check-square-o fa"></i>
Update Tags
</button>
</div>
</form>
</div>
<!-- /#page-wrapper -->
</body>
<script>
var table
$(document).ready(function(){
table = $('#myTable_').DataTable(
{
"aLengthMenu": [[5, 10, 15, 20, -1], [5, 10, 15, 20, "All"]],
"iDisplayLength": 10,
"order": [[ 3, "desc" ]]
}
);
});
</script>
<script>
function submitActiveTags(){
table.destroy()
table = $('#myTable_').DataTable(
{
"iDisplayLength": -1,
}
);
}
</script>
</html>

View File

@ -0,0 +1,120 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Analysis Information Leak framework Dashboard</title>
<!-- Core CSS -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='font-awesome/css/font-awesome.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/sb-admin-2.css') }}" rel="stylesheet">
<link href="/static//css/dataTables.bootstrap.css" rel="stylesheet" type="text/css" />
<!-- JS -->
<script type="text/javascript" src="{{ url_for('static', filename='js/dygraph-combined.js') }}"></script>
<script language="javascript" src="{{ url_for('static', filename='js/jquery.js')}}"></script>
<script src="/static//js/bootstrap.min.js"></script>
<script src="/static//js/jquery.dataTables.min.js"></script>
<script src="/static//js/dataTables.bootstrap.js"></script>
<style>
.tooltip-inner {
text-align: left;
height: 200%;
width: 200%;
max-width: 500px;
max-height: 500px;
font-size: 13px;
}
xmp {
white-space:pre-wrap;
word-wrap:break-word;
}
.test thead{
background: #d91f2d;
color: #fff;
}
</style>
</head>
<body>
{% include 'navbar.html' %}
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Galaxies</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<table class="test table table-striped table-bordered table-hover table-responsive " id="myTable_">
<thead>
<tr>
<th>Name</th>
<th style="max-width: 800px;">Description</th>
<th>Namespace</th>
<th>Version</th>
<th>Enabled</th>
<th>Active Tags</th>
</tr>
</thead>
<tbody>
{% for type in all_type %}
<tr>
<td>
{{ name[loop.index0] }}
<div>
<i class="fa fa-{{ icon[loop.index0] }}"></i>
</div>
</td>
<td>{{ description[loop.index0] }}</td>
<td>{{ namespace[loop.index0] }}</td>
<td>{{ version[loop.index0] }}</td>
<td style="text-align: center;">
{% if enabled[loop.index0] %}
<div style="display:none;">Enabled</div>
<div style="color:Green; display:inline-block"><i class="fa fa-check-circle fa-2x"></i></div>
{% endif %}
{% if not enabled[loop.index0] %}
<div style="display:none;">Disabled</div>
<div style="color:Red; display:inline-block"><i class="fa fa-times-circle fa-2x"></i></div>
{% endif %}
</td>
<td style="text-align: center;">
<div style="display:none;">{{ n_tags[loop.index0] }}</div>
<a class="btn btn-primary" href="{{ url_for('Tags.edit_galaxy') }}?galaxy={{ type }}">Active Tags <span class="badge">{{ n_tags[loop.index0] }}</span></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /#page-wrapper -->
</body>
<script>
$(document).ready(function(){
//search_table = $('#myTable_').DataTable({ "order": [[ 2, "desc" ]] });
$('#myTable_').DataTable(
{
"aLengthMenu": [[5, 10, 15, 20, -1], [5, 10, 15, 20, "All"]],
"iDisplayLength": 15,
}
);
});
</script>
</html>

View File

@ -0,0 +1 @@
<li id='page-Tags'><a href="{{ url_for('Tags.Tags_page') }}"><i class="fa fa-tag "></i> Tags </a></li>

View File

@ -0,0 +1,113 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Analysis Information Leak framework Dashboard</title>
<!-- Core CSS -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='font-awesome/css/font-awesome.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/sb-admin-2.css') }}" rel="stylesheet">
<link href="/static//css/dataTables.bootstrap.css" rel="stylesheet" type="text/css" />
<!-- JS -->
<script type="text/javascript" src="{{ url_for('static', filename='js/dygraph-combined.js') }}"></script>
<script language="javascript" src="{{ url_for('static', filename='js/jquery.js')}}"></script>
<script src="/static//js/bootstrap.min.js"></script>
<script src="/static//js/jquery.dataTables.min.js"></script>
<script src="/static//js/dataTables.bootstrap.js"></script>
<style>
.tooltip-inner {
text-align: left;
height: 200%;
width: 200%;
max-width: 500px;
max-height: 500px;
font-size: 13px;
}
xmp {
white-space:pre-wrap;
word-wrap:break-word;
}
.test thead{
background: #d91f2d;
color: #fff;
}
</style>
</head>
<body>
{% include 'navbar.html' %}
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<a href="{{ url_for('Tags.edit_galaxy') }}?galaxy={{ request.args.get('galaxy') }}" class="btn btn-light pull-left">
<i class="fa fa-arrow-left fa"></i> {{ request.args.get('galaxy') }} Galaxy
</a>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="panel panel-primary">
<div class="panel-heading">{{ title }}
{% if active %}
<span class="label label-success pull-right"> Enabled</span>
{% endif %}
{% if not active %}
<span class="label label-danger pull-right"> Disabled</span>
{% endif %}
</div>
<div class="panel-body">
{{ description }}
<br><br>
Source: {{ source }}
{% if metadata %}
<div class="panel panel-info pull-right" style="width: 60%;">
<div class="panel-heading"> Metadata :
<ul class="list-group">
{% for meta in list_metadata %}
<li class="list-group-item">{{ meta }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{% if bool_synonyms %}
<br><br>
<ul class="list-group" style="width: 30%;">
<li class="list-group-item active">synonyms :</li>
{% for synonym in synonyms %}
<li class="list-group-item">{{ synonym }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
</div>
<!-- /#page-wrapper -->
</body>
<script>
$(document).ready(function(){
$('#myTable_').DataTable(
{
"aLengthMenu": [[5, 10, 15, 20, -1], [5, 10, 15, 20, "All"]],
"iDisplayLength": 15,
}
);
});
</script>
</html>

View File

@ -0,0 +1,307 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Analysis Information Leak framework Dashboard</title>
<!-- Core CSS -->
<link href="/static//css/bootstrap.min.css" rel="stylesheet">
<link href="/static//font-awesome/css/font-awesome.css" rel="stylesheet">
<link href="/static//css/sb-admin-2.css" rel="stylesheet">
<link href="/static//css/dataTables.bootstrap.css" rel="stylesheet" type="text/css" />
<link href="{{ url_for('static', filename='css/tags.css') }}" rel="stylesheet" type="text/css" />
<script language="javascript" src="/static//js/jquery.js"></script>
<script src="/static//js/bootstrap.min.js"></script>
<script src="/static//js/jquery.dataTables.min.js"></script>
<script src="/static//js/dataTables.bootstrap.js"></script>
<script src="{{ url_for('static', filename='js/tags.js') }}"></script>
<style>
.tooltip-inner {
text-align: left;
height: 200%;
width: 200%;
max-width: 500px;
max-height: 500px;
font-size: 13px;
}
xmp {
white-space:pre-wrap;
word-wrap:break-word;
}
.test thead{
background: #d91f2d;
color: #fff;
}
</style>
</head>
<body>
{% include 'navbar.html' %}
<!-- Modal -->
<div id="mymodal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<!-- Modal content-->
<div id="mymodalcontent" class="modal-content">
<div id="mymodalbody" class="modal-body" max-width="850px">
<p>Loading paste information...</p>
<img id="loading-gif-modal" src="{{url_for('static', filename='image/loading.gif') }}" height="26" width="26" style="margin: 4px;">
</div>
<div class="modal-footer">
<a id="button_show_path" target="_blank" href=""><button type="button" class="btn btn-info">Show saved paste</button></a>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header" data-page="page-tags" >Tags</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="form-group input-group" >
<input id="ltags" style="width:100%;" type="text" name="ltags" autocomplete="off">
<div class="input-group-btn">
<button type="button" class="btn btn-search btn-primary btn-tags" onclick="searchTags()">
<span class="glyphicon glyphicon-search "></span>
<span class="label-icon">Search Tags</span>
</button>
</div>
</div>
<button class="btn btn-primary" onclick="emptyTags()" style="margin-bottom: 30px;">
<span class="glyphicon glyphicon-remove"></span>
<span class="label-icon">Clear Tags</span>
</button>
<table class="test table table-striped table-bordered table-hover table-responsive " id="myTable_">
<thead>
<tr>
<th>#</th>
<th style="max-width: 800px;">Path</th>
<th>Date</th>
<th># of lines</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for path in all_path %}
<tr>
<td> {{ loop.index0 }}</td>
<td><a target="_blank" href="{{ url_for('showsavedpastes.showsavedpaste') }}?paste={{path}}">{{ path }}</a>
<div>
{% for tag in paste_tags[loop.index0] %}
<a href="{{ url_for('Tags.get_tagged_paste') }}?ltags={{ tag[1] }}">
<span class="label label-{{ bootstrap_label[loop.index0 % 5] }} pull-left">{{ tag[0] }}</span>
</a>
{% endfor %}
</div>
</td>
<td>{{ paste_date[loop.index0] }}</td>
<td>{{ paste_linenum[loop.index0] }}</td>
<td><p><span class="glyphicon glyphicon-info-sign" data-toggle="tooltip" data-placement="left" title="{{ content[loop.index0] }} "></span> <button type="button" class="btn-link" data-num="{{ loop.index0 + 1 }}" data-toggle="modal" data-target="#mymodal" data-url="{{ url_for('showsavedpastes.showsavedpaste') }}?paste={{ path }}&num={{ loop.index0+1 }}" data-path="{{ path }}"><span class="fa fa-search-plus"></span></button></p></td>
</tr>
{% endfor %}
</tbody>
</table>
</br>
<div id="nbr_entry" class="alert alert-info">
</div>
<div id="div_stil_data">
<button id="load_more_json_button1" type="button" class="btn btn-default" onclick="add_entries(100)" style="display: True">Load 100 entries</button>
<button id="load_more_json_button2" type="button" class="btn btn-warning" onclick="add_entries(300)" style="display: True">Load 300 entries</button>
<img id="loading_gif_browse" src="/static//image/loading.gif" heigt="20" width="20" style="margin: 2px;"></div>
</br>
<div>
<br></br>
<a class="btn btn-tags" href="{{ url_for('Tags.taxonomies') }}" target="_blank">
<i class="fa fa-wrench fa-2x"></i>
<br></br>
<span class="label-icon">Edit Taxonomies List </span>
</a>
<a class="btn btn-tags" href="{{ url_for('Tags.galaxies') }}" target="_blank">
<i class="fa fa-rocket fa-2x"></i>
<br></br>
<span class="label-icon">Edit Galaxies List</span>
</a>
</div>
</div>
</body>
<script>
var search_table;
var ltags;
var last_clicked_paste;
var can_change_modal_content = true;
$("#myTable_").attr('data-numElem', "{{ all_path|length }}");
$(document).ready(function(){
search_table = $('#myTable_').DataTable({ "order": [[ 2, "desc" ]] });
$('[data-toggle="tooltip"]').tooltip();
$("[data-toggle='modal']").off('click.openmodal').on("click.openmodal", function (event) {
get_html_and_update_modal(event, $(this));
});
$("#load_more_json_button1").hide();
$("#load_more_json_button2").hide();
$("#nbr_entry").hide();
$("#loading_gif_browse").hide();
$.getJSON('/Tags/get_all_tags',
function(data) {
activePage = "page-Tags"
$("#"+activePage).addClass("active");
var valueData = [
{% for tag in list_tag %}
'{{tag|safe}}',
{% endfor %}
];
ltags = $('#ltags').tagSuggest({
data: data,
value: valueData,
sortOrder: 'name',
maxDropHeight: 200,
name: 'ltags',
});
});
});
</script>
<script>
function searchTags() {
var data = ltags.getValue();
window.location.replace("{{ url_for('Tags.get_tagged_paste') }}?ltags=" + data);
}
function emptyTags() {
ltags.clear();
}
</script>
<!-- Dynamically update the modal -->
<script>
// static data
var alert_message = '<div class="alert alert-info alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><strong>No more data.</strong> Full paste displayed.</div>';
var complete_paste = null;
var char_to_display = {{ char_to_display }};
var start_index = 0;
// When the modal goes out, refresh it to normal content
$("#mymodal").on('hidden.bs.modal', function () {
can_change_modal_content = true;
$("#mymodalbody").html("<p>Loading paste information...</p>");
var loading_gif = "<img id='loading-gif-modal' class='img-center' src=\"{{url_for('static', filename='image/loading.gif') }}\" height='26' width='26' style='margin: 4px;'>";
$("#mymodalbody").append(loading_gif); // Show the loading GIF
$("#button_show_path").attr('href', '');
$("#button_show_path").hide();
complete_paste = null;
start_index = 0;
});
// Update the paste preview in the modal
function update_preview() {
if (start_index + char_to_display > complete_paste.length-1){ // end of paste reached
var final_index = complete_paste.length-1;
var flag_stop = true;
} else {
var final_index = start_index + char_to_display;
}
if (final_index != start_index){ // still have data to display
// Append the new content using text() and not append (XSS)
$("#mymodalbody").find("#paste-holder").text($("#mymodalbody").find("#paste-holder").text()+complete_paste.substring(start_index+1, final_index+1));
start_index = final_index;
if (flag_stop)
nothing_to_display();
} else {
nothing_to_display();
}
}
// Update the modal when there is no more data
function nothing_to_display() {
var new_content = $(alert_message).hide();
$("#mymodalbody").find("#panel-body").append(new_content);
new_content.show('fast');
$("#load-more-button").hide();
}
function get_html_and_update_modal(event, truemodal) {
event.preventDefault();
var modal=truemodal;
var url = " {{ url_for('showsavedpastes.showpreviewpaste') }}?paste=" + modal.attr('data-path') + "&num=" + modal.attr('data-num');
last_clicked_paste = modal.attr('data-num');
$.get(url, function (data) {
// verify that the reveived data is really the current clicked paste. Otherwise, ignore it.
var received_num = parseInt(data.split("|num|")[1]);
if (received_num == last_clicked_paste && can_change_modal_content) {
can_change_modal_content = false;
// clear data by removing html, body, head tags. prevent dark modal background stack bug.
var cleared_data = data.split("<body>")[1].split("</body>")[0];
$("#mymodalbody").html(cleared_data);
var button = $('<button type="button" id="load-more-button" class="btn btn-info btn-xs center-block" data-url="' + $(modal).attr('data-path') +'" data-toggle="tooltip" data-placement="bottom" title="Load more content"><span class="glyphicon glyphicon-download"></span></button>');
button.tooltip();
$("#mymodalbody").children(".panel-default").append(button);
$("#button_show_path").attr('href', $(modal).attr('data-url'));
$("#button_show_path").show('fast');
$("#loading-gif-modal").css("visibility", "hidden"); // Hide the loading GIF
if ($("[data-initsize]").attr('data-initsize') < char_to_display) { // All the content is displayed
nothing_to_display();
}
// On click, donwload all paste's content
$("#load-more-button").on("click", function (event) {
if (complete_paste == null) { //Donwload only once
$.get("{{ url_for('showsavedpastes.getmoredata') }}"+"?paste="+$(modal).attr('data-path'), function(data, status){
complete_paste = data;
update_preview();
});
} else {
update_preview();
}
});
} else if (can_change_modal_content) {
$("#mymodalbody").html("Ignoring previous not finished query of paste #" + received_num);
}
});
}
// Use to bind the button with the new displayed data
// (The bind do not happens if the dataTable is in tabs and the clicked data is in another page)
search_table.on( 'draw.dt', function () {
// Bind tooltip each time we draw a new page
$('[data-toggle="tooltip"]').tooltip();
// On click, get html content from url and update the corresponding modal
$("[data-toggle='modal']").off('click.openmodal').on("click.openmodal", function (event) {
get_html_and_update_modal(event, $(this));
});
} );
</script>

View File

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Analysis Information Leak framework Dashboard</title>
<!-- Core CSS -->
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='font-awesome/css/font-awesome.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/sb-admin-2.css') }}" rel="stylesheet">
<link href="/static//css/dataTables.bootstrap.css" rel="stylesheet" type="text/css" />
<!-- JS -->
<script type="text/javascript" src="{{ url_for('static', filename='js/dygraph-combined.js') }}"></script>
<script language="javascript" src="{{ url_for('static', filename='js/jquery.js')}}"></script>
<script src="/static//js/bootstrap.min.js"></script>
<script src="/static//js/jquery.dataTables.min.js"></script>
<script src="/static//js/dataTables.bootstrap.js"></script>
<style>
.tooltip-inner {
text-align: left;
height: 200%;
width: 200%;
max-width: 500px;
max-height: 500px;
font-size: 13px;
}
xmp {
white-space:pre-wrap;
word-wrap:break-word;
}
.test thead{
background: #d91f2d;
color: #fff;
}
</style>
</head>
<body>
{% include 'navbar.html' %}
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Taxonomies</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<table class="test table table-striped table-bordered table-hover table-responsive " id="myTable_">
<thead>
<tr>
<th>Name</th>
<th style="max-width: 800px;">Description</th>
<th>Version</th>
<th>Enabled</th>
<th>Active Tags</th>
</tr>
</thead>
<tbody>
{% for name in all_name %}
<tr>
<td>{{ name }}</td>
<td>{{ description[loop.index0] }}</td>
<td>{{ version[loop.index0] }}</td>
<td style="text-align: center;">
{% if enabled[loop.index0] %}
<div style="display:none;">Enabled</div>
<div style="color:Green; display:inline-block"><i class="fa fa-check-circle fa-2x"></i></div>
{% endif %}
{% if not enabled[loop.index0] %}
<div style="display:none;">Disabled</div>
<div style="color:Red; display:inline-block"><i class="fa fa-times-circle fa-2x"></i></div>
{% endif %}
</td>
<td style="text-align: center;">
<div style="display:none;">{{ n_tags[loop.index0] }}</div>
<a class="btn btn-primary" href="{{ url_for('Tags.edit_taxonomie') }}?taxonomie={{ id[loop.index0] }}">Active Tags <span class="badge">{{ n_tags[loop.index0] }}</span></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- /#page-wrapper -->
</body>
<script>
$(document).ready(function(){
$('#myTable_').DataTable(
{
"aLengthMenu": [[5, 10, 15, 20, -1], [5, 10, 15, 20, "All"]],
"iDisplayLength": 15,
}
);
});
</script>
</html>

View File

@ -20,6 +20,8 @@ app = Flask_config.app
cfg = Flask_config.cfg
max_preview_char = Flask_config.max_preview_char
max_preview_modal = Flask_config.max_preview_modal
r_serv_metadata = Flask_config.r_serv_metadata
bootstrap_label = Flask_config.bootstrap_label
#init all lvlDB servers
curYear = datetime.now().year
@ -56,6 +58,7 @@ def getPastebyType(server, module_name):
def event_stream_getImportantPasteByModule(module_name, year):
index = 0
all_pastes_list = getPastebyType(r_serv_db[year], module_name)
paste_tags = []
for path in all_pastes_list:
index += 1
@ -64,6 +67,23 @@ def event_stream_getImportantPasteByModule(module_name, year):
content_range = max_preview_char if len(content)>max_preview_char else len(content)-1
curr_date = str(paste._get_p_date())
curr_date = curr_date[0:4]+'/'+curr_date[4:6]+'/'+curr_date[6:]
p_tags = r_serv_metadata.smembers('tag:'+path)
l_tags = []
for tag in p_tags:
complete_tag = tag.replace('"', '&quot;')
tag = tag.split('=')
if len(tag) > 1:
if tag[1] != '':
tag = tag[1][1:-1]
# no value
else:
tag = tag[0][1:-1]
# use for custom tags
else:
tag = tag[0]
l_tags.append( (tag, complete_tag) )
data = {}
data["module"] = module_name
data["index"] = index
@ -71,6 +91,8 @@ def event_stream_getImportantPasteByModule(module_name, year):
data["content"] = content[0:content_range]
data["linenum"] = paste.get_lines_info()[0]
data["date"] = curr_date
data["l_tags"] = l_tags
data["bootstrap_label"] = bootstrap_label
data["char_to_display"] = max_preview_modal
data["finished"] = True if index == len(all_pastes_list) else False
yield 'retry: 100000\ndata: %s\n\n' % json.dumps(data) #retry to avoid reconnection of the browser
@ -98,6 +120,7 @@ def importantPasteByModule():
paste_date = []
paste_linenum = []
all_path = []
paste_tags = []
allPastes = getPastebyType(r_serv_db[currentSelectYear], module_name)
for path in allPastes[0:10]:
@ -110,6 +133,24 @@ def importantPasteByModule():
curr_date = curr_date[0:4]+'/'+curr_date[4:6]+'/'+curr_date[6:]
paste_date.append(curr_date)
paste_linenum.append(paste.get_lines_info()[0])
p_tags = r_serv_metadata.smembers('tag:'+path)
l_tags = []
for tag in p_tags:
complete_tag = tag
tag = tag.split('=')
if len(tag) > 1:
if tag[1] != '':
tag = tag[1][1:-1]
# no value
else:
tag = tag[0][1:-1]
# use for custom tags
else:
tag = tag[0]
l_tags.append( (tag, complete_tag) )
paste_tags.append(l_tags)
if len(allPastes) > 10:
finished = False
@ -124,6 +165,8 @@ def importantPasteByModule():
paste_date=paste_date,
paste_linenum=paste_linenum,
char_to_display=max_preview_modal,
paste_tags=paste_tags,
bootstrap_label=bootstrap_label,
finished=finished)
@browsepastes.route("/_getImportantPasteByModule", methods=['GET'])

View File

@ -12,7 +12,15 @@
{% for path in all_path %}
<tr>
<td> {{ loop.index0 }}</td>
<td><a target="_blank" href="{{ url_for('showsavedpastes.showsavedpaste') }}?paste={{path}}&num={{loop.index0+1}}">{{ path }}</a></td>
<td><a target="_blank" href="{{ url_for('showsavedpastes.showsavedpaste') }}?paste={{path}}">{{ path }}</a>
<div>
{% for tag in paste_tags[loop.index0] %}
<a href="{{ url_for('Tags.get_tagged_paste') }}?ltags={{ tag[1] }}">
<span class="label label-{{ bootstrap_label[loop.index0 % 5] }} pull-left">{{ tag[0] }}</span>
</a>
{% endfor %}
</div>
</td>
<td>{{ paste_date[loop.index0] }}</td>
<td>{{ paste_linenum[loop.index0] }}</td>
<td><p><span class="glyphicon glyphicon-info-sign" data-toggle="tooltip" data-placement="left" title="{{ content[loop.index0] }} "></span> <button type="button" class="btn-link" data-num="{{ loop.index0 + 1 }}" data-toggle="modal" data-target="#mymodal" data-url="{{ url_for('showsavedpastes.showsavedpaste') }}?paste={{ path }}&num={{ loop.index0+1 }}" data-path="{{ path }}"><span class="fa fa-search-plus"></span></button></p></td>
@ -89,14 +97,21 @@ function add_entries_X(to_add) {
} else {
var feed = json_array.shift();
elem_added++;
search_table.row.add( [
feed.index,
"<a target=\"_blank\" href=\"{{ url_for('showsavedpastes.showsavedpaste') }}?paste="+feed.path+"&num="+feed.index+"\"> "+ feed.path +"</a>",
feed.date,
feed.linenum,
"<p><span class=\"glyphicon glyphicon-info-sign\" data-toggle=\"tooltip\" data-placement=\"left\" title=\""+feed.content.replace(/\"/g, "\'").replace(/\r/g, "\'").replace(/\n/g, "\'")+"\"></span> <button type=\"button\" class=\"btn-link\" data-num=\""+feed.index+"\" data-toggle=\"modal\" data-target=\"#mymodal\" data-url=\"{{ url_for('showsavedpastes.showsavedpaste') }}?paste="+feed.path+"&num="+feed.index+"\" data-path=\""+feed.path+"\"><span class=\"fa fa-search-plus\"></span></button></p>"
] ).draw( false );
$("#myTable_"+moduleName).attr('data-numElem', curr_numElem+1);
var tag = ""
for(j=0; j<feed.l_tags.length; j++) {
console.log(feed.l_tags[j][1])
tag = tag + "<a href=\"{{ url_for('Tags.get_tagged_paste') }}?ltags=" + feed.l_tags[j][1] + "\">"
+ "<span class=\"label label-" + feed.bootstrap_label[j % 5] + " pull-left\">" + feed.l_tags[j][0] + "</span>" + "</a>";
}
search_table.row.add( [
feed.index,
"<a target=\"_blank\" href=\"{{ url_for('showsavedpastes.showsavedpaste') }}?paste="+feed.path+"&num="+feed.index+"\"> "+ feed.path +"</a>"
+ "<div>" + tag + "</div>" ,
feed.date,
feed.linenum,
"<p><span class=\"glyphicon glyphicon-info-sign\" data-toggle=\"tooltip\" data-placement=\"left\" title=\""+feed.content.replace(/\"/g, "\'").replace(/\r/g, "\'").replace(/\n/g, "\'")+"\"></span> <button type=\"button\" class=\"btn-link\" data-num=\""+feed.index+"\" data-toggle=\"modal\" data-target=\"#mymodal\" data-url=\"{{ url_for('showsavedpastes.showsavedpaste') }}?paste="+feed.path+"&num="+feed.index+"\" data-path=\""+feed.path+"\"><span class=\"fa fa-search-plus\"></span></button></p>"
] ).draw( false );
$("#myTable_"+moduleName).attr('data-numElem', curr_numElem+1);
}
}
$("#load_more_json_button1").removeAttr('disabled');
@ -122,7 +137,6 @@ $("#myTable_"+moduleName).attr('data-numElem', "{{ all_path|length }}");
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
$("[data-toggle='modal']").off('click.openmodal').on("click.openmodal", function (event) {
//get_html_and_update_modal(event);
get_html_and_update_modal(event, $(this));
});

View File

@ -22,8 +22,10 @@ import Flask_config
app = Flask_config.app
cfg = Flask_config.cfg
r_serv_pasteName = Flask_config.r_serv_pasteName
r_serv_metadata = Flask_config.r_serv_metadata
max_preview_char = Flask_config.max_preview_char
max_preview_modal = Flask_config.max_preview_modal
bootstrap_label = Flask_config.bootstrap_label
baseindexpath = os.path.join(os.environ['AIL_HOME'], cfg.get("Indexer", "path"))
@ -95,6 +97,7 @@ def search():
c = [] #preview of the paste content
paste_date = []
paste_size = []
paste_tags = []
index_name = request.form['index_name']
num_elem_to_get = 50
@ -119,13 +122,15 @@ def search():
# Search full line
schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT)
print(selected_index)
ix = index.open_dir(selected_index)
with ix.searcher() as searcher:
query = QueryParser("content", ix.schema).parse(" ".join(q))
results = searcher.search_page(query, 1, pagelen=num_elem_to_get)
for x in results:
r.append(x.items()[0][1])
paste = Paste.Paste(x.items()[0][1])
path = x.items()[0][1]
paste = Paste.Paste(path)
content = paste.get_p_content()
content_range = max_preview_char if len(content)>max_preview_char else len(content)-1
c.append(content[0:content_range])
@ -133,6 +138,24 @@ def search():
curr_date = curr_date[0:4]+'/'+curr_date[4:6]+'/'+curr_date[6:]
paste_date.append(curr_date)
paste_size.append(paste._get_p_size())
p_tags = r_serv_metadata.smembers('tag:'+path)
l_tags = []
for tag in p_tags:
complete_tag = tag
tag = tag.split('=')
if len(tag) > 1:
if tag[1] != '':
tag = tag[1][1:-1]
# no value
else:
tag = tag[0][1:-1]
# use for custom tags
else:
tag = tag[0]
l_tags.append( (tag, complete_tag) )
paste_tags.append(l_tags)
results = searcher.search(query)
num_res = len(results)
@ -142,6 +165,8 @@ def search():
query=request.form['query'], paste_date=paste_date,
paste_size=paste_size, char_to_display=max_preview_modal,
num_res=num_res, index_min=index_min, index_max=index_max,
bootstrap_label=bootstrap_label,
paste_tags=paste_tags,
index_list=get_index_list(selected_index)
)
@ -165,6 +190,7 @@ def get_more_search_result():
preview_array = []
date_array = []
size_array = []
list_tags = []
schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT)
@ -173,8 +199,9 @@ def get_more_search_result():
query = QueryParser("content", ix.schema).parse(" ".join(q))
results = searcher.search_page(query, page_offset, num_elem_to_get)
for x in results:
path_array.append(x.items()[0][1])
paste = Paste.Paste(x.items()[0][1])
path = x.items()[0][1]
path_array.append(path)
paste = Paste.Paste(path)
content = paste.get_p_content()
content_range = max_preview_char if len(content)>max_preview_char else len(content)-1
preview_array.append(content[0:content_range])
@ -182,11 +209,30 @@ def get_more_search_result():
curr_date = curr_date[0:4]+'/'+curr_date[4:6]+'/'+curr_date[6:]
date_array.append(curr_date)
size_array.append(paste._get_p_size())
p_tags = r_serv_metadata.smembers('tag:'+path)
l_tags = []
for tag in p_tags:
tag = tag.split('=')
if len(tag) > 1:
if tag[1] != '':
tag = tag[1][1:-1]
# no value
else:
tag = tag[0][1:-1]
# use for custom tags
else:
tag = tag[0]
l_tags.append(tag)
list_tags.append(l_tags)
to_return = {}
to_return["path_array"] = path_array
to_return["preview_array"] = preview_array
to_return["date_array"] = date_array
to_return["size_array"] = size_array
to_return["list_tags"] = list_tags
to_return["bootstrap_label"] = bootstrap_label
if len(path_array) < num_elem_to_get: #pagelength
to_return["moreData"] = False
else:

View File

@ -75,7 +75,7 @@
<div class="panel-body">
<div class="row">
<div class="col-md-12">
<strong style="">Index: </strong>
<strong style="">Index: </strong>
<select class="form-control" id="index_name" style="display: inline-block; margin-bottom: 5px; width: 30%">
{% for indexElem in index_list %}
<option {% if indexElem[2] %} selected="selected" {% endif %} value="{{ indexElem[0] }}" >{{ indexElem[1] }}</option>
@ -96,11 +96,19 @@
<tbody id="table_body">
{% for path in r %}
<tr>
<td>{{ loop.index0 + 1 }}</td>
<td><a target="_blank" href="{{ url_for('showsavedpastes.showsavedpaste') }}?paste={{ path }}&num={{ loop.index0+1 }}"> {{ path }}</a></td>
<td>{{ paste_date[loop.index0] }}</td>
<td>{{ paste_size[loop.index0] }}</td>
<td><p><span class="glyphicon glyphicon-info-sign" data-toggle="tooltip" data-placement="left" title="{{ c[loop.index0] }}"></span> <button type="button" class="btn-link" data-num="{{ loop.index0 + 1 }}" data-toggle="modal" data-target="#mymodal" data-url="{{ url_for('showsavedpastes.showsavedpaste') }}?paste={{ path }}&num={{ loop.index0+1 }}" data-path="{{ path }}"><span class="fa fa-search-plus"></span></button></p></td>
<td> {{ loop.index0 }}</td>
<td><a target="_blank" href="{{ url_for('showsavedpastes.showsavedpaste') }}?paste={{path}}">{{ path }}</a>
<div>
{% for tag in paste_tags[loop.index0] %}
<a href="{{ url_for('Tags.get_tagged_paste') }}?ltags={{ tag[1] }}">
<span class="label label-{{ bootstrap_label[loop.index0 % 5] }} pull-left">{{ tag[0] }}</span>
</a>
{% endfor %}
</div>
</td>
<td>{{ paste_date[loop.index0] }}</td>
<td>{{ paste_size[loop.index0] }}</td>
<td><p><span class="glyphicon glyphicon-info-sign" data-toggle="tooltip" data-placement="left" title="{{ c[loop.index0] }} "></span> <button type="button" class="btn-link" data-num="{{ loop.index0 + 1 }}" data-toggle="modal" data-target="#mymodal" data-url="{{ url_for('showsavedpastes.showsavedpaste') }}?paste={{ path }}" data-path="{{ path }}"><span class="fa fa-search-plus"></span></button></p></td>
</tr>
{% endfor %}
</tbody>
@ -160,7 +168,7 @@
input1.setAttribute("name", "index_name");
input1.setAttribute("value", this.value);
form.appendChild(input1);
var input2 = document.createElement('input');
input2.setAttribute("type", "hidden");
input2.setAttribute("name", "query");
@ -190,9 +198,14 @@
for(i=0; i<data.path_array.length; i++) {
var curr_preview = data.preview_array[i].replace(/\"/g, "\'");
var tag = ""
for(j=0; j<data.list_tags[i].length; j++) {
tag = tag + "<span class=\"label label-" + data.bootstrap_label[j % 5] + " pull-left\">" + data.list_tags[j] + "</span>"
}
search_table.row.add( [
init_num_of_elements_in_table+((offset))+i+1,
"<a target=\"_blank\" href=\"{{ url_for('showsavedpastes.showsavedpaste') }}?paste="+data.path_array[i]+"&num="+i+"\"> "+ data.path_array[i] +"</a>",
"<a target=\"_blank\" href=\"{{ url_for('showsavedpastes.showsavedpaste') }}?paste="+data.path_array[i]+"&num="+i+"\"> "+ data.path_array[i] +"</a>"
+ "<div>" + tag + "</div>",
data.date_array[i],
data.size_array[i],
"<p><span class=\"glyphicon glyphicon-info-sign\" data-toggle=\"tooltip\" data-placement=\"left\" title=\""+curr_preview+"\"></span> <button type=\"button\" class=\"btn-link\" data-num=\""+i+"\" data-toggle=\"modal\" data-target=\"#mymodal\" data-url=\"{{ url_for('showsavedpastes.showsavedpaste') }}?paste="+data.path_array[i]+"&num="+i+"\" data-path=\""+data.path_array[i]+"\"><span class=\"fa fa-search-plus\"></span></button></p>"
@ -245,7 +258,7 @@
if (final_index != start_index){ // still have data to display
// Append the new content using text() and not append (XSS)
$("#mymodalbody").find("#paste-holder").text($("#mymodalbody").find("#paste-holder").text() + complete_paste.substring(start_index+1, final_index+1));
$("#mymodalbody").find("#paste-holder").text($("#mymodalbody").find("#paste-holder").text() + complete_paste.substring(start_index+1, final_index+1));
start_index = final_index;
if (flag_stop)
nothing_to_display();
@ -272,7 +285,7 @@
last_clicked_paste = $(this).attr('data-num');
$.get(url, function (data) {
// verify that the reveived data is really the current clicked paste. Otherwise, ignore it.
// verify that the reveived data is really the current clicked paste. Otherwise, ignore it.
var received_num = parseInt(data.split("|num|")[1]);
if (received_num == last_clicked_paste && can_change_modal_content) {
can_change_modal_content = false;
@ -285,7 +298,7 @@
var button = $('<button type="button" id="load-more-button" class="btn btn-info btn-xs center-block" data-url="' + $(modal).attr('data-path') +'" data-toggle="tooltip" data-placement="bottom" title="Load more content"><span class="glyphicon glyphicon-download"></span></button>');
button.tooltip();
$("#mymodalbody").children(".panel-default").append(button);
$("#button_show_path").attr('href', $(modal).attr('data-url'));
$("#button_show_path").show('fast');
$("#loading-gif-modal").css("visibility", "hidden"); // Hide the loading GIF

View File

@ -19,9 +19,11 @@ app = Flask_config.app
cfg = Flask_config.cfg
r_serv_pasteName = Flask_config.r_serv_pasteName
r_serv_metadata = Flask_config.r_serv_metadata
r_serv_tags = Flask_config.r_serv_tags
max_preview_char = Flask_config.max_preview_char
max_preview_modal = Flask_config.max_preview_modal
DiffMaxLineLength = Flask_config.DiffMaxLineLength
bootstrap_label = Flask_config.bootstrap_label
showsavedpastes = Blueprint('showsavedpastes', __name__, template_folder='templates')
@ -96,7 +98,23 @@ def showpaste(content_range):
if content_range != 0:
p_content = p_content[0:content_range]
return render_template("show_saved_paste.html", date=p_date, source=p_source, encoding=p_encoding, language=p_language, size=p_size, mime=p_mime, lineinfo=p_lineinfo, content=p_content, initsize=len(p_content), duplicate_list = p_duplicate_list, simil_list = p_simil_list, hashtype_list = p_hashtype_list, date_list=p_date_list)
#active taxonomies
active_taxonomies = r_serv_tags.smembers('active_taxonomies')
l_tags = r_serv_metadata.smembers('tag:'+requested_path)
#active galaxies
active_galaxies = r_serv_tags.smembers('active_galaxies')
list_tags = []
for tag in l_tags:
if(tag[9:28] == 'automatic-detection'):
list_tags.append( (tag, True) )
else:
list_tags.append( (tag, False) )
return render_template("show_saved_paste.html", date=p_date, bootstrap_label=bootstrap_label, active_taxonomies=active_taxonomies, active_galaxies=active_galaxies, list_tags=list_tags, source=p_source, encoding=p_encoding, language=p_language, size=p_size, mime=p_mime, lineinfo=p_lineinfo, content=p_content, initsize=len(p_content), duplicate_list = p_duplicate_list, simil_list = p_simil_list, hashtype_list = p_hashtype_list, date_list=p_date_list)
# ============ ROUTES ============

View File

@ -9,6 +9,8 @@
<link href="{{ url_for('static', filename='font-awesome/css/font-awesome.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/sb-admin-2.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/dataTables.bootstrap.css') }}" rel="stylesheet" type="text/css" />
<link href="{{ url_for('static', filename='css/tags.css') }}" rel="stylesheet" type="text/css" />
<script language="javascript" src="{{ url_for('static', filename='js/jquery.js')}}"></script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.dataTables.min.js') }}"></script>
@ -16,12 +18,130 @@
<script src="{{ url_for('static', filename='js/jquery.flot.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.flot.time.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery.flot.stack.js') }}"></script>
<script src="{{ url_for('static', filename='js/tags.js') }}"></script>
<style>
.scrollable-menu {
height: auto;
max-height: 200px;
overflow-x: hidden;
width:100%;
}
</style>
</head>
<body>
<div class="panel panel-default">
<div class="panel-heading">
<h1 class="page-header" >Paste: {{ request.args.get('paste') }}</h1>
<h2 class="page-header" >({{ request.args.get('num') }})</h2>
<h2 class="page-header" >
<div>
<div id="mymodal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<!-- Modal content-->
<div id="mymodalcontent" class="modal-content">
<div class="modal-header" style="border-bottom: 4px solid #cccccc; background-color: #cccccc; color: #ffffff;">
<p class="heading">Edit this tag</p>
</div>
<div class="modal-body">
<div class="form-group input-group" >
<input id="ltags" style="width:850%;" type="text" name="ltags">
</div>
<div class="btn-group btn-block">
<button type="button" class="btn btn-primary dropdown-toggle btn-block" data-toggle="dropdown">Taxonomie Selection
<i class="fa fa-chevron-down"></i>
</button>
<ul class="dropdown-menu scrollable-menu" role="menu">
<li><a href="#" id="all-tags-taxonomies">All Tags <i class="fa fa-tags"></i></a></li>
<li role="separator" class="divider"></li>
{% for taxo in active_taxonomies %}
<li><a href="#" id="{{ taxo }}-id{{ loop.index0 }}">{{ taxo }}</a></li>
{% endfor %}
</ul>
</div>
<br/><br/>
<div class="form-group input-group" >
<input id="ltagsgalaxies" style="width:850%;" type="text" name="ltagsgalaxies">
</div>
<div class="btn-group btn-block">
<button type="button" class="btn btn-primary dropdown-toggle btn-block" data-toggle="dropdown">Galaxy Selection
<i class="fa fa-chevron-down"></i>
</button>
<ul class="dropdown-menu scrollable-menu" role="menu">
<li><a href="#" id="all-tags-galaxies">All Tags <i class="fa fa-tags"></i></a></li>
<li role="separator" class="divider"></li>
{% for galaxy in active_galaxies %}
<li><a href="#" id="{{ galaxy }}-idgalax{{ loop.index0 }}">{{ galaxy }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="modal-footer">
<a class="btn btn-tags pull-left" href="{{ url_for('Tags.taxonomies') }}" target="_blank">
<span class="label-icon">Edit Taxonomies List </span>
<i class="fa fa-wrench fa-2x"></i>
</a>
<a class="btn btn-tags pull-left" href="{{ url_for('Tags.galaxies') }}" target="_blank">
<span class="label-icon">Edit Galaxies List</span>
<i class="fa fa-rocket fa-2x"></i>
</a>
<button class="btn btn-primary btn-tags" onclick="addTags()">
<span class="glyphicon glyphicon-plus"></span>
<span class="label-icon">Add Tags</span>
</button>
<button type="button" class="btn btn-default" data-dismiss="modal" >Close</button>
</div>
</div>
</div>
</div>
{% for tag in list_tags %}
<span class="btn btn-{{ bootstrap_label[loop.index0 % 5] }} btn-lg pull-left" data-toggle="modal" data-target="#myModal_{{ loop.index0 }}">{{ tag[0] }}</span>
<!-- Modal edit this tag -->
<div class="modal fade" id="myModal_{{ loop.index0 }}" role="dialog">
<div class="modal-dialog">
<div class="modal-content text-center">
<div class="modal-header" style="border-bottom: 4px solid #cccccc; background-color: #cccccc; color: #ffffff;">
<p class="heading">Edit this tag</p>
</div>
<div class="modal-body">
<span class="label label-{{ bootstrap_label[loop.index0 % 5] }}" >{{ tag[0] }}</span>
</div>
<div class="modal-footer center">
{% if tag[1] %}
<a href="{{ url_for('Tags.confirm_tag') }}?paste={{ request.args.get('paste') }}&tag={{ tag[0] }}" class="btn btn-primary">
<span class="glyphicon glyphicon-ok "></span> Confirm this Tag
</a>
{% endif %}
<a href="{{ url_for('Tags.remove_tag') }}?paste={{ request.args.get('paste') }}&tag={{ tag[0] }}" class="btn btn-danger">
<span class="glyphicon glyphicon-trash "></span> Delete this Tag
</a>
</div>
</div>
</div>
</div>
{% endfor %}
<button type="button" class="btn btn-light btn-lg" data-toggle="modal" data-target="#mymodal" data-url="{{ url_for('Tags.taxonomies') }}">
<span class="glyphicon glyphicon-plus "></span>
</button>
</div>
</h2>
<table class="table table-condensed">
<thead>
@ -49,6 +169,7 @@
</tr>
</tbody>
</table>
</div>
<div class="panel-body" id="panel-body">
{% if duplicate_list|length == 0 %}
@ -86,7 +207,86 @@
</div>
</body>
<script>
$('#tableDup').DataTable();
var ltags
var ltagsgalaxies
$(document).ready(function(){
$.getJSON('/Tags/get_all_tags_taxonomies',
function(data) {
ltags = $('#ltags').tagSuggest({
data: data,
maxDropHeight: 200,
name: 'ltags'
});
});
$.getJSON('/Tags/get_all_tags_galaxies',
function(data) {
ltagsgalaxies = $('#ltagsgalaxies').tagSuggest({
data: data,
maxDropHeight: 200,
name: 'ltagsgalaxies'
});
});
$('#tableDup').DataTable();
});
</script>
<script>
jQuery("#all-tags-taxonomies").click(function(e){
//change input tags list
$.getJSON('/Tags/get_all_tags_taxonomies',
function(data) {
ltags.setData(data)
});
});
</script>
<script>
jQuery("#all-tags-galaxies").click(function(e){
$.getJSON('/Tags/get_all_tags_galaxies',
function(data) {
ltagsgalaxies.setData(data)
});
});
</script>
<script>
function addTags() {
var tags = ltags.getValue()
var tagsgalaxy = ltagsgalaxies.getValue()
var path = '{{ request.args.get('paste') }}'
window.location.replace("{{ url_for('Tags.addTags') }}?tags=" + tags + "&tagsgalaxies=" + tagsgalaxy + "&path=" + path);
}
</script>
<script>
{% for taxo in active_taxonomies %}
jQuery("#{{ taxo }}-id{{ loop.index0 }}").click(function(e){
$.getJSON('/Tags/get_tags_taxonomie?taxonomie={{ taxo }}',
function(data) {
ltags.setData(data)
});
});
{% endfor %}
</script>
<script>
{% for galaxy in active_galaxies %}
jQuery("#{{ galaxy }}-idgalax{{ loop.index0 }}").click(function(e){
$.getJSON('/Tags/get_tags_galaxy?galaxy={{ galaxy }}',
function(data) {
ltagsgalaxies.setData(data)
});
});
{% endfor %}
</script>
</html>

226
var/www/static/css/tags.css Normal file
View File

@ -0,0 +1,226 @@
.tag-ctn{
position: relative;
height: 30px;
padding: 0;
margin-bottom: 0px;
font-size: 14px;
line-height: 20px;
color: #555555;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background-color: #ffffff;
border: 1px solid #cccccc;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
-moz-transition: border linear 0.2s, box-shadow linear 0.2s;
-o-transition: border linear 0.2s, box-shadow linear 0.2s;
transition: border linear 0.2s, box-shadow linear 0.2s;
cursor: default;
display: block;
}
.tag-ctn-invalid{
border: 1px solid #CC0000;
}
.tag-ctn-readonly{
cursor: pointer;
}
.tag-ctn-disabled{
cursor: not-allowed;
background-color: #eeeeee;
}
.tag-ctn-bootstrap-focus,
.tag-ctn-bootstrap-focus .tag-res-ctn{
border-color: rgba(82, 168, 236, 0.8) !important;
/* IE6-9 */
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6) !important;
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6) !important;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6) !important;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.tag-ctn input{
border: 0;
box-shadow: none;
-webkit-transition: none;
outline: none;
display: block;
padding: 4px 6px;
line-height: normal;
overflow: hidden;
height: auto;
border-radius: 0;
float: left;
margin: 2px 0 2px 2px;
}
.tag-ctn-disabled input{
cursor: not-allowed;
background-color: #eeeeee;
}
.tag-ctn .tag-input-readonly{
cursor: pointer;
}
.tag-ctn .tag-empty-text{
color: #DDD;
}
.tag-ctn input:focus{
border: 0;
box-shadow: none;
-webkit-transition: none;
background: #FFF;
}
.tag-ctn .tag-trigger{
float: right;
width: 27px;
height:100%;
position:absolute;
right:0;
border-left: 1px solid #CCC;
background: #EEE;
cursor: pointer;
}
.tag-ctn .tag-trigger .tag-trigger-ico {
display: inline-block;
width: 0;
height: 0;
vertical-align: top;
border-top: 4px solid gray;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
content: "";
margin-left: 9px;
margin-top: 13px;
}
.tag-ctn .tag-trigger:hover{
background: -moz-linear-gradient(100% 100% 90deg, #e3e3e3, #f1f1f1);
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f1f1f1), to(#e3e3e3));
}
.tag-ctn .tag-trigger:hover .tag-trigger-ico{
background-position: 0 -4px;
}
.tag-ctn-disabled .tag-trigger{
cursor: not-allowed;
background-color: #eeeeee;
}
.tag-ctn-bootstrap-focus{
border-bottom: 1px solid #CCC;
}
.tag-res-ctn{
position: relative;
background: #FFF;
overflow-y: auto;
z-index: 9999;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #CCC;
left: -1px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
-moz-transition: border linear 0.2s, box-shadow linear 0.2s;
-o-transition: border linear 0.2s, box-shadow linear 0.2s;
transition: border linear 0.2s, box-shadow linear 0.2s;
border-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.tag-res-ctn .tag-res-group{
line-height: 23px;
text-align: left;
padding: 2px 5px;
font-weight: bold;
border-bottom: 1px dotted #CCC;
border-top: 1px solid #CCC;
background: #f3edff;
color: #333;
}
.tag-res-ctn .tag-res-item{
line-height: 25px;
text-align: left;
padding: 2px 5px;
color: #666;
cursor: pointer;
}
.tag-res-ctn .tag-res-item-grouped{
padding-left: 15px;
}
.tag-res-ctn .tag-res-odd{
background: #F3F3F3;
}
.tag-res-ctn .tag-res-item-active{
background-color: #3875D7;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3875D7', endColorstr='#2A62BC', GradientType=0 );
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #3875D7), color-stop(90%, #2A62BC));
background-image: -webkit-linear-gradient(top, #3875D7 20%, #2A62BC 90%);
background-image: -moz-linear-gradient(top, #3875D7 20%, #2A62BC 90%);
background-image: -o-linear-gradient(top, #3875D7 20%, #2A62BC 90%);
background-image: linear-gradient(#3875D7 20%, #2A62BC 90%);
color: #fff;
}
.tag-sel-ctn{
overflow: auto;
line-height: 22px;
padding-right:27px;
}
.tag-sel-ctn .tag-sel-item{
background: #555;
color: #EEE;
float: left;
font-size: 12px;
padding: 0 5px;
border-radius: 3px;
margin-left: 5px;
margin-top: 4px;
}
.tag-sel-ctn .tag-sel-text{
background: #FFF;
color: #666;
padding-right: 0;
margin-left: 0;
font-size: 14px;
font-weight: normal;
}
.tag-res-ctn .tag-res-item em{
font-style: normal;
background: #565656;
color: #FFF;
}
.tag-sel-ctn .tag-sel-item:hover{
background: #565656;
}
.tag-sel-ctn .tag-sel-text:hover{
background: #FFF;
}
.tag-sel-ctn .tag-sel-item-active{
border: 1px solid red;
background: #757575;
}
.tag-ctn .tag-sel-ctn .tag-sel-item{
margin-top: 3px;
}
.tag-stacked .tag-sel-item{
float: inherit;
}
.tag-sel-ctn .tag-sel-item .tag-close-btn{
width: 7px;
cursor: pointer;
height: 7px;
float: right;
margin: 8px 2px 0 10px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAOCAYAAADjXQYbAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAEZ0FNQQAAsY58+1GTAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAABSSURBVHjahI7BCQAwCAOTzpThHMHh3Kl9CVos9XckFwQAuPtGuWTWwMwaczKzyHsqg6+5JqMJr28BABHRwmTWQFJjTmYWOU1L4tdck9GE17dnALGAS+kAR/u2AAAAAElFTkSuQmCC);
}
.tag-sel-ctn .tag-sel-item .tag-close-btn:hover{
background-position: 0 -7px;
}
.tag-helper{
color: #AAA;
font-size: 10px;
position: absolute;
top: -17px;
right: 0;
}

1516
var/www/static/js/tags.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,23 +5,27 @@ set -e
wget http://dygraphs.com/dygraph-combined.js -O ./static/js/dygraph-combined.js
SBADMIN_VERSION='3.3.7'
FONT_AWESOME_VERSION='4.7.0'
rm -rf temp
mkdir temp
wget https://github.com/BlackrockDigital/startbootstrap-sb-admin/archive/v${SBADMIN_VERSION}.zip -O temp/${SBADMIN_VERSION}.zip
wget https://github.com/BlackrockDigital/startbootstrap-sb-admin-2/archive/v${SBADMIN_VERSION}.zip -O temp/${SBADMIN_VERSION}-2.zip
wget https://github.com/FortAwesome/Font-Awesome/archive/v${FONT_AWESOME_VERSION}.zip -O temp/FONT_AWESOME_${FONT_AWESOME_VERSION}.zip
unzip temp/${SBADMIN_VERSION}.zip -d temp/
unzip temp/${SBADMIN_VERSION}-2.zip -d temp/
unzip temp/FONT_AWESOME_${FONT_AWESOME_VERSION}.zip -d temp/
mv temp/startbootstrap-sb-admin-${SBADMIN_VERSION} temp/sb-admin
mv temp/startbootstrap-sb-admin-2-${SBADMIN_VERSION} temp/sb-admin-2
mv temp/Font-Awesome-${FONT_AWESOME_VERSION} temp/font-awesome
rm -rf ./static/js/plugins
mv temp/sb-admin/js/* ./static/js/
rm -rf ./static/fonts/ ./static/font-awesome/
mv temp/sb-admin/fonts/ ./static/
mv temp/sb-admin/font-awesome/ ./static/
mv temp/font-awesome/ ./static/
rm -rf ./static/css/plugins/
mv temp/sb-admin/css/* ./static/css/
@ -60,3 +64,9 @@ mkdir -p ./static/image
pushd static/image
wget https://www.circl.lu/assets/images/logos/AIL.png -O AIL.png
popd
#active virtualenv
source ./../../AILENV/bin/activate
#Update MISP Taxonomies and Galaxies
python3 -m pip install git+https://github.com/MISP/PyTaxonomies
python3 -m pip install git+https://github.com/MISP/PyMISPGalaxies