Rahul Let's try this a different way.
Attached is a simple multi-tenant app with one table. Does this do what you need? 1. Create a new project in web2py 2. Replace db.py in your models dir with this one 3. Replace default.py in your controllers dir with this one 4. Replace index.html in views/default with this one 5. Add notes.html to views/default 6. Replace storage.sqlite in your databases dir with this one Depending on your version of web2py this should all work. I've created 2 logins elvis - password is password blueeyes - password is password Click on the notes link logged in as each of them and you'll see different notes show up based on the common filter. -Jim On Sat, Oct 27, 2018 at 12:52 PM Rahul <[email protected]> wrote: > Hi Dave and Jim, > Please find the files in the zipped archive. I have added > default.py, db.py, index.html and also layout file which I am converting to > use with web2py. called ace.html. I have also attached the views\login.html > file since I am extending this file specifically for login form as it is > different than layout file. Let me know. Thanks! > > > Regards, > > Rahul > > On Friday, October 26, 2018 at 5:11:12 PM UTC+5:30, Jim S wrote: >> >> Can you show the entire db.py, default py and index.html? >> >> Jim >> >> >> On Fri, Oct 26, 2018, 1:44 AM Rahul <[email protected]> wrote: >> >>> Nope - doesnt help. I commented out all the user functions defined in >>> the controller and >>> >>> >>> # ---- User functions --- >>> '''def login(): return dict(form=auth.login()) >>> def register(): return dict(form=auth.register()) >>> def retrieve_password(): return dict(form=auth.reset_password()) >>> def logout(): return dict(form=auth.logout()) >>> def profile(): return dict(form=auth.profile()) >>> ''' >>> >>> I even decorated index - It does take me to the login screen but from >>> there nothing happens. It just wont log me in like it did before. Also, I >>> have two users in database but none work now. Again, register seems to >>> fail (It did work earlier) but now it doesnt. See screenshot of both >>> screens. Looks like I must be really doing something weird. If this wont >>> work by this Sunday. I may go back to my old style of coding and do it all >>> by myself. I've seriously lost 10 days reading and experimenting with Auth >>> to make it work . Not too much coded. >>> >>> @auth.requires_login() >>> def index(): >>> response.flash = T("Hello User") >>> #redirect(URL(r=request, c='default/user', f='login')) # Redirects >>> user to login page >>> return dict(message=T('Welcome to web2py!')) >>> >>> >>> >>> Thanks, >>> >>> Rahul >>> >>> >>> >>> On Thursday, October 25, 2018 at 6:02:45 PM UTC+5:30, Jim S wrote: >>>> >>>> Having the default user() functions is all you need. I'd try >>>> commenting out your 'user' functions. >>>> >>>> -Jim >>>> >>>> On Wednesday, October 24, 2018 at 10:59:45 PM UTC-5, Rahul wrote: >>>>> >>>>> Yes this is in default.py. Please excuse me for my bad code as I am >>>>> still experimenting with Auth and not totally familiar with the >>>>> implementation. Is this the right way that I am doing it? or only having >>>>> user() function is enough ? >>>>> >>>>> Thanks, Rahul >>>>> >>>>> On Wednesday, October 24, 2018 at 9:45:21 PM UTC+5:30, Jim S wrote: >>>>>> >>>>>> I'm confused. Is this code in your controller somewhere? >>>>>> >>>>>> # ---- User functions --- >>>>>> def login(): return dict(form=auth.login()) >>>>>> def register(): return dict(form=auth.register()) >>>>>> def retrieve_password(): return dict(form=auth.reset_password()) >>>>>> def logout(): return dict(form=auth.logout()) >>>>>> def profile(): return dict(form=auth.profile()) >>>>>> >>>>>> You shouldn't need it. To override the default login stuff I've just >>>>>> modified the one in default.py. >>>>>> >>>>>> -Jim >>>>>> >>>>>> >>>>>> >>>>>> On Tuesday, October 23, 2018 at 11:26:45 PM UTC-5, Rahul wrote: >>>>>>> >>>>>>> The user function remains as-is - No modifications done. >>>>>>> >>>>>>> def user(): >>>>>>> """ >>>>>>> exposes: >>>>>>> http://..../[app]/default/user/login >>>>>>> http://..../[app]/default/user/logout >>>>>>> http://..../[app]/default/user/register >>>>>>> http://..../[app]/default/user/profile >>>>>>> http://..../[app]/default/user/retrieve_password >>>>>>> http://..../[app]/default/user/change_password >>>>>>> http://..../[app]/default/user/bulk_register >>>>>>> use @auth.requires_login() >>>>>>> @auth.requires_membership('group name') >>>>>>> @auth.requires_permission('read','table name',record_id) >>>>>>> to decorate functions that need access control >>>>>>> also notice there is http://..../[app]/appadmin/manage/auth to >>>>>>> allow administrator to manage users >>>>>>> """ >>>>>>> return dict(form=auth()) >>>>>>> >>>>>>> I am using the specified functions to expose methods as below - >>>>>>> # ---- User functions --- >>>>>>> def login(): return dict(form=auth.login()) >>>>>>> def register(): return dict(form=auth.register()) >>>>>>> def retrieve_password(): return dict(form=auth.reset_password()) >>>>>>> def logout(): return dict(form=auth.logout()) >>>>>>> def profile(): return dict(form=auth.profile()) >>>>>>> >>>>>>> >>>>>>> >>>>>>> and the corresponding files reside in \views\ *not in* >>>>>>> \views\default - I am not sure if the application is even picking up >>>>>>> these >>>>>>> files. >>>>>>> >>>>>>> Note - I have extended the Auth (auth_user) table and added >>>>>>> workspace and other fields - This will be specified everytime I add a >>>>>>> new >>>>>>> user. I would filter out the results as you mentioned but only after all >>>>>>> the login stuff works properly. >>>>>>> >>>>>>> auth.settings.extra_fields['auth_user'] = [ >>>>>>> Field ('workspace', length=128), >>>>>>> >>>>>>> Sincerely, >>>>>>> >>>>>>> Rahul >>>>>>> >>>>>>> On Tuesday, October 23, 2018 at 7:49:48 PM UTC+5:30, Jim S wrote: >>>>>>>> >>>>>>>> Did you modify the user() function in default.py? Or, are you >>>>>>>> using your own custom login functions? >>>>>>>> >>>>>>>> -Jim >>>>>>>> >>>>>>>> On Tuesday, October 23, 2018 at 7:59:21 AM UTC-5, Rahul wrote: >>>>>>>>> >>>>>>>>> Hi Jim, All, >>>>>>>>> Okay I tried this - And I also decorated index() function >>>>>>>>> in controller like below as I want to redirect the user to login page >>>>>>>>> rather than directly jumping to index.html >>>>>>>>> >>>>>>>>> # ---- example index page ---- >>>>>>>>> @auth.requires_login() >>>>>>>>> def index(): >>>>>>>>> response.flash= T("Hello World") >>>>>>>>> return dict(message=T('Welcome to web2py!')) >>>>>>>>> >>>>>>>>> However, now when I put the credentials username and password, it >>>>>>>>> doesnt log me in - I generates the below URL like below and appends >>>>>>>>> it to >>>>>>>>> url box. What might I be missing because it was logging me in fine >>>>>>>>> sometime >>>>>>>>> ago but now it doesnt allow. Note I did cleanup a lot of HTML code >>>>>>>>> from my >>>>>>>>> login page. There sure is something going on here that I am not >>>>>>>>> catching - >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> http:// >>>>>>>>> 127.0.0.1:8000/scaffolding_app/default/user/login?username=rahul&password=integer10&_next=%2Fscaffolding_ace_admin%2Fdefault%2Findex&_formkey=0c0c022a-377d-47dd-bd72-a13e8ee6f387&_formname=login >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> Sincerely, Rahul D. >>>>>>>>> >>>>>>>>> >>>>>>>>> On Friday, October 19, 2018 at 12:24:19 PM UTC+5:30, Rahul wrote: >>>>>>>>>> >>>>>>>>>> Hi Jim, >>>>>>>>>> That makes sense. I will check it out on which option to >>>>>>>>>> go. Thanks! for all the guidance. >>>>>>>>>> >>>>>>>>>> Thank you, >>>>>>>>>> >>>>>>>>>> *Rahul Dhakate* >>>>>>>>>> >>>>>>>>>> On Wednesday, October 17, 2018 at 7:57:32 PM UTC+5:30, Jim S >>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> Rahul >>>>>>>>>>> >>>>>>>>>>> First, what I was referring to was common_filters, not common >>>>>>>>>>> fields. Here is the scenario as I see it. >>>>>>>>>>> >>>>>>>>>>> In you auth_user table you have a workspace field. Then in >>>>>>>>>>> other tables that are workspace-specific you also have a workspace >>>>>>>>>>> field to >>>>>>>>>>> show which workspace they relate to >>>>>>>>>>> >>>>>>>>>>> Here is how I think I would handle it, assuming I am >>>>>>>>>>> understanding your need. And, assuming that the workspace >>>>>>>>>>> identifier is >>>>>>>>>>> stored on the user record. You wouldn't gather it on the login >>>>>>>>>>> page. >>>>>>>>>>> >>>>>>>>>>> In db.py I'd have code that would check to see if the user is >>>>>>>>>>> logged in. If so, then set the common filters for the >>>>>>>>>>> workspace-specific >>>>>>>>>>> tables >>>>>>>>>>> >>>>>>>>>>> if auth.is_logged_in: >>>>>>>>>>>> db.related_table_1._common_filter = lambda query: >>>>>>>>>>>> db.related_table_1.workspace = auth.user.workspace >>>>>>>>>>>> db.related_table_2._common_filter = lambda query: >>>>>>>>>>>> db.related_table_2.workspace = auth.user.workspace >>>>>>>>>>>> db.related_table_3._common_filter = lambda query: >>>>>>>>>>>> db.related_table_3.workspace = auth.user.workspace >>>>>>>>>>>> db.related_table_4._common_filter = lambda query: >>>>>>>>>>>> db.related_table_4.workspace = auth.user.workspace >>>>>>>>>>>> ...etc... >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Make sense? >>>>>>>>>>> >>>>>>>>>>> Anyone else out there that's done this and can show a better >>>>>>>>>>> way? >>>>>>>>>>> >>>>>>>>>>> -Jim >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> NOTE - you might also skip the common filters if you're logging >>>>>>>>>>> in as an admin. Then you might want to see data for all workspaces >>>>>>>>>>> >>>>>>>>>>> NOTE 2 - If you really want people to specify their workspace >>>>>>>>>>> when they login (meaning they have access to all of them but they >>>>>>>>>>> choose >>>>>>>>>>> which one on login) then you'd have to override the default login >>>>>>>>>>> code to >>>>>>>>>>> gather that extra variable and store it in your session somewhere. >>>>>>>>>>> Then >>>>>>>>>>> use that instead of auth.user.workspace when building your filters. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Wed, Oct 17, 2018 at 2:06 AM Rahul <[email protected]> >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi Jim, >>>>>>>>>>>> I am afraid no I didn't check that section but I just >>>>>>>>>>>> finished reading it. Thanks! for directing me to it. Looks like a >>>>>>>>>>>> new >>>>>>>>>>>> addition to DAL (might be a couple of versions back) & looks >>>>>>>>>>>> promising. So >>>>>>>>>>>> now, we can specify something like request_tenant using >>>>>>>>>>>> db._common_fields >>>>>>>>>>>> field parameter. >>>>>>>>>>>> >>>>>>>>>>>> I would need it for all tables so is there a specific syntax >>>>>>>>>>>> like below that I am required to specify in each table I create ? >>>>>>>>>>>> >>>>>>>>>>>> db._common_fields.append(Field('request_tenant', >>>>>>>>>>>> default=request.env.http_host, >>>>>>>>>>>> writable=False)) >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Also, can we set the default value to a field value that we can >>>>>>>>>>>> query or pass as a session variable like session.workspace == 'some >>>>>>>>>>>> workspace name' while the user logs in ? >>>>>>>>>>>> >>>>>>>>>>>> default=session.workspace, >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> If yes - what do I need to modify to add this additional field >>>>>>>>>>>> in Auth so it will be an input field for the user to key in the >>>>>>>>>>>> workspace >>>>>>>>>>>> name. Then I can store this workspace in session variable and use >>>>>>>>>>>> it. The >>>>>>>>>>>> reason is I want a group of users (accessing the same app and >>>>>>>>>>>> database from >>>>>>>>>>>> different locations) belonging to same workspace. This is how >>>>>>>>>>>> they are >>>>>>>>>>>> grouped. please see the screenshot posted from my actual >>>>>>>>>>>> application login. >>>>>>>>>>>> In it I use workspace name as well to validate but after reading >>>>>>>>>>>> the book >>>>>>>>>>>> seems like we would not require workspace for validation if we can >>>>>>>>>>>> have the >>>>>>>>>>>> user provide the field for redirection and for us to grab the >>>>>>>>>>>> session >>>>>>>>>>>> variable. >>>>>>>>>>>> >>>>>>>>>>>> Or is this not needed at all after we use common fields ? >>>>>>>>>>>> >>>>>>>>>>>> I hope I am clear and make sense :-) >>>>>>>>>>>> >>>>>>>>>>>> Regards, >>>>>>>>>>>> >>>>>>>>>>>> Rahul >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Tuesday, October 16, 2018 at 7:49:49 PM UTC+5:30, Jim S >>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> Have you looked at common filters? >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> http://web2py.com/books/default/chapter/29/06/the-database-abstraction-layer?search=common+filter#Common-filters >>>>>>>>>>>>> >>>>>>>>>>>>> -Jim >>>>>>>>>>>>> >>>>>>>>>>>>> On Tuesday, October 16, 2018 at 7:35:04 AM UTC-5, Rahul wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> Hey Everyone, >>>>>>>>>>>>>> Greetings! I have a question. I went through Auth >>>>>>>>>>>>>> documentation and understood that we can add extra fields to the >>>>>>>>>>>>>> Auth >>>>>>>>>>>>>> tables. However, I still want to be a little more clear to >>>>>>>>>>>>>> achieve below - >>>>>>>>>>>>>> I am currently using three fields for a multi-tenant system like >>>>>>>>>>>>>> workspace, >>>>>>>>>>>>>> username and password. Here workspace depicts where the user >>>>>>>>>>>>>> belongs to >>>>>>>>>>>>>> (see explanation in Q1 below) I am currently using my own code >>>>>>>>>>>>>> to manage >>>>>>>>>>>>>> this stuff manually (almost everything that auth does), now >>>>>>>>>>>>>> though I want >>>>>>>>>>>>>> to give Auth a try and tailor it to fit my needs. I dont want to >>>>>>>>>>>>>> maintain >>>>>>>>>>>>>> that amount of code and use the existing API. Can I get help on >>>>>>>>>>>>>> achieving >>>>>>>>>>>>>> that in the simplest way. If it works, I would switch to using >>>>>>>>>>>>>> Auth >>>>>>>>>>>>>> >>>>>>>>>>>>>> * Q1]* How can we use Auth to add one more extra field for >>>>>>>>>>>>>> authentication when I want a system to validate login based on >>>>>>>>>>>>>> three >>>>>>>>>>>>>> parameters like - Validation needs to be done based on all three >>>>>>>>>>>>>> parameters >>>>>>>>>>>>>> specified. For each application I can use 'n' number of unique >>>>>>>>>>>>>> workspaces >>>>>>>>>>>>>> and 'n' number of users would belong to these workspaces. How to >>>>>>>>>>>>>> do this ? >>>>>>>>>>>>>> >>>>>>>>>>>>>> 1. *workspace *- An alpha numeric field that would store >>>>>>>>>>>>>> a unique name denoting users belonging to a particular set >>>>>>>>>>>>>> (For example >>>>>>>>>>>>>> users working in a specific location like los-angeles or >>>>>>>>>>>>>> washington) or >>>>>>>>>>>>>> an office location like michigan, nevada or Zones like north, >>>>>>>>>>>>>> south .. >>>>>>>>>>>>>> sort-of etc. ) >>>>>>>>>>>>>> 2. *username *- Its available already >>>>>>>>>>>>>> 3. *password *- Its available already >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> *Q2]* Which all tables need to be modified ? >>>>>>>>>>>>>> >>>>>>>>>>>>>> *Q3] *Any changes in any other code in any files ? >>>>>>>>>>>>>> >>>>>>>>>>>>>> I know I can clone my app multiple times and support >>>>>>>>>>>>>> multi-tenancy however, if this can be achieved with Auth - that >>>>>>>>>>>>>> would be >>>>>>>>>>>>>> great. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>> >>>>>>>>>>>>>> *Rahul * >>>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>> Resources: >>>>>>>>>>>> - http://web2py.com >>>>>>>>>>>> - http://web2py.com/book (Documentation) >>>>>>>>>>>> - http://github.com/web2py/web2py (Source code) >>>>>>>>>>>> - https://code.google.com/p/web2py/issues/list (Report Issues) >>>>>>>>>>>> --- >>>>>>>>>>>> You received this message because you are subscribed to a topic >>>>>>>>>>>> in the Google Groups "web2py-users" group. >>>>>>>>>>>> To unsubscribe from this topic, visit >>>>>>>>>>>> https://groups.google.com/d/topic/web2py/6SscBvMorU0/unsubscribe >>>>>>>>>>>> . >>>>>>>>>>>> To unsubscribe from this group and all its topics, send an >>>>>>>>>>>> email to [email protected]. >>>>>>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>>>>>> >>>>>>>>>>> -- >>> Resources: >>> - http://web2py.com >>> - http://web2py.com/book (Documentation) >>> - http://github.com/web2py/web2py (Source code) >>> - https://code.google.com/p/web2py/issues/list (Report Issues) >>> --- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "web2py-users" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/web2py/6SscBvMorU0/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> [email protected]. >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- > Resources: > - http://web2py.com > - http://web2py.com/book (Documentation) > - http://github.com/web2py/web2py (Source code) > - https://code.google.com/p/web2py/issues/list (Report Issues) > --- > You received this message because you are subscribed to a topic in the > Google Groups "web2py-users" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/web2py/6SscBvMorU0/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.{{extend 'layout.html'}} {{block header}}
Multitenant Test
# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------
# This is a sample controller
# this file is released under public domain and you can use without limitations
# -------------------------------------------------------------------------
# ---- example index page ----
def index():
response.flash = T("Hello World")
return dict(message=T('Welcome to web2py!'))
# ---- API (example) -----
@auth.requires_login()
def api_get_user_email():
if not request.env.request_method == 'GET': raise HTTP(403)
return response.json({'status':'success', 'email':auth.user.email})
# ---- Smart Grid (example) -----
@auth.requires_membership('admin') # can only be accessed by members of admin groupd
def grid():
response.view = 'generic.html' # use a generic view
tablename = request.args(0)
if not tablename in db.tables: raise HTTP(403)
grid = SQLFORM.smartgrid(db[tablename], args=[tablename], deletable=False, editable=False)
return dict(grid=grid)
# ---- Embedded wiki (example) ----
def wiki():
auth.wikimenu() # add the wiki to the menu
return auth.wiki()
# ---- Action for login/register/etc (required for auth) -----
def user():
"""
exposes:
http://..../[app]/default/user/login
http://..../[app]/default/user/logout
http://..../[app]/default/user/register
http://..../[app]/default/user/profile
http://..../[app]/default/user/retrieve_password
http://..../[app]/default/user/change_password
http://..../[app]/default/user/bulk_register
use @auth.requires_login()
@auth.requires_membership('group name')
@auth.requires_permission('read','table name',record_id)
to decorate functions that need access control
also notice there is http://..../[app]/appadmin/manage/auth to allow administrator to manage users
"""
return dict(form=auth())
# ---- action to server uploaded static content (required) ---
@cache.action()
def download():
"""
allows downloading of uploaded files
http://..../[app]/default/download/[filename]
"""
return response.download(request, db)
@auth.requires_login()
def notes():
grid = SQLFORM.grid(db.notemaker)
return dict(grid=grid)# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------
# AppConfig configuration made easy. Look inside private/appconfig.ini
# Auth is for authenticaiton and access control
# -------------------------------------------------------------------------
from gluon.contrib.appconfig import AppConfig
from gluon.tools import Auth
# -------------------------------------------------------------------------
# This scaffolding model makes your app work on Google App Engine too
# File is released under public domain and you can use without limitations
# -------------------------------------------------------------------------
if request.global_settings.web2py_version < "2.15.5":
raise HTTP(500, "Requires web2py 2.15.5 or newer")
# -------------------------------------------------------------------------
# if SSL/HTTPS is properly configured and you want all HTTP requests to
# be redirected to HTTPS, uncomment the line below:
# -------------------------------------------------------------------------
# request.requires_https()
# -------------------------------------------------------------------------
# once in production, remove reload=True to gain full speed
# -------------------------------------------------------------------------
configuration = AppConfig(reload=True)
if not request.env.web2py_runtime_gae:
# ---------------------------------------------------------------------
# if NOT running on Google App Engine use SQLite or other DB
# ---------------------------------------------------------------------
db = DAL(configuration.get('db.uri'),
pool_size=configuration.get('db.pool_size'),
migrate_enabled=configuration.get('db.migrate'),
check_reserved=['all'])
else:
# ---------------------------------------------------------------------
# connect to Google BigTable (optional 'google:datastore://namespace')
# ---------------------------------------------------------------------
db = DAL('google:datastore+ndb')
# ---------------------------------------------------------------------
# store sessions and tickets there
# ---------------------------------------------------------------------
session.connect(request, response, db=db)
# ---------------------------------------------------------------------
# or store session in Memcache, Redis, etc.
# from gluon.contrib.memdb import MEMDB
# from google.appengine.api.memcache import Client
# session.connect(request, response, db = MEMDB(Client()))
# ---------------------------------------------------------------------
# -------------------------------------------------------------------------
# by default give a view/generic.extension to all actions from localhost
# none otherwise. a pattern can be 'controller/function.extension'
# -------------------------------------------------------------------------
response.generic_patterns = []
if request.is_local and not configuration.get('app.production'):
response.generic_patterns.append('*')
# -------------------------------------------------------------------------
# choose a style for forms
# -------------------------------------------------------------------------
response.formstyle = 'bootstrap4_inline'
response.form_label_separator = ''
# -------------------------------------------------------------------------
# (optional) optimize handling of static files
# -------------------------------------------------------------------------
# response.optimize_css = 'concat,minify,inline'
# response.optimize_js = 'concat,minify,inline'
# -------------------------------------------------------------------------
# (optional) static assets folder versioning
# -------------------------------------------------------------------------
# response.static_version = '0.0.0'
# -------------------------------------------------------------------------
# Here is sample code if you need for
# - email capabilities
# - authentication (registration, login, logout, ... )
# - authorization (role based authorization)
# - services (xml, csv, json, xmlrpc, jsonrpc, amf, rss)
# - old style crud actions
# (more options discussed in gluon/tools.py)
# -------------------------------------------------------------------------
# host names must be a list of allowed host names (glob syntax allowed)
auth = Auth(db, host_names=configuration.get('host.names'))
auth.settings.extra_fields['auth_user'] = [
Field ('workspace', length=128),
Field ('created_on', 'date', default=request.now),
]
auth.define_tables(username=True, signature=False) ## Default username=False for using emails
# -------------------------------------------------------------------------
# create all tables needed by auth, maybe add a list of extra fields
# -------------------------------------------------------------------------
auth.settings.extra_fields['auth_user'] = []
auth.define_tables(username=False, signature=False)
# -------------------------------------------------------------------------
# configure email
# -------------------------------------------------------------------------
mail = auth.settings.mailer
mail.settings.server = 'logging' if request.is_local else configuration.get('smtp.server')
mail.settings.sender = configuration.get('smtp.sender')
mail.settings.login = configuration.get('smtp.login')
mail.settings.tls = configuration.get('smtp.tls') or False
mail.settings.ssl = configuration.get('smtp.ssl') or False
# -------------------------------------------------------------------------
# configure auth policy
# -------------------------------------------------------------------------
auth.settings.registration_requires_verification = False
auth.settings.registration_requires_approval = False
auth.settings.reset_password_requires_verification = True
# -------------------------------------------------------------------------
# read more at http://dev.w3.org/html5/markup/meta.name.html
# -------------------------------------------------------------------------
response.meta.author = configuration.get('app.author')
response.meta.description = configuration.get('app.description')
response.meta.keywords = configuration.get('app.keywords')
response.meta.generator = configuration.get('app.generator')
response.show_toolbar = configuration.get('app.toolbar')
# -------------------------------------------------------------------------
# your http://google.com/analytics id
# -------------------------------------------------------------------------
response.google_analytics_id = configuration.get('google.analytics_id')
# -------------------------------------------------------------------------
# maybe use the scheduler
# -------------------------------------------------------------------------
if configuration.get('scheduler.enabled'):
from gluon.scheduler import Scheduler
scheduler = Scheduler(db, heartbeat=configuration.get('heartbeat'))
# -------------------------------------------------------------------------
# Define your tables below (or better in another model file) for example
#
# >>> db.define_table('mytable', Field('myfield', 'string'))
#
# Fields can be 'string','text','password','integer','double','boolean'
# 'date','time','datetime','blob','upload', 'reference TABLENAME'
# There is an implicit 'id integer autoincrement' field
# Consult manual for more options, validators, etc.
#
# More API examples for controllers:
#
# >>> db.mytable.insert(myfield='value')
# >>> rows = db(db.mytable.myfield == 'value').select(db.mytable.ALL)
# >>> for row in rows: print row.id, row.myfield
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# after defining tables, uncomment below to enable auditing
# -------------------------------------------------------------------------
# auth.enable_record_versioning(db)
if auth.is_logged_in():
print 'workspace', auth.user.workspace
# Notes table
db.define_table('notemaker',
Field('workspace', length=128, default=auth.user.workspace if auth.is_logged_in() else None, writable=False),
Field('written_on', 'datetime', default=request.now),
Field('written_by', default=session.user_name),
Field('note_type', 'string'),
Field('note_title', ),
Field('reference', ), # requires=IS_EMPTY_OR(IS_IN_SET(projects)) ),
Field('note', 'text', requires=IS_NOT_EMPTY()),
Field('attachment1', 'upload', label='Attachment-1', autodelete=True),
Field('attachment2', 'upload', label='Attachment-2', autodelete=True),
common_filter=lambda query: db.notemaker.workspace==auth.user.workspace if auth.is_logged_in() else None)
{{extend 'layout.html'}}
{{=grid}}
storage.sqlite
Description: Binary data

