|
@ -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
|
||||
|
|
|
@ -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
|
||||
------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
29
bin/Keys.py
|
@ -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 :
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
After Width: | Height: | Size: 98 KiB |
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 125 KiB |
After Width: | Height: | Size: 12 KiB |
|
@ -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
|
||||
|
|
|
@ -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__":
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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)
|
|
@ -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>
|
|
@ -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"> </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>
|
|
@ -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"> </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>
|
|
@ -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>
|
|
@ -0,0 +1 @@
|
|||
<li id='page-Tags'><a href="{{ url_for('Tags.Tags_page') }}"><i class="fa fa-tag "></i> Tags </a></li>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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('"', '"')
|
||||
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'])
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ============
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|