Compare commits

...

6 Commits

Author SHA1 Message Date
mdipierro
4599dcd988 R-2.3.2 2012-12-17 09:00:46 -06:00
mdipierro
14bdfd3321 fixed issue 1227, entropy check with IS_STRONG, thanks Clavin Sim 2012-12-17 08:50:08 -06:00
mdipierro
e7d14c028b fixed issue 1225, NEWINSTALL ignored 2012-12-17 08:46:33 -06:00
mdipierro
0207a17afa cursor point in share.js, issue 1123, thanks Nathan 2012-12-16 12:36:28 -06:00
mdipierro
73b049f361 added oneall login support, issue 1124, thanks Nathan 2012-12-16 12:34:08 -06:00
mdipierro
5695fe34f0 fixed example in examples from pull-request, thanks tpng 2012-12-14 14:28:31 -06:00
9 changed files with 129 additions and 16 deletions

View File

@@ -1,4 +1,4 @@
## 2.3.1
## 2.3.1 - 2.3.2
- new virtual fields syntax:
``db.define_table('person',Field('name'),Field.Virtual('namey',lambda row: row.person.name+'y'))``

View File

@@ -29,7 +29,7 @@ update:
wget -O gluon/contrib/simplejsonrpc.py http://rad2py.googlecode.com/hg/ide2py/simplejsonrpc.py
echo "remember that pymysql was tweaked"
src:
echo 'Version 2.3.1 ('`date +%Y-%m-%d\ %H:%M:%S`') stable' > VERSION
echo 'Version 2.3.2 ('`date +%Y-%m-%d\ %H:%M:%S`') stable' > VERSION
### rm -f all junk files
make clean
### clean up baisc apps

View File

@@ -1 +1 @@
Version 2.3.1 (2012-12-14 09:21:31) stable
Version 2.3.2 (2012-12-17 08:59:58) stable

View File

@@ -1,3 +1,4 @@
def hello1():
""" simple page without template """
@@ -99,7 +100,7 @@ def rss_aggregator():
pubDate=datetime.datetime.now()) for entry in
d.entries])
response.headers['Content-Type'] = 'application/rss+xml'
return rss2.dumps(rss)
return rss.to_xml(encoding='utf-8')
def ajaxwiki():

View File

