Merge ssh://github.com/web2py/web2py
This commit is contained in:
2
VERSION
2
VERSION
@@ -1 +1 @@
|
||||
Version 2.6.0-development+timestamp.2013.07.17.07.36.50
|
||||
Version 2.6.0-development+timestamp.2013.07.17.17.18.40
|
||||
|
||||
@@ -327,6 +327,89 @@ font-style: italic;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/*=============================================================
|
||||
EDIT PAGE SLIDING FILES MENU
|
||||
==============================================================*/
|
||||
@media (max-width: 979px) {
|
||||
body.edit div#header {position:relative; z-index: 1030 !important;}
|
||||
}
|
||||
|
||||
#editor_area, #edit_placeholder {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#editor_area {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#files {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: 1029;
|
||||
border-right: 3px solid #000;
|
||||
/* animation (it doesn't work in IE<10) */
|
||||
-moz-transition: all 0.4s;
|
||||
-webkit-transition: all 0.4s;
|
||||
-o-transition: all 0.4s;
|
||||
transition: all 0.4s;
|
||||
}
|
||||
|
||||
#files:hover, #files:focus {
|
||||
left: 0px !important;
|
||||
}
|
||||
|
||||
#files, .files-toggle {
|
||||
background: #1b1b1b;
|
||||
opacity: 0.98;
|
||||
}
|
||||
|
||||
.files-toggle {
|
||||
width: 18px;
|
||||
height: 86px;
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
right: -18px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
width: 18px;
|
||||
height: 70px;
|
||||
background: url(../images/files_toggle.png) no-repeat;
|
||||
}
|
||||
|
||||
.files-menu {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#filelist {
|
||||
position: relative;
|
||||
top: 60px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
#filelist li {
|
||||
padding-right: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#filelist li>a {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/*=============================================================
|
||||
MEDIA QUERIES
|
||||
==============================================================*/
|
||||
|
||||
BIN
applications/admin/static/images/files_toggle.png
Normal file
BIN
applications/admin/static/images/files_toggle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -121,7 +121,7 @@ jQuery(document).on('click', 'a.font_button', function (e) {
|
||||
case 'decr': new_incr = -2; break;
|
||||
case 'default': new_incr = 0; break;
|
||||
}
|
||||
jQuery('textarea[name="data"]') .each(function(id, ta) {
|
||||
jQuery('textarea[name="data"]').each(function(id, ta) {
|
||||
editor = jQuery(ta).data('editor');
|
||||
set_font(editor, new_incr);
|
||||
});
|
||||
@@ -163,9 +163,6 @@ jQuery(document).on('click', 'a.font_button', function (e) {
|
||||
|
||||
<div class='row-fluid'>
|
||||
<div class="right controls btn-toolbar pull-right">
|
||||
<div class="btn-group">
|
||||
<a class="button btn" onclick="jQuery('#files').toggle(); return false" href="#">Files toggle</a>
|
||||
</div>
|
||||
<div class="dropdown btn-group pull-left">
|
||||
<a class="dropdown-toggle button btn" data-target="themes" data-toggle="dropdown" href="#" >Theme: <span id="themeName" style="color: #E8953C">Web2py</span> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" id="themes">
|
||||
@@ -189,40 +186,51 @@ jQuery(document).on('click', 'a.font_button', function (e) {
|
||||
</div>
|
||||
</div>
|
||||
<div id="editor_area" class="row-fluid">
|
||||
<div id="files">
|
||||
<ul class="nav nav-list span2 well" rel="pagebookmark" id="filelist">
|
||||
<li><input type="text" placeholder="{{=T('Rapid Search')}}" class="input-block-level typeahead-tw search-query"></li>
|
||||
{{dirs=[{'name':'models', 'reg':'.*\.py$'},
|
||||
{'name':'controllers', 'reg':'.*\.py$'},
|
||||
{'name':'views', 'reg':'[\w/\-]+(\.\w+)+$'},
|
||||
{'name':'modules', 'reg':'.*\.py$'},
|
||||
{'name':'private', 'reg': '[^\.#].*'}]}}
|
||||
{{auto_complete_list=[]}}
|
||||
{{for dir in dirs:}}
|
||||
<li class="nav-header component" onclick="collapse('{{="%s_files" % dir['name']}}');">{{=dir['name']}}</li>
|
||||
<li id="{{="%s_files" % dir['name']}}">
|
||||
<ul class="nav nav-list small-font">
|
||||
{{for f in listfiles(app, dir['name'], regexp=dir['reg'] ):}}
|
||||
{{id="%s__" % dir['name'] + f.replace('.','__')}}
|
||||
{{current_file = request.args(len(request.args) - 1)}}
|
||||
<li class="{{#='active' if current_file==f else ''}}" style="overflow:hidden">
|
||||
{{a_tag=editfile(dir['name'], f, dict(id=id))}}
|
||||
{{=a_tag}}
|
||||
{{auto_complete_list.append({'value':f, 'tokens':f.split('/'), 'a_tag':a_tag})}}
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
<div id="files">
|
||||
<div class="files-toggle"><span class="arrow"></span></div>
|
||||
<div class="files-menu">
|
||||
<ul class="nav nav-list" rel="pagebookmark" id="filelist">
|
||||
<li><input type="text" placeholder="{{=T('Rapid Search')}}" class="input-block-level typeahead-tw search-query"></li>
|
||||
{{dirs=[{'name':'models', 'reg':'.*\.py$'},
|
||||
{'name':'controllers', 'reg':'.*\.py$'},
|
||||
{'name':'views', 'reg':'[\w/\-]+(\.\w+)+$'},
|
||||
{'name':'modules', 'reg':'.*\.py$'},
|
||||
{'name':'private', 'reg': '[^\.#].*'}]}}
|
||||
{{auto_complete_list=[]}}
|
||||
{{for dir in dirs:}}
|
||||
<li class="nav-header component" onclick="collapse('{{="%s_files" % dir['name']}}');">{{=dir['name']}}</li>
|
||||
<li id="{{="%s_files" % dir['name']}}">
|
||||
<ul class="nav nav-list small-font">
|
||||
{{for f in listfiles(app, dir['name'], regexp=dir['reg'] ):}}
|
||||
{{id="%s__" % dir['name'] + f.replace('.','__')}}
|
||||
{{current_file = request.args(len(request.args) - 1)}}
|
||||
<li class="{{#='active' if current_file==f else ''}}" style="overflow:hidden">
|
||||
{{a_tag=editfile(dir['name'], f, dict(id=id))}}
|
||||
{{=a_tag}}
|
||||
{{auto_complete_list.append({'value':f, 'tokens':f.split('/'), 'a_tag':a_tag})}}
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
</li>
|
||||
{{pass}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span10" id="edit_placeholder">
|
||||
<div class="span12" id="edit_placeholder">
|
||||
<ul class="nav nav-tabs " id="filesTab">
|
||||
</ul>
|
||||
<div id="myTabContent" class="tab-content">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(document).ready(function() {
|
||||
var filesMenu = jQuery('#files');
|
||||
var ow = filesMenu.outerWidth();
|
||||
filesMenu.width(ow);
|
||||
setTimeout( function(){jQuery('#files').css('left', '-'+ow+'px');}, 1000);
|
||||
});
|
||||
</script>
|
||||
<!-- Typeahead scripts here so the page load faster -->
|
||||
<script src="{{=URL('static/js', 'typeahead.min.js')}}"></script>
|
||||
<script src="{{=URL('static/js', 'hogan-2.0.0.js')}}"></script>
|
||||
|
||||
@@ -40,19 +40,12 @@
|
||||
:copyright: (c) Copyright 2011 by Armin Ronacher.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
#import hmac
|
||||
#import hashlib
|
||||
import hmac
|
||||
try:
|
||||
# Use PyCrypto (if available).
|
||||
from Crypto.Hash import HMAC as hmac, SHA as sha1
|
||||
from hashlib import sha1
|
||||
except ImportError:
|
||||
# PyCrypto not available. Use the Python standard library.
|
||||
import hmac
|
||||
try:
|
||||
from hashlib import sha1
|
||||
except ImportError:
|
||||
# hashlib not available. Use the old sha module.
|
||||
import sha as sha1
|
||||
# hashlib not available. Use the old sha module.
|
||||
import sha as sha1
|
||||
|
||||
from struct import Struct
|
||||
from operator import xor
|
||||
@@ -121,9 +114,8 @@ def test():
|
||||
check('pass\x00word', 'sa\x00lt', 4096, 16,
|
||||
'56fa6aa75548099dcc37d7f03425e0c3')
|
||||
# This one is from the RFC but it just takes for ages
|
||||
##check('password', 'salt', 16777216, 20,
|
||||
## 'eefe3d61cd4da4e4e9945b3d6ba2158c2634e984')
|
||||
|
||||
check('password', 'salt', 16777216, 20,
|
||||
'eefe3d61cd4da4e4e9945b3d6ba2158c2634e984')
|
||||
# From Crypt-PBKDF2
|
||||
check('password', 'ATHENA.MIT.EDUraeburn', 1, 16,
|
||||
'cdedb5281bb2f801565a1122b2563515')
|
||||
|
||||
@@ -143,7 +143,6 @@ class MockTable(object):
|
||||
release_lock(self.r_server, key_lock, newid)
|
||||
return newid
|
||||
|
||||
|
||||
class MockQuery(object):
|
||||
"""a fake Query object that supports querying by id
|
||||
and listing all keys. No other operation is supported
|
||||
|
||||
@@ -498,7 +498,6 @@ class Session(Storage):
|
||||
masterapp=None,
|
||||
clear_session=False
|
||||
):
|
||||
|
||||
if request is None:
|
||||
request = current.request
|
||||
if response is None:
|
||||
@@ -576,13 +575,14 @@ class Session(Storage):
|
||||
if record_id == '0':
|
||||
raise Exception('record_id == 0')
|
||||
# Select from database
|
||||
row = db(table.id == record_id).select().first()
|
||||
row = db(table.id == record_id).select()
|
||||
row = row and row[0] or None
|
||||
# Make sure the session data exists in the database
|
||||
if not row or row.unique_key != unique_key:
|
||||
raise Exception('No record')
|
||||
|
||||
unique_key = web2py_uuid()
|
||||
row.update_record(unique_key=unique_key)
|
||||
db(table.id == record_id).update(unique_key=unique_key)
|
||||
response.session_id = '%s:%s' % (record_id, unique_key)
|
||||
response.session_db_table = table
|
||||
response.session_db_record_id = record_id
|
||||
|
||||
@@ -1794,7 +1794,7 @@ class Auth(object):
|
||||
guess = keys.get('email', 'anonymous').split('@')[0]
|
||||
keys['first_name'] = keys.get('username', guess)
|
||||
user_id = table_user.insert(**table_user._filter_fields(keys))
|
||||
user = table_user[user_id]
|
||||
user = table_user[user_id]
|
||||
print user
|
||||
if self.settings.create_user_groups:
|
||||
group_id = self.add_group(
|
||||
@@ -1856,11 +1856,14 @@ class Auth(object):
|
||||
delattr(user,'password')
|
||||
else:
|
||||
user = Row(user)
|
||||
for key,value in user.items():
|
||||
for key, value in user.items():
|
||||
if callable(value) or key=='password':
|
||||
delattr(user,key)
|
||||
sessdb = current.response.session_db_table and current.response.session_db_table._db or None
|
||||
current.session.renew(
|
||||
clear_session=not self.settings.keep_session_onlogin, db=self.db)
|
||||
clear_session=not self.settings.keep_session_onlogin,
|
||||
db=sessdb
|
||||
)
|
||||
current.session.auth = Storage(
|
||||
user = user,
|
||||
last_visit=current.request.now,
|
||||
@@ -2247,8 +2250,10 @@ class Auth(object):
|
||||
|
||||
current.session.auth = None
|
||||
current.session.flash = self.messages.logged_out
|
||||
sessdb = current.response.session_db_table and current.response.session_db_table._db or None
|
||||
current.session.renew(
|
||||
clear_session=not self.settings.keep_session_onlogout, db=self.db)
|
||||
clear_session=not self.settings.keep_session_onlogout,
|
||||
db=sessdb)
|
||||
if not next is None:
|
||||
redirect(next)
|
||||
|
||||
@@ -4913,7 +4918,7 @@ class Expose(object):
|
||||
def __init__(self, base=None, basename=None, extensions=None, allow_download=True):
|
||||
"""
|
||||
Usage:
|
||||
|
||||
|
||||
def static():
|
||||
return dict(files=Expose())
|
||||
|
||||
@@ -4995,7 +5000,7 @@ class Expose(object):
|
||||
return ''
|
||||
|
||||
def xml(self):
|
||||
return DIV(
|
||||
return DIV(
|
||||
H2(self.breadcrumbs(self.basename)),
|
||||
self.paragraph or '',
|
||||
self.table_folders(),
|
||||
@@ -5154,7 +5159,7 @@ class Wiki(object):
|
||||
db.wiki_tag.insert(name=tag, wiki_page=page.id)
|
||||
db.wiki_page._after_insert.append(update_tags_insert)
|
||||
db.wiki_page._after_update.append(update_tags_update)
|
||||
|
||||
|
||||
if (auth.user and
|
||||
check_credentials(current.request, gae_login=False) and
|
||||
not 'wiki_editor' in auth.user_groups.values()):
|
||||
|
||||
@@ -11,8 +11,8 @@ This file specifically includes utilities for security.
|
||||
|
||||
import threading
|
||||
import struct
|
||||
import hashlib
|
||||
import hmac
|
||||
#import hashlib
|
||||
#import hmac
|
||||
import uuid
|
||||
import random
|
||||
import time
|
||||
@@ -23,6 +23,7 @@ import logging
|
||||
import socket
|
||||
import base64
|
||||
import zlib
|
||||
from types import ModuleType
|
||||
|
||||
_struct_2_long_long = struct.Struct('=QQ')
|
||||
|
||||
@@ -33,21 +34,15 @@ if python_version == 2:
|
||||
else:
|
||||
import pickle
|
||||
|
||||
try:
|
||||
from Crypto.Hash import MD5 as md5, \
|
||||
SHA as sha1, \
|
||||
SHA224 as sha224, \
|
||||
SHA256 as sha256, \
|
||||
SHA384 as sha384, \
|
||||
SHA512 as sha512
|
||||
except ImportError:
|
||||
from hashlib import md5, sha1, sha224, sha256, sha384, sha512
|
||||
from hashlib import md5, sha1, sha224, sha256, sha384, sha512
|
||||
|
||||
try:
|
||||
from Crypto.Cipher import AES
|
||||
except ImportError:
|
||||
import contrib.aes as AES
|
||||
|
||||
import hmac
|
||||
|
||||
try:
|
||||
from contrib.pbkdf2 import pbkdf2_hex
|
||||
HAVE_PBKDF2 = True
|
||||
@@ -80,8 +75,7 @@ def compare(a, b):
|
||||
|
||||
def md5_hash(text):
|
||||
""" Generate a md5 hash with the given text """
|
||||
return md5.new(text).hexdigest()
|
||||
|
||||
return md5(text).hexdigest()
|
||||
|
||||
def simple_hash(text, key='', salt='', digest_alg='md5'):
|
||||
"""
|
||||
@@ -100,7 +94,7 @@ def simple_hash(text, key='', salt='', digest_alg='md5'):
|
||||
digest_alg = get_digest(digest_alg)
|
||||
h = hmac.new(key + salt, text, digest_alg)
|
||||
else: # compatible with third party systems
|
||||
h = hashlib.new(digest_alg)
|
||||
h = get_digest(digest_alg)()
|
||||
h.update(text + salt)
|
||||
return h.hexdigest()
|
||||
|
||||
@@ -143,7 +137,7 @@ def pad(s, n=32, padchar=' '):
|
||||
|
||||
def secure_dumps(data, encryption_key, hash_key=None, compression_level=None):
|
||||
if not hash_key:
|
||||
hash_key = hashlib.sha1(encryption_key).hexdigest()
|
||||
hash_key = sha1(encryption_key).hexdigest()
|
||||
dump = pickle.dumps(data)
|
||||
if compression_level:
|
||||
dump = zlib.compress(dump, compression_level)
|
||||
@@ -158,7 +152,7 @@ def secure_loads(data, encryption_key, hash_key=None, compression_level=None):
|
||||
if not ':' in data:
|
||||
return None
|
||||
if not hash_key:
|
||||
hash_key = hashlib.sha1(encryption_key).hexdigest()
|
||||
hash_key = sha1(encryption_key).hexdigest()
|
||||
signature, encrypted_data = data.split(':', 1)
|
||||
actual_signature = hmac.new(hash_key, encrypted_data).hexdigest()
|
||||
if not compare(signature, actual_signature):
|
||||
|
||||
Reference in New Issue
Block a user