getting webapp2 session id - sessionid

How to get a session id in webapp2?
It doesn't seem to be documented anywhere and it wasn't trivial to me.
I have found some solution, which I present in the answer to this question, but maybe somebody will find simpler or better one.
Anyway I think that this can be useful to somebody

My solution looks like this:
import webapp2
from webapp2_extras import sessions
class Test(webapp2.RequestHandler):
def get(self):
session_store = sessions.get_store(request=self.request)
cookie_name = session_store.config['cookie_name']
session_id = self.request.cookies[cookie_name]
self.response.out.write('<html><body>')
self.response.out.write('Session id: %s' % session_id)
self.response.out.write("</body></html>")

In your example, you can't get the session id, until you refresh the page. You should make an authenticate page to create the session. Also you should define a base handler that extends the dispatch() method to start the session store and save all sessions at the end of a request. Read the documentation See an example:
class Main(main.BaseHandler):
def get(self):
if not self.session.get('user'):
self.redirect("/authenticate",abort=True)
session = self.request.cookies("session")
#more stuff........
class Authenticate(main.BaseHandler):
def get(self):
if self.session.get('user'):
self.redirect("/")
else:
self.render("authenticate.htm")
def post(self):
if self.session.get('user'):
self.redirect("/",abort=True)
post_param = {"username":self.request.get("username"),
"password":self.request.get("password")}
if not post_param["password"] or not post_param["username"]:
redirect("/authenticate")
mySql = dbLib.MySqlLib()
try:
mySql.query("SELECT password FROM users where username=%s", post_param["username"],))
dbPassword = mySql.dbCur.fetchone()[0]
except dbLib.ProgrmmgError as error:
self.render("authenticate.htm",username = post_param["username"],
errorMessage = "Password and/or Username\
else: invalid")
if bcrypt.hashpw(post_param["password"],dbPassword) == dbPassword:
self.session['user'] = "root"
self.redirect("/")
else:
self.render("authenticate.htm",username = post_param["username"],
errorMessage = "Password and/or Username\
mySql.close()
app = main.webapp2.WSGIApplication([('/', Main),
("/authenticate",Authenticate),
(".*",main.Error_404)],
debug=True)

Related

How to Save Currently Logged in User to Model in Django

I am trying to get the currently logged in User and save it to a model. I am getting the following error
"Cannot assign "<SimpleLazyObject: <User: rsomani005>>": "process_master.user" must be a "User" instance"
I am using Django's built in user model.
My model looks like this -
class User(auth.models.User,auth.models.PermissionsMixin):
def __str__(self):
return "#{}".format(self.username)
class plan_master(models.Model):
plan_name = models.CharField(max_length=256)
plan_description = models.CharField(max_length=256)
plan_price = models.FloatField()
plan_active_status = models.BooleanField(default=True)
plan_credits = models.IntegerField(default=0)
registration_type_name = models.CharField(max_length=50)
My view file looks like this -
class FileFieldView(LoginRequiredMixin,FormView):
form_class = FileFieldForm
template_name = 'merge_ops/merge_ops.html'
success_url = reverse_lazy('merge_ops:file_setup')
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
files = request.FILES.getlist('file_field')
if form.is_valid():
for f in files:
fs = FileSystemStorage()
fs.save(f.name,f)
obj = process_master()
user = request.user
obj.user = user
obj.process_date = datetime.now()
obj.number_of_workbooks = len(files)
obj.save()
return self.form_valid(form)
else:
return self.form_invalid(form)
An easy way to get the logged user in one of your views is:
user = request.user
but that is usually when the user model that you have created is something like that in the model.py:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
pass
I would suggest using this one to register users because it is automatic and complete.
and from there use the object for what you need. You can pass it on as a context or
source model objects from it.

Extend Plone-Controlpanel Form

Is it possible to extend the Controlpanel-View with each addon?
For Example
ca.db.core -> Makes basic fieldset/tab for DB Connection Settings
ca.db.person -> If installed, Adds to the "core" settings a new fieldset/tab for Person specific fields/settings
ca.db.schema -> If installed, also adds an new fieldset/tab for schema.org Fields
Yes it's possible, I once discussed this problem with a guy, who wrote the bda.plone.shop addon.
They faced the same problem, and solved it by using a ContextProxy object, which puts the different schema definitions together in one proxy object.
Using a proxy is IMHO a hack, but I don't know a better solution.
The proxy, tries to get/set a attribute from a list of schemas.
Be aware, you need to handle conflicting names, means if you have the same field name in more than one schema.
class ContextProxy(object):
def __init__(self, interfaces):
self.__interfaces = interfaces
alsoProvides(self, *interfaces)
def __setattr__(self, name, value):
if name.startswith('__') or name.startswith('_ContextProxy__'):
return object.__setattr__(self, name, value)
registry = getUtility(IRegistry)
for interface in self.__interfaces:
proxy = registry.forInterface(interface)
try:
getattr(proxy, name)
except AttributeError:
pass
else:
return setattr(proxy, name, value)
raise AttributeError(name)
def __getattr__(self, name):
if name.startswith('__') or name.startswith('_ContextProxy__'):
return object.__getattr__(self, name)
registry = getUtility(IRegistry)
for interface in self.__interfaces:
proxy = registry.forInterface(interface)
try:
return getattr(proxy, name)
except AttributeError:
pass
raise AttributeError(name)
Now you need to use the proxy in your ControlPanel form.
I assume you're using the RegistryEditForm from plone.registry:
class SettingsEditForm(controlpanel.RegistryEditForm):
schema = ISettings
label = _(u"Settings")
description = _(u"")
# IMPORTANT Note 1 - This is where you hook in your proxy
def getContent(self):
interfaces = [self.schema] # Base schema from ca.db.core
interfaces.extend(self.additionalSchemata) # List of additional schemas
return ContextProxy(interfaces)
# IMPORTANT Note 2 - You may get the additional schemas dynamically to extend the Settings Form. For example by name (startswith...)
# In this case they have a separate interface, which marks the relevant interfaces.
#property
def additionalSchemata(self):
registry = getUtility(IRegistry)
interface_names = set(record.interfaceName for record
in registry.records.values())
for name in interface_names:
if not name:
continue
interface = None
try:
interface = resolve(name)
except ImportError:
# In case of leftover registry entries of uninstalled Products
continue
if ISettingsProvider.providedBy(interface):
yield interface
...
You can find the full code here

Plone: Add additional registration fields to users (members)

I have two additional fields for my group objects (like described here).
Now I need (other) additional fields for my member objects as well (short strings). I have created them in portal_memberdata/manage_propertiesForm, but I still can't select them for registration form usage (##member-registration).
I need the two new fields for registration, at least one of them mandatory. How can I achieve this? Thank you!
Update:
I found plone.app.users.userdataschema and added my fields to the interface IUserDataSchema; furthermore, I monkeypatched plone.app.users.browser.personalpreferences.UserDataPanelAdapter. There still seems to be missing something (no change visible in ##member-registration).
My customization code looks like this:
from plone.app.users.userdataschema import IUserDataSchema
from zope import schema
from Products.CMFPlone import PloneMessageFactory as _
IUserDataSchema.custom1 = schema.ASCIILine(
title=_(u'label_custom1',
default=u'Custom1 member id'),
description=_(u'help_custom1_creation',
default=u'Custom1 membership is required; '
u'please enter your member id'),
required=True)
from plone.app.users.browser.personalpreferences import UserDataPanelAdapter
def set_custom1(self, value):
if value is None:
value = ''
return self.context.setMemberProperties({'custom1': value})
def get_custom1(self):
return self._getProperty('custom1')
UserDataPanelAdapter.custom1 = property(get_custom1, set_custom1)
It didn't work when I used the monkeypatched original interface class;
but it does work to monkeypatch the UserDataSchemaProvider to return a subclass:
from plone.app.users.userdataschema import IUserDataSchema
from plone.app.users.userdataschema import UserDataSchemaProvider
from zope import schema
from Products.CMFPlone import PloneMessageFactory as _
class IUserDataSchemaExtended(IUserDataSchema):
"""
Extends the userdata schema
by a mandatory field
"""
customField1 = schema.ASCIILine(
title=_(u'label_customField1',
default=u'CustomField1 member id'),
description=_(u'help_customField1_creation',
default=u'CustomField1 membership is required; '
u'please enter your member id'),
required=True)
def getExtendedSchema(self):
return IUserDataSchemaExtended
UserDataSchemaProvider.getSchema = getExtendedSchema
from plone.app.users.browser.personalpreferences import UserDataPanelAdapter
def set_customField1(self, value):
if value is None:
value = ''
return self.context.setMemberProperties({'customField1': value})
def get_customField1(self):
return self._getProperty('customField1')
UserDataPanelAdapter.customField1 = property(get_customField1, set_customField1)
Remarks:
It might be better to simply use customField1 for the translatable title instead of label_customField as the name the field is used when the registration page is quickedited
with Plone 5, it apparently is possible to configure additional userdata fields via XML

How to retrieve the email from gae datastore?

I was using the google datastore and jinja2 for starting off. I am able to add and retrieve string values but when I use the email property as :
email=db.Email
and retrieve it using .email, I get
class 'google.appengine.api.datastore_types.Email' from the datastore.
How do i get the value of the email instead?
using .email works for me.
python code
import webapp2
from google.appengine.ext import db
class Greeting(db.Model):
author = db.StringProperty()
email = db.EmailProperty()
class MainPage(webapp2.RequestHandler):
def get(self):
en = Greeting(author='hellooo', email=db.Email("a#a.com"))
en.put()
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
and get the value like this
dev~devchat> x = Greeting.get_by_id(2)
dev~devchat> x.author
u'hellooo'
dev~devchat> x.email
u'a#a.com'
dev~devchat> x.email.ToXml()
u'<gd:email address="a#a.com" />'

Table creation fails with SqlAlchemy and Pylons

I just upgraded to Pylons 1.0 and SqlAlchemy 0.6.5. What was a simple process of creating the DB schema no longer works.
I have a simple model:
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
user_name = Column(String)
def __init__(self, userName):
self.userName = userName
def __repr__(self):
return "<User('%s')>" % (self.userName)
When I run
paster setup-app development.ini
the database file is created (sqlite3), but not the table, and no errors are returned.
Logging shows that the following lines in websetup.py do execute:
log.info("Creating schema...")
Base.metadata.create_all(bind = Session.bind, checkfirst = True)
log.info("Database successfully set up.")
What am I missing?
Edit: Further digging shows that the Base.metadata.tables dictionary is empty. So, why isn't the model reflected in the metadata?
Ok, I found the issue.
In model.meta.py, Base = declarative_base() was already performed. When I also added that statement to the model.__init__.py, it evidently creates a new instance without the metadata, so there were no tables to create.
I'm not clear on exactly why/how this works, so if anyone (Mike Bayer?) has details, I would love to know.

Resources