Merge ssh://github.com/web2py/web2py

This commit is contained in:
Michele Comitini
2013-07-18 11:25:58 +02:00
9 changed files with 154 additions and 73 deletions

View File

@@ -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

View File

@@ -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
==============================================================*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -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>

View File

@@ -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')

View File

@@ -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

View File

@@ -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

View File

@@ -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()):

View File

@@ -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):