@@ -27,7 +27,7 @@ jQuery(function(){
jQuery('body').append(tbar);
var st = jQuery('#socialdrawer');
st.css({'opacity':'.7','z-index':'3000','background':'#FFF','border':'solid 1px #666','border-width':' 1px 0 0 1px','height':'20px','width':'40px','position':'fixed','bottom':'0','right':'0','padding':'2px 5px','overflow':'hidden','-webkit-border-top-left-radius':' 12px','-moz-border-radius-topleft':' 12px','border-top-left-radius':' 12px','-moz-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','-webkit-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)'});
jQuery('#socialdrawer a').css({'float':'left','width':'32px','margin':'3px 2px 2px 2px','padding':'0'});
jQuery('#socialdrawer a').css({'float':'left','width':'32px','margin':'3px 2px 2px 2px','padding':'0','cursor':'pointer'});
jQuery('#socialdrawer span').css({'float':'left','margin':'2px 3px','text-shadow':' 1px 1px 1px #FFF','color':'#444','font-size':'12px','line-height':'1em'});
jQuery('#socialdrawer img').hide();
// hover

View File

@@ -0,0 +1,107 @@
#!/usr/bin/env python
# coding: utf8
"""
Oneall Authentication for web2py
Developed by Nathan Freeze (Copyright © 2013)
Email <nathan@freezable.com>
This file contains code to allow using onall.com
authentication services with web2py
"""
import os
import base64
from gluon import *
from gluon.storage import Storage
from gluon.contrib.simplejson import JSONDecodeError
from gluon.tools import fetch
import gluon.contrib.simplejson as json
class OneallAccount(object):
"""
from gluon.contrib.login_methods.oneall_account import OneallAccount
auth.settings.actions_disabled=['register','change_password',
'request_reset_password']
auth.settings.login_form = OneallAccount(request,
public_key="...",
private_key="...",
domain="...",
url = "http://localhost:8000/%s/default/user/login" % request.application)
"""
def __init__(self, request, public_key="", private_key="", domain="",
url=None, providers=None, on_login_failure=None):
self.request = request
self.public_key = public_key
self.private_key = private_key
self.url = url
self.domain = domain
self.profile = None
self.on_login_failure = on_login_failure
self.providers = providers or ["facebook", "google", "yahoo", "openid"]
self.mappings = Storage()
def defaultmapping(profile):
name = profile.get('name',{})
dname = name.get('formatted',profile.get('displayName'))
email=profile.get('emails', [{}])[0].get('value')
reg_id=profile.get('identity_token','')
username=profile.get('preferredUsername',email)
first_name=name.get('givenName', dname.split(' ')[0])
last_name=profile.get('familyName',dname.split(' ')[1])
return dict(registration_id=reg_id,username=username,email=email,
first_name=first_name,last_name=last_name)
self.mappings.default = defaultmapping
def get_user(self):
request = self.request
user = None
if request.vars.connection_token:
auth_url = "https://%s.api.oneall.com/connections/%s.json" % \
(self.domain, request.vars.connection_token)
auth_pw = "%s:%s" % (self.public_key,self.private_key)
auth_pw = base64.b64encode(auth_pw)
headers = dict(Authorization="Basic %s" % auth_pw)
try:
auth_info_json = fetch(auth_url,headers=headers)
auth_info = json.loads(auth_info_json)
data = auth_info['response']['result']['data']
if data['plugin']['key'] == 'social_login':
if data['plugin']['data']['status'] == 'success':
userdata = data['user']
self.profile = userdata['identity']
source = self.profile['source']['key']
mapping = self.mappings.get(source,self.mappings['default'])
user = mapping(self.profile)
except (JSONDecodeError, KeyError):
pass
if user is None and self.on_login_failure:
redirect(self.on_login_failure)
return user
def login_form(self):
scheme = self.request.env.wsgi_url_scheme
oneall_url = scheme + "://%s.api.oneall.com/socialize/library.js" % self.domain
oneall_lib = SCRIPT(_src=oneall_url,_type='text/javascript')
container = DIV(_id="oa_social_login_container")
widget = SCRIPT('oneall.api.plugins.social_login.build("oa_social_login_container",',
'{providers : %s,' % self.providers,
'callback_uri: "%s"});' % self.url,
_type="text/javascript")
form = DIV(oneall_lib,container,widget)
return form
def use_oneall(auth, filename='private/oneall.key', **kwargs):
path = os.path.join(current.request.folder, filename)
if os.path.exists(path):
request = current.request
domain, public_key, private_key = open(path, 'r').read().strip().split(':')
url = URL('default', 'user', args='login', scheme=True)
auth.settings.actions_disabled =\
['register', 'change_password', 'request_reset_password']
auth.settings.login_form = OneallAccount(
request, public_key=public_key,private_key=private_key,
domain=domain, url=url, **kwargs)

View File

@@ -15,6 +15,7 @@ import tarfile
import glob
import time
import datetime
import logging
from http import HTTP
from gzip import open as gzopen
@@ -240,19 +241,20 @@ def w2p_pack(filename, path, compiled=False):
tarfp.close()
os.unlink(tarname)
def w2p_unpack(filename, path, delete_tar=True):
if filename=='welcome.w2p' and (
not os.path.exists('welcome.w2p') or \
os.path.exists('NEWINSTALL')):
def create_welcome_w2p():
if not os.path.exists('welcome.w2p') or os.path.exists('NEWINSTALL'):
try:
w2p_pack('welcome.w2p', 'applications/welcome')
os.unlink('NEWINSTALL')
logging.info("New installation: created welcome.w2p file")
except:
msg = "New installation: unable to create welcome.w2p file"
sys.stderr.write(msg)
logging.error("New installation error: unable to create welcome.w2p file")
def w2p_unpack(filename, path, delete_tar=True):
if filename=='welcome.w2p':
create_welcome_w2p()
filename = abspath(filename)
path = abspath(path)
if filename[-4:] == '.w2p' or filename[-3:] == '.gz':

View File

@@ -468,8 +468,9 @@ class PasswordWidget(FormWidget):
requires = [requires]
is_strong = [r for r in requires if isinstance(r, IS_STRONG)]
if is_strong:
output.append(SCRIPT("web2py_validate_entropy(jQuery('#%s'),%s);"
% (attr['_id'], is_strong[0].entropy)))
output.append(SCRIPT("web2py_validate_entropy(jQuery('#%s'),%s);" % (
attr['_id'], is_strong[0].entropy
if is_strong[0].entropy else "null")))
# end entropy check
return output

View File

@@ -25,7 +25,7 @@ import newcron
import getpass
import main
from fileutils import w2p_pack, read_file, write_file
from fileutils import w2p_pack, read_file, write_file, create_welcome_w2p
from settings import global_settings
from shell import run, test
from utils import is_valid_ip_address, is_loopback_ip_address
@@ -969,6 +969,8 @@ def console():
if options.numthreads is not None and options.minthreads is None:
options.minthreads = options.numthreads # legacy
create_welcome_w2p()
if not options.cronjob:
# If we have the applications package or if we should upgrade
if not os.path.exists('applications/__init__.py'):