Compare commits

..
10 Commits
Author SHA1 Message Date
mdipierro 1abdf72a04 2.9.4 2014-03-04 22:42:22 -06:00
mdipierro 7c536b66d0 Merge branch 'master' of github.com:web2py/web2py 2014-03-04 22:40:00 -06:00
mdipierro cc1c019216 Merge pull request #387 from apa-1/master
Added 'from_address' to allow for separation of 'envelope sender' and 'f...
2014-03-04 22:39:40 -06:00
mdipierro d20f231b34 fixed memdb anc session issue 1885 2014-03-04 22:33:50 -06:00
mdipierro 8b03bf5fd9 fixed gae_memacache issue 1887, thanks mjwatson 2014-03-04 22:28:35 -06:00
alex af4025731a Added 'from_address' to allow for separation of 'envelope sender' and 'from' in email 2014-03-04 13:10:08 -05:00
mdipierro 77bbb405fb 2.9.3 2014-03-03 08:50:52 -06:00
mdipierro 7592cd2fe0 always reset the session when auth session expires 2014-03-03 08:44:02 -06:00
mdipierro c5b996c8b1 fixed problem with too many sessions 2014-03-03 08:14:36 -06:00
mdipierro ae0749d6b8 reverted some bs3 changes 2014-03-03 08:13:37 -06:00
10 changed files with 83 additions and 73 deletions
+3 -2
View File
@@ -1,8 +1,9 @@
## 2.9.1 ## 2.9.1 - 2.9.3
- jquery 1.11 - jquery 1.11
- codemirror 3.21, thanks Paolo Valleri - codemirror 3.21, thanks Paolo Valleri
- fixed a security issue with sessions in database - fixed security issue with sessions in database, thanks Nathan Humphreys
- fixed security issue with persistant data in session, thanks Kiran
- fixed security issue with redirect after expired login, thanks André Kablu - fixed security issue with redirect after expired login, thanks André Kablu
- cleaner DAL and rname integration, thanks niphlod and Michele - cleaner DAL and rname integration, thanks niphlod and Michele
- added mongodb and imap tests for dal, thanks Alan - added mongodb and imap tests for dal, thanks Alan
+1 -1
View File
@@ -30,7 +30,7 @@ update:
echo "remember that pymysql was tweaked" echo "remember that pymysql was tweaked"
src: src:
### Use semantic versioning ### Use semantic versioning
echo 'Version 2.9.2-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION echo 'Version 2.9.4-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
### rm -f all junk files ### rm -f all junk files
make clean make clean
### clean up baisc apps ### clean up baisc apps
+1 -1
View File
@@ -1 +1 @@
Version 2.9.2-stable+timestamp.2014.03.02.17.46.39 Version 2.9.4-stable+timestamp.2014.03.04.22.40.54
+2 -2
View File
@@ -75,8 +75,8 @@
* this over and over... all will be bound to the document * this over and over... all will be bound to the document
*/ */
/*adds btn class to buttons*/ /*adds btn class to buttons*/
$('button', target).addClass('btn').addClass('btn-default'); $('button', target).addClass('btn');
$('form input[type="submit"], form input[type="button"]', target).addClass('btn').addClass('btn-default'); $('form input[type="submit"], form input[type="button"]', target).addClass('btn');
/* javascript for PasswordWidget*/ /* javascript for PasswordWidget*/
$('input[type=password][data-w2p_entropy]', target).each(function () { $('input[type=password][data-w2p_entropy]', target).each(function () {
web2py.validate_entropy($(this)); web2py.validate_entropy($(this));
+2 -2
View File
@@ -75,8 +75,8 @@
* this over and over... all will be bound to the document * this over and over... all will be bound to the document
*/ */
/*adds btn class to buttons*/ /*adds btn class to buttons*/
$('button', target).addClass('btn').addClass('btn-default'); $('button', target).addClass('btn');
$('form input[type="submit"], form input[type="button"]', target).addClass('btn').addClass('btn-default'); $('form input[type="submit"], form input[type="button"]', target).addClass('btn');
/* javascript for PasswordWidget*/ /* javascript for PasswordWidget*/
$('input[type=password][data-w2p_entropy]', target).each(function () { $('input[type=password][data-w2p_entropy]', target).each(function () {
web2py.validate_entropy($(this)); web2py.validate_entropy($(this));
+35 -50
View File
@@ -1,50 +1,35 @@
{{left_sidebar_enabled,right_sidebar_enabled=False,('message' in globals())}} {{left_sidebar_enabled,right_sidebar_enabled=False,('message' in globals())}}
{{extend 'layout.html'}} {{extend 'layout.html'}}
{{block head}} {{if 'message' in globals():}}
<style> <h3>{{=message}}</h3>
#w2padmin-btn {margin:30px 0 30px 0;}
</style> <h4>{{=T('How did you get here?')}}</h4>
{{end head}} <ol>
<li>{{=T('You are successfully running web2py')}}</li>
{{if 'message' in globals():}} <li>{{=XML(T('You visited the url %s', A(request.env.path_info,_href=request.env.path_info)))}}</li>
<h2>{{=message}}</h2> <li>{{=XML(T('Which called the function %s located in the file %s',
<p class="lead">{{=T('How did you get here?')}}</p> (A(request.function+'()',_href='#'),
<ol> A('web2py/applications/%(application)s/controllers/%(controller)s.py'%request,
<li>{{=T('You are successfully running web2py')}}</li> _href=URL('admin','default','peek', args=(request.application,'controllers',request.controller+'.py'))))))}}</li>
<li>{{=XML(T('You visited the url %s', A(request.env.path_info,_href=request.env.path_info)))}}</li> <li>{{=XML(T('The output of the file is a dictionary that was rendered by the view %s',
<li>{{=XML(T('Which called the function %s located in the file %s', A('web2py/applications/%(application)s/views/%(controller)s/index.html'%request,
(A(request.function+'()',_href='#'), _href=URL('admin','default','peek',args=(request.application,'views',request.controller,'index.html')))))}}</li>
A('web2py/applications/%(application)s/controllers/%(controller)s.py'%request, <li>{{=T('You can modify this application and adapt it to your needs')}}</li>
_href=URL('admin','default','peek', args=(request.application,'controllers',request.controller+'.py'))))))}}</li> </ol>
<li>{{=XML(T('The output of the file is a dictionary that was rendered by the view %s', {{elif 'content' in globals():}}
A('web2py/applications/%(application)s/views/%(controller)s/index.html'%request, {{=content}}
_href=URL('admin','default','peek',args=(request.application,'views',request.controller,'index.html')))))}}</li> {{else:}}
<li>{{=T('You can modify this application and adapt it to your needs')}}</li> {{=BEAUTIFY(response._vars)}}
</ol> {{pass}}
{{elif 'content' in globals():}}
{{=content}} {{block right_sidebar}}
{{else:}} {{=A(T("Administrative Interface"), _href=URL('admin','default','index'), _class='btn',
{{=BEAUTIFY(response._vars)}} _style='margin-top: 1em;')}}
{{pass}} <h6>{{=T("Don't know what to do?")}}</h6>
<ul>
{{block right_sidebar}} <li>{{=A(T("Online examples"), _href=URL('examples','default','index'))}}</li>
<button id="w2padmin-btn" class="btn btn-primary btn-lg btn-block"> <li><a href="http://web2py.com">web2py.com</a></li>
<i class="glyphicon glyphicon-cog"></i> {{=T("Administrative Interface")}}</button> <li><a href="http://web2py.com/book">{{=T('Documentation')}}</a></li>
<div class="panel panel-info"> </ul>
<div class="panel-heading">{{=T("Don't know what to do?")}}</div> {{end}}
<ul class="list-group">
<li class="list-group-item">{{=A(T("Online examples"), _href=URL('examples','default','index'))}}</li>
<li class="list-group-item"><a href="http://web2py.com">web2py.com</a></li>
<li class="list-group-item"><a href="http://web2py.com/book">{{=T('Documentation')}}</a></li>
</ul>
</div>
{{end}}
{{block page_js}}
<script>
$('#w2padmin-btn').click(function() {
window.location = "{{=URL('admin','default','index')}}";
});
</script>
{{end}}
+6 -2
View File
@@ -17,15 +17,19 @@ class MemcacheClient(object):
client = Client() client = Client()
def __init__(self, request): def __init__(self, request, default_time_expire = 300):
self.request = request self.request = request
self.default_time_expire = default_time_expire
def __call__( def __call__(
self, self,
key, key,
f, f,
time_expire=300, time_expire=None,
): ):
if time_expire is None:
time_expire = self.default_time_expire
key = '%s/%s' % (self.request.application, key) key = '%s/%s' % (self.request.application, key)
value = None value = None
obj = self.client.get(key) obj = self.client.get(key)
+5 -2
View File
@@ -292,8 +292,11 @@ class Table(DALStorage):
def __str__(self): def __str__(self):
return self._tablename return self._tablename
def __call__(self, id): def __call__(self, id, **kwargs):
return self.get(id) record = self.get(id)
if kwargs and any(record[key]!=kwargs[key] for key in kwargs):
return None
return record
class Expression(object): class Expression(object):
+1
View File
@@ -887,6 +887,7 @@ class Session(Storage):
# Unpickle the data # Unpickle the data
session_data = cPickle.loads(row.session_data) session_data = cPickle.loads(row.session_data)
self.update(session_data) self.update(session_data)
response.session_new = False
else: else:
record_id = None record_id = None
if record_id: if record_id:
+27 -11
View File
@@ -278,7 +278,8 @@ class Mail(object):
sender=None, sender=None,
encoding='utf-8', encoding='utf-8',
raw=False, raw=False,
headers={} headers={},
from_address=None
): ):
""" """
Sends an email using data specified in constructor Sends an email using data specified in constructor
@@ -308,8 +309,9 @@ class Mail(object):
encoding: encoding of all strings passed to this method (including encoding: encoding of all strings passed to this method (including
message bodies) message bodies)
headers: dictionary of headers to refine the headers just before headers: dictionary of headers to refine the headers just before
sending mail, e.g. {'Return-Path' : 'bounces@example.org'} sending mail, e.g. {'X-Mailer' : 'web2py mailer'}
from_address: address to appear in the 'From:' header, this is not the
envelope sender. If not specified the sender will be used
Examples: Examples:
#Send plain text message to single address: #Send plain text message to single address:
@@ -655,7 +657,10 @@ class Mail(object):
# no cryptography process as usual # no cryptography process as usual
payload = payload_in payload = payload_in
payload['From'] = encoded_or_raw(sender.decode(encoding)) if from_address:
payload['From'] = encoded_or_raw(from_address.decode(encoding))
else:
payload['From'] = encoded_or_raw(sender.decode(encoding))
origTo = to[:] origTo = to[:]
if to: if to:
payload['To'] = encoded_or_raw(', '.join(to).decode(encoding)) payload['To'] = encoded_or_raw(', '.join(to).decode(encoding))
@@ -1153,16 +1158,27 @@ class Auth(object):
self.user_groups = auth and auth.user_groups or {} self.user_groups = auth and auth.user_groups or {}
if secure: if secure:
request.requires_https() request.requires_https()
if auth and auth.last_visit and auth.last_visit + \ now = request.now
datetime.timedelta(days=0, seconds=auth.expiration) > request.now: # if we have auth info
self.user = auth.user # if not expired it, used it
# this is a trick to speed up sessions # if expired, clear the session
if (request.now - auth.last_visit).seconds > (auth.expiration / 10): # else, only clear auth info in the session
auth.last_visit = request.now if auth:
delta = datetime.timedelta(days=0, seconds=auth.expiration)
if auth.last_visit and auth.last_visit + delta > now:
self.user = auth.user
# this is a trick to speed up sessions to avoid many writes
if (now - auth.last_visit).seconds > (auth.expiration / 10):
auth.last_visit = request.now
else:
self.user = None
if session.auth:
del session.auth
session.renew(clear_session=True)
else: else:
self.user = None self.user = None
if session.auth: if session.auth:
del session.auth del session.auth
# ## what happens after login? # ## what happens after login?
url_index = URL(controller, 'index') url_index = URL(controller, 'index')