This commit is contained in:
Terrtia 2018-05-16 14:39:01 +02:00
parent 80720f8ca5
commit b1b7d33c96
No known key found for this signature in database
GPG key ID: 1E1B1F50D84613D0
19 changed files with 674 additions and 2 deletions

View file

@ -41,6 +41,8 @@ def search_api_key(message):
print(to_print) print(to_print)
publisher.warning('{}Checked {} found Google API Key;{}'.format( publisher.warning('{}Checked {} found Google API Key;{}'.format(
to_print, len(google_api_key), paste.p_path)) 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): if(len(aws_access_key) > 0 or len(aws_secret_key) > 0):
print('found AWS key') print('found AWS key')
@ -48,8 +50,13 @@ def search_api_key(message):
total = len(aws_access_key) + len(aws_secret_key) total = len(aws_access_key) + len(aws_secret_key)
publisher.warning('{}Checked {} found AWS Key;{}'.format( publisher.warning('{}Checked {} found AWS Key;{}'.format(
to_print, total, paste.p_path)) 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) msg = 'apikey;{}'.format(filename)
p.populate_set_out(msg, 'alertHandler') p.populate_set_out(msg, 'alertHandler')
#Send to duplicate #Send to duplicate

View file

@ -65,6 +65,9 @@ def search_base64(content, message):
msg = ('base64;{}'.format(message)) msg = ('base64;{}'.format(message))
p.populate_set_out( msg, 'alertHandler') 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): def save_base64_as_file(decode, type, hash, json_data):
filename_b64 = os.path.join(os.environ['AIL_HOME'], filename_b64 = os.path.join(os.environ['AIL_HOME'],

View file

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

View file

@ -105,6 +105,9 @@ if __name__ == "__main__":
msg = 'credential;{}'.format(filepath) msg = 'credential;{}'.format(filepath)
p.populate_set_out(msg, 'alertHandler') 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 #Put in form, count occurences, then send to moduleStats
creds_sites = {} creds_sites = {}
site_occurence = re.findall(regex_site_for_stats, content) site_occurence = re.findall(regex_site_for_stats, content)

View file

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

View file

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

View file

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

View file

@ -110,6 +110,8 @@ function launching_scripts {
sleep 0.1 sleep 0.1
screen -S "Script_AIL" -X screen -t "Duplicates" bash -c './Duplicates.py; read x' screen -S "Script_AIL" -X screen -t "Duplicates" bash -c './Duplicates.py; read x'
sleep 0.1 sleep 0.1
#screen -S "Script_AIL" -X screen -t "Attributes" bash -c './Attributes.py; read x'
#sleep 0.1
screen -S "Script_AIL" -X screen -t "Lines" bash -c './Lines.py; read x' screen -S "Script_AIL" -X screen -t "Lines" bash -c './Lines.py; read x'
sleep 0.1 sleep 0.1
screen -S "Script_AIL" -X screen -t "DomClassifier" bash -c './DomClassifier.py; read x' screen -S "Script_AIL" -X screen -t "DomClassifier" bash -c './DomClassifier.py; read x'
@ -144,6 +146,8 @@ function launching_scripts {
sleep 0.1 sleep 0.1
screen -S "Script_AIL" -X screen -t "Base64" bash -c './Base64.py; read x' screen -S "Script_AIL" -X screen -t "Base64" bash -c './Base64.py; read x'
sleep 0.1 sleep 0.1
screen -S "Script_AIL" -X screen -t "DbDump" bash -c './DbDump.py; read x'
sleep 0.1
screen -S "Script_AIL" -X screen -t "Bitcoin" bash -c './Bitcoin.py; read x' screen -S "Script_AIL" -X screen -t "Bitcoin" bash -c './Bitcoin.py; read x'
sleep 0.1 sleep 0.1
screen -S "Script_AIL" -X screen -t "Phone" bash -c './Phone.py; read x' screen -S "Script_AIL" -X screen -t "Phone" bash -c './Phone.py; read x'
@ -160,6 +164,8 @@ function launching_scripts {
sleep 0.1 sleep 0.1
screen -S "Script_AIL" -X screen -t "alertHandler" bash -c './alertHandler.py; read x' screen -S "Script_AIL" -X screen -t "alertHandler" bash -c './alertHandler.py; read x'
sleep 0.1 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' screen -S "Script_AIL" -X screen -t "SentimentAnalysis" bash -c './SentimentAnalysis.py; read x'
} }

View file

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

View file

@ -152,6 +152,9 @@ if __name__ == "__main__":
for url in fetch(p, r_cache, urls, domains_list, path): for url in fetch(p, r_cache, urls, domains_list, path):
publisher.info('{}Checked {};{}'.format(to_print, url, PST.p_path)) publisher.info('{}Checked {};{}'.format(to_print, url, PST.p_path))
p.populate_set_out('onion;{}'.format(PST.p_path), 'alertHandler') 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: else:
publisher.info('{}Onion related;{}'.format(to_print, PST.p_path)) publisher.info('{}Onion related;{}'.format(to_print, PST.p_path))

View file

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

View file

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

68
bin/Tags.py Executable file
View file

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

View file

@ -0,0 +1,150 @@
#!/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
import json
import Paste
# ============ 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
Tags = Blueprint('Tags', __name__, template_folder='templates')
# ============ FUNCTIONS ============
def one():
return 1
# ============= 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 = []
id = 0
for tag in all_tags:
list_tags.append( tag )
id += 1
return jsonify(list_tags)
@Tags.route("/Tags/get_tagged_paste")
def get_tagged_paste():
tags = request.args.get('ltags')[1:-1]
tags = tags.replace('\\','')
list_tags = tags.split(',')
tmp_list_tags = []
# remove " char
for tag in list_tags:
tmp_list_tags.append(tag[1:-1])
list_tags = tmp_list_tags
# 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'
#currentSelectYear = int(datetime.now().year)
currentSelectYear = 2018
bootstrap_label = []
bootstrap_label.append('primary')
bootstrap_label.append('success')
bootstrap_label.append('danger')
bootstrap_label.append('warning')
bootstrap_label.append('info')
bootstrap_label.append('dark')
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)
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)
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,
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)
return 'OK'
@Tags.route("/Tags/res")
def get_tagged_paste_res():
return render_template("res.html")
# ========= REGISTRATION =========
app.register_blueprint(Tags)

View file

@ -0,0 +1,78 @@
<!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 -->
<form action="/Tags/get_tagged_paste">
<div class="form-group input-group" >
<input id="ltags" style="width:100%;" type="text" name="ltags">
<div class="input-group-btn">
<button type="submit" class="btn btn-search btn-primary btn-tags">
<span class="glyphicon glyphicon-search"></span>
<span class="label-icon">Search</span>
</button>
</div>
</div>
</form>
<button type="button" class="btn btn-primary" style="margin-bottom: 30px;" data-target="#filter-panel">
<span class="glyphicon glyphicon-cog "></span> Advanced Search
</button>
</div>
<!-- /#page-wrapper -->
<script>
$(document).ready(function(){
$.getJSON('/Tags/get_all_tags',
function(data) {
//console.log(data)
//for(var i=0;i<data.length;i++) jsonData.push({id:i,name:data[i]});
var ltags = $('#ltags').tagSuggest({
data: data,
sortOrder: 'name',
maxDropHeight: 200,
name: 'ltags'
});
});
});
</script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
</body>
</html>

View file

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

View file

@ -0,0 +1,285 @@
<!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 -->
<form action="/Tags/get_tagged_paste">
<div class="form-group input-group" >
<input id="ltags" style="width:100%;" type="text" name="ltags">
<div class="input-group-btn">
<button type="submit" class="btn btn-search btn-primary btn-tags">
<span class="glyphicon glyphicon-search"></span>
<span class="label-icon">Search</span>
</button>
</div>
</div>
</form>
<button type="button" class="btn btn-primary" style="margin-bottom: 30px;" data-target="#filter-panel">
<span class="glyphicon glyphicon-cog "></span> Advanced Search
</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] %}
<span class="label label-{{ bootstrap_label[loop.index0 % 6] }} pull-left">{{ tag }}</span>
{% 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>
</body>
<script>
var search_table;
var last_clicked_paste;
var can_change_modal_content = true;
$("#myTable_").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));
});
search_table = $('#myTable_').DataTable({ "order": [[ 2, "desc" ]] });
$("#load_more_json_button1").hide();
$("#load_more_json_button2").hide();
$("#nbr_entry").hide();
$("#loading_gif_browse").hide();
/*$('#myTable_').DataTable(
{
"aLengthMenu": [[5, 10, 25, -1], [5, 10, 25, "All"]],
"iDisplayLength": 10
}
);*/
$.getJSON('/Tags/get_all_tags',
function(data) {
//console.log(data)
//for(var i=0;i<data.length;i++) jsonData.push({id:i,name:data[i]});
//var slct_tags = String({{ original_tag }})
var ltags = $('#ltags').tagSuggest({
data: data,
//value: slct_tags,
sortOrder: 'name',
maxDropHeight: 200,
name: 'ltags'
});
});
});
</script>
<!-- Dynamically update the modal -->
<script type="text/javascript">
// static data
var alert_message = '<div class="alert alert-info alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><strong>No more data.</strong> Full paste displayed.</div>';
var complete_paste = null;
var char_to_display = {{ char_to_display }};
var start_index = 0;
// When the modal goes out, refresh it to normal content
$("#mymodal").on('hidden.bs.modal', function () {
can_change_modal_content = true;
$("#mymodalbody").html("<p>Loading paste information...</p>");
var loading_gif = "<img id='loading-gif-modal' class='img-center' src=\"{{url_for('static', filename='image/loading.gif') }}\" height='26' width='26' style='margin: 4px;'>";
$("#mymodalbody").append(loading_gif); // Show the loading GIF
$("#button_show_path").attr('href', '');
$("#button_show_path").hide();
complete_paste = null;
start_index = 0;
});
// Update the paste preview in the modal
function update_preview() {
if (start_index + char_to_display > complete_paste.length-1){ // end of paste reached
var final_index = complete_paste.length-1;
var flag_stop = true;
} else {
var final_index = start_index + char_to_display;
}
if (final_index != start_index){ // still have data to display
// Append the new content using text() and not append (XSS)
$("#mymodalbody").find("#paste-holder").text($("#mymodalbody").find("#paste-holder").text()+complete_paste.substring(start_index+1, final_index+1));
start_index = final_index;
if (flag_stop)
nothing_to_display();
} else {
nothing_to_display();
}
}
// Update the modal when there is no more data
function nothing_to_display() {
var new_content = $(alert_message).hide();
$("#mymodalbody").find("#panel-body").append(new_content);
new_content.show('fast');
$("#load-more-button").hide();
}
function get_html_and_update_modal(event, truemodal) {
event.preventDefault();
var modal=truemodal;
var url = " {{ url_for('showsavedpastes.showpreviewpaste') }}?paste=" + modal.attr('data-path') + "&num=" + modal.attr('data-num');
last_clicked_paste = modal.attr('data-num');
$.get(url, function (data) {
// verify that the reveived data is really the current clicked paste. Otherwise, ignore it.
var received_num = parseInt(data.split("|num|")[1]);
if (received_num == last_clicked_paste && can_change_modal_content) {
can_change_modal_content = false;
// clear data by removing html, body, head tags. prevent dark modal background stack bug.
var cleared_data = data.split("<body>")[1].split("</body>")[0];
$("#mymodalbody").html(cleared_data);
var button = $('<button type="button" id="load-more-button" class="btn btn-info btn-xs center-block" data-url="' + $(modal).attr('data-path') +'" data-toggle="tooltip" data-placement="bottom" title="Load more content"><span class="glyphicon glyphicon-download"></span></button>');
button.tooltip();
$("#mymodalbody").children(".panel-default").append(button);
$("#button_show_path").attr('href', $(modal).attr('data-url'));
$("#button_show_path").show('fast');
$("#loading-gif-modal").css("visibility", "hidden"); // Hide the loading GIF
if ($("[data-initsize]").attr('data-initsize') < char_to_display) { // All the content is displayed
nothing_to_display();
}
// On click, donwload all paste's content
$("#load-more-button").on("click", function (event) {
if (complete_paste == null) { //Donwload only once
$.get("{{ url_for('showsavedpastes.getmoredata') }}"+"?paste="+$(modal).attr('data-path'), function(data, status){
complete_paste = data;
update_preview();
});
} else {
update_preview();
}
});
} else if (can_change_modal_content) {
$("#mymodalbody").html("Ignoring previous not finished query of paste #" + received_num);
}
});
}
// Use to bind the button with the new displayed data
// (The bind do not happens if the dataTable is in tabs and the clicked data is in another page)
search_table.on( 'draw.dt', function () {
// Bind tooltip each time we draw a new page
$('[data-toggle="tooltip"]').tooltip();
// On click, get html content from url and update the corresponding modal
$("[data-toggle='modal']").off('click.openmodal').on("click.openmodal", function (event) {
get_html_and_update_modal(event, $(this));
});
} );
</script>

View file

@ -96,7 +96,17 @@ def showpaste(content_range):
if content_range != 0: if content_range != 0:
p_content = p_content[0:content_range] 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) bootstrap_label = []
bootstrap_label.append('primary')
bootstrap_label.append('success')
bootstrap_label.append('danger')
bootstrap_label.append('warning')
bootstrap_label.append('info')
bootstrap_label.append('dark')
list_tags = r_serv_metadata.smembers('tag:'+requested_path)
return render_template("show_saved_paste.html", date=p_date, bootstrap_label=bootstrap_label, 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 ============ # ============ ROUTES ============

View file

@ -21,7 +21,13 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h1 class="page-header" >Paste: {{ request.args.get('paste') }}</h1> <h1 class="page-header" >Paste: {{ request.args.get('paste') }}</h1>
<h2 class="page-header" >({{ request.args.get('num') }})</h2> <h2 class="page-header" >
<div>
{% for tag in list_tags %}
<span class="label label-{{ bootstrap_label[loop.index0 % 6] }} pull-left">{{ tag }}</span>
{% endfor %}
</div>
</h2>
<table class="table table-condensed"> <table class="table table-condensed">
<thead> <thead>