initial commit

This commit is contained in:
Massimo Di Pierro
2011-11-22 23:30:42 -06:00
commit d421c1321b
580 changed files with 115527 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
EXPIRATION = 60 * 60 # logout after 60 minutes of inactivity
CHECK_VERSION = True
WEB2PY_URL = 'http://web2py.com'
WEB2PY_VERSION_URL = WEB2PY_URL+'/examples/default/version'
###########################################################################
# Preferences for EditArea
# the user-interface feature that allows you to edit files in your web
# browser.
## Default editor
TEXT_EDITOR = 'edit_area' or 'amy'
### edit_area
# The default font size, measured in 'points'. The value must be an integer > 0
FONT_SIZE = 10
# Displays the editor in full screen mode. The value must be 'true' or 'false'
FULL_SCREEN = 'false'
# Display a check box under the editor to allow the user to switch
# between the editor and a simple
# HTML text area. The value must be 'true' or 'false'
ALLOW_TOGGLE = 'true'
# Replaces tab characters with space characters.
# The value can be 'false' (meaning that tabs are not replaced),
# or an integer > 0 that specifies the number of spaces to replace a tab with.
REPLACE_TAB_BY_SPACES = 4
# Toggle on/off the code editor instead of textarea on startup
DISPLAY = "onload" or "later"
# if demo mode is True then admin works readonly and does not require login
DEMO_MODE = False
# if visible_apps is not empty only listed apps will be accessible
FILTER_APPS = []
# To upload on google app engine this has to point to the proper appengine
# config file
import os
# extract google_appengine_x.x.x.zip to web2py root directory
#GAE_APPCFG = os.path.abspath(os.path.join('appcfg.py'))
# extract google_appengine_x.x.x.zip to applications/admin/private/
GAE_APPCFG = os.path.abspath(os.path.join('/usr/local/bin/appcfg.py'))
# To use web2py as a teaching tool, set MULTI_USER_MODE to True
MULTI_USER_MODE = False
# configurable twitterbox, set to None/False to suppress
TWITTER_HASH = "web2py"
# parameter for downloading LAYOUTS
LAYOUTS_APP = 'http://web2py.com/layouts'
#LAYOUTS_APP = 'http://127.0.0.1:8000/layouts'
# parameter for downloading PLUGINS
PLUGINS_APP = 'http://web2py.com/plugins'
#PLUGINS_APP = 'http://127.0.0.1:8000/plugins'
# set the language
if 'adminLanguage' in request.cookies and not (request.cookies['adminLanguage'] is None):
T.force(request.cookies['adminLanguage'].value)
+26
View File
@@ -0,0 +1,26 @@
import time
import os
import sys
import re
import urllib
import cgi
import difflib
import shutil
import stat
import socket
from textwrap import dedent
try:
from mercurial import ui, hg, cmdutil
have_mercurial = True
except ImportError:
have_mercurial = False
from gluon.utils import md5_hash
from gluon.fileutils import listdir, cleanpath, up
from gluon.fileutils import tar, tar_compiled, untar, fix_newlines
from gluon.languages import findT, update_all_languages
from gluon.myregex import *
from gluon.restricted import *
from gluon.compileapp import compile_application, remove_compiled_application
+146
View File
@@ -0,0 +1,146 @@
import os, time
from gluon import portalocker
from gluon.admin import apath
from gluon.fileutils import read_file
# ###########################################################
# ## make sure administrator is on localhost or https
# ###########################################################
http_host = request.env.http_host.split(':')[0]
if request.env.web2py_runtime_gae:
session_db = DAL('gae')
session.connect(request, response, db=session_db)
hosts = (http_host, )
if request.env.http_x_forwarded_for or request.is_https:
session.secure()
elif not request.is_local and not DEMO_MODE:
raise HTTP(200, T('Admin is disabled because insecure channel'))
try:
_config = {}
port = int(request.env.server_port or 0)
restricted(read_file(apath('../parameters_%i.py' % port, request)), _config)
if not 'password' in _config or not _config['password']:
raise HTTP(200, T('admin disabled because no admin password'))
except IOError:
import gluon.fileutils
if request.env.web2py_runtime_gae:
if gluon.fileutils.check_credentials(request):
session.authorized = True
session.last_time = time.time()
else:
raise HTTP(200,
T('admin disabled because not supported on google app engine'))
else:
raise HTTP(200, T('admin disabled because unable to access password file'))
def verify_password(password):
session.pam_user = None
if DEMO_MODE:
return True
elif not 'password' in _config:
return False
elif _config['password'].startswith('pam_user:'):
session.pam_user = _config['password'][9:].strip()
import gluon.contrib.pam
return gluon.contrib.pam.authenticate(session.pam_user,password)
else:
return _config['password'] == CRYPT()(password)[0]
# ###########################################################
# ## handle brute-force login attacks
# ###########################################################
deny_file = os.path.join(request.folder, 'private', 'hosts.deny')
allowed_number_of_attempts = 5
expiration_failed_logins = 3600
def read_hosts_deny():
import datetime
hosts = {}
if os.path.exists(deny_file):
hosts = {}
f = open(deny_file, 'r')
portalocker.lock(f, portalocker.LOCK_SH)
for line in f.readlines():
if not line.strip() or line.startswith('#'):
continue
fields = line.strip().split()
if len(fields) > 2:
hosts[fields[0].strip()] = ( # ip
int(fields[1].strip()), # n attemps
int(fields[2].strip()) # last attempts
)
portalocker.unlock(f)
f.close()
return hosts
def write_hosts_deny(denied_hosts):
f = open(deny_file, 'w')
portalocker.lock(f, portalocker.LOCK_EX)
for key, val in denied_hosts.items():
if time.time()-val[1] < expiration_failed_logins:
line = '%s %s %s\n' % (key, val[0], val[1])
f.write(line)
portalocker.unlock(f)
f.close()
def login_record(success=True):
denied_hosts = read_hosts_deny()
val = (0,0)
if success and request.client in denied_hosts:
del denied_hosts[request.client]
elif not success and not request.is_local:
val = denied_hosts.get(request.client,(0,0))
if time.time()-val[1]<expiration_failed_logins \
and val[0] >= allowed_number_of_attempts:
return val[0] # locked out
time.sleep(2**val[0])
val = (val[0]+1,int(time.time()))
denied_hosts[request.client] = val
write_hosts_deny(denied_hosts)
return val[0]
# ###########################################################
# ## session expiration
# ###########################################################
t0 = time.time()
if session.authorized:
if session.last_time and session.last_time < t0 - EXPIRATION:
session.flash = T('session expired')
session.authorized = False
else:
session.last_time = t0
if not session.authorized and not \
(request.controller == 'default' and \
request.function in ('index','user')):
if request.env.query_string:
query_string = '?' + request.env.query_string
else:
query_string = ''
if request.env.web2py_original_uri:
url = request.env.web2py_original_uri
else:
url = request.env.path_info + query_string
redirect(URL(request.application, 'default', 'index', vars=dict(send=url)))
elif session.authorized and \
request.controller == 'default' and \
request.function == 'index':
redirect(URL(request.application, 'default', 'site'))
if request.controller=='appadmin' and DEMO_MODE:
session.flash = 'Appadmin disabled in demo mode'
redirect(URL('default','sites'))
+23
View File
@@ -0,0 +1,23 @@
# Template helpers
import os
def button(href, label):
return A(SPAN(label),_class='button',_href=href)
def button_enable(href, app):
if os.path.exists(os.path.join(apath(app,r=request),'DISABLED')):
label = SPAN(T('Enable'),_style='color:red')
else:
label = SPAN(T('Disable'),_style='color:green')
id = 'enable_'+app
return A(label,_class='button',_id=id,callback=href,target=id)
def sp_button(href, label):
return A(SPAN(label),_class='button special',_href=href)
def helpicon():
return IMG(_src=URL('static', 'images/help.png'), _alt='help')
def searchbox(elementid):
return TAG[''](LABEL(IMG(_src=URL('static', 'images/search.png'), _alt=T('filter')), _class='icon', _for=elementid), ' ', INPUT(_id=elementid, _type='text', _size=12))
+40
View File
@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
# this file is released under public domain and you can use without limitations
if MULTI_USER_MODE:
db = DAL('sqlite://storage.sqlite') # if not, use SQLite or other DB
from gluon.tools import *
mail = Mail() # mailer
auth = Auth(globals(),db) # authentication/authorization
crud = Crud(globals(),db) # for CRUD helpers using auth
service = Service(globals()) # for json, xml, jsonrpc, xmlrpc, amfrpc
plugins = PluginManager()
mail.settings.server = 'logging' or 'smtp.gmail.com:587' # your SMTP server
mail.settings.sender = 'you@gmail.com' # your email
mail.settings.login = 'username:password' # your credentials or None
auth.settings.hmac_key = '<your secret key>' # before define_tables()
auth.define_tables() # creates all needed tables
auth.settings.mailer = mail # for user email verification
auth.settings.registration_requires_verification = False
auth.settings.registration_requires_approval = True
auth.messages.verify_email = 'Click on the link http://'+request.env.http_host+URL('default','user',args=['verify_email'])+'/%(key)s to verify your email'
auth.settings.reset_password_requires_verification = True
auth.messages.reset_password = 'Click on the link http://'+request.env.http_host+URL('default','user',args=['reset_password'])+'/%(key)s to reset your password'
db.define_table('app',Field('name'),Field('owner',db.auth_user))
if not session.authorized and MULTI_USER_MODE:
if auth.user and not request.function=='user':
session.authorized = True
elif not request.function=='user':
redirect(URL('default','user/login'))
def is_manager():
if not MULTI_USER_MODE:
return True
elif auth.user and auth.user.id==1:
return True
else:
return False
+33
View File
@@ -0,0 +1,33 @@
# ###########################################################
# ## generate menu
# ###########################################################
_a = request.application
_c = request.controller
_f = request.function
response.title = '%s %s' % (_f, '/'.join(request.args))
response.subtitle = 'admin'
response.menu = [(T('Site'), _f == 'site', URL(_a,'default','site'))]
if request.args:
_t = request.args[0]
response.menu.append((T('Edit'), _c == 'default' and _f == 'design',
URL(_a,'default','design',args=_t)))
response.menu.append((T('About'), _c == 'default' and _f == 'about',
URL(_a,'default','about',args=_t)))
response.menu.append((T('Errors'), _c == 'default' and _f == 'errors',
URL(_a,'default','errors',args=_t)))
response.menu.append((T('Versioning'),
_c == 'mercurial' and _f == 'commit',
URL(_a,'mercurial','commit',args=_t)))
if not session.authorized:
response.menu = [(T('Login'), True, '')]
else:
response.menu.append((T('Logout'), False,
URL(_a,'default',f='logout')))
if os.path.exists('applications/examples'):
response.menu.append((T('Help'), False, URL('examples','default','index')))
else:
response.menu.append((T('Help'), False, 'http://web2py.com/examples'))
@@ -0,0 +1,4 @@
response.files.append(URL('static','plugin_multiselect/jquery.dimensions.js'))
response.files.append(URL('static','plugin_multiselect/jquery.multiselect.js'))
response.files.append(URL('static','plugin_multiselect/jquery.multiselect.css'))
response.files.append(URL('static','plugin_multiselect/start.js'))