how can I expire tokens after 1 minute? - python

I am trying to expire tokens after its creation with a max duration of 1 minute to meet security requirements. my function looks like this, but I don't think is doing it the right way, and I Would like to know what is the best way to expire the token after 1 minute? I am using the technique of diffing two times. the following function works under models.py
def is_token_expired(self):
if self.token == None:
return False
now = datetime.datetime.utcnow().replace(tzinfo=utc)
timediff = now - self.created_at
if timediff.seconds / 60 - 1 > 0:
return True
return False

I think the elegant way to archive your goal is leveraging django cache.
Sample code:
class Foo(models.Model):
...
def save(self, *args, **kwargs):
if not self.pk:
# save the token when record created
cache.set('token_key', '<Your token>', timeout=60)
super(Foo, self).save(*args, **kwargs)
#property
def is_token_expired(self):
# check if the token expired
return cache.get('token_key') is None
#property
def token(self):
# get token
return cache.get('token_key')

It is better to use #property in your model:
from datetime import timedelta
class Foo(models.Model):
some_field = models.CharField()
creation_date = models.DateTimeField(auto_now_add=True)
#property
def is_expired(self):
if datetime.now > (self.creation_date + timedelta(minutes=1)):
return True
return False
you can change timedelta(minutes=1) to amount that your token is valid.
and use it in your code like this:
if your_instance.is_expired == True:
# do something
You can also use Django builtin cache system (that Enix mentioned) as a better approach.

Related

Python TDD assert statements not working like i thought

I am just confused about why this is happening. When I run my assert it seems that each test is not creating its own object. so when i get to the last assert statement the test fails because the other assert are still in the list. Any help would be great thank you
My Class code:
from datetime import date
class Transaction():
"""
Transaction
"""
balance = 0.0
timestamp = date.today()
def __init__(self, amount, dt=None):
self.balance = amount
self.transactions = []
if dt is None:
self.timestamp = date.today()
else:
self.timestamp = dt
def __repr__(self):
return '{self.__class__.__name__}({self.balance:,.2f}, {self.timestamp})'.format(self=self)
def __str__(self):
return f'{self.timestamp}: ${self.balance:,.2f}'
class Account():
"""
Account Class
"""
balance = 0.0
transaction = Transaction(balance)
def __init__(self):
self.balance = 0.0
def deposit(self, amount):
self.balance += +amount
self.transaction.transactions.append(+amount)
def withdraw(self, amount):
self.balance -= amount
self.transaction.transactions.append(-amount)
def get_balance(self):
if len(self.transaction.transactions) < 1:
return 0
return sum(self.transaction.transactions)
My Code for pytest:
def test_append_transaction():
account = Account()
account.deposit(200)
assert account.transaction.transactions == [200]
def test_deposit():
user = Account()
user.deposit(300)
assert user.balance == +300.00
def test_append_withdraw():
account = Account()
account.withdraw(50)
assert account.transaction.transactions == [-50]
def test_withdraw():
account = Account()
account.withdraw(50)
assert account.balance == -50.0
Your tests are failing because your code is wrong - i.e. they are failing because you've written your tests correctly, in a way which is able to detect bugs, and they detected a bug in your code.
Yes, each test function does create a new Account instance, as you can clearly see in the test functions themselves. However, each Account instance does not have its own distinct Transaction instance, because you made this a class attribute instead of an instance attribute.
To fix the bug in your Account class, you should initialise
self.transaction = Transaction(self.balance)
in the __init__ method, so that each Account instance has a reference to a distinct Transaction instance.

Django: do I need to make a caching method?

I have a model Person where I do a lot of queries of the same type. For example, I may ask a lot of times the "profile picture" in the same page.
As you can see in my code, I've implemented a "sort" of cache: put the result in an array, and later, if there's a key in this array, return the result.
class Personne(BaseModel):
def __init__(self, *args, **kwargs):
# Mise en place de cache :
self.cache = {}
super(Personne, self).__init__(*args, **kwargs)
def url_profile_picture(self):
# gestion du cache :
retour = self.cache.get('profile_picture')
if retour:
return retour
a = PersonnePhoto.objects.filter(personne=self,
photo_type=PersonnePhoto.PHOTO_PROFIL)
if len(a):
a = reverse('url_public', kwargs={'path': a[0].photo})
else:
a = staticfiles.static('img/no-picture-yet.png')
self.cache['photo_profil'] = a
return a
I was wondering (because I'm a Django newbie) if it's useful of if Django has already a caching system on its own. What I mean is: will my query PersonnePhoto.objects.filter(...) access the database all the time -> I definitely need my own cache, or will it be cached by Django -> useless to write my own caching method?
from django.core.cache import cache
In your model, i suggest something like this:
def url_profile_picture(self):
# gestion du cache :
retour = cache.get('profile_picture_%s' % self.pk)
if retour:
return retour
else:
a = PersonnePhoto.objects.filter(personne=self,
photo_type=PersonnePhoto.PHOTO_PROFIL)
if len(a):
a = reverse('url_public', kwargs={'path': a[0].photo})
else:
a = staticfiles.static('img/no-picture-yet.png')
cache.set('profile_picture_%s' % self.pk, a)
return a
can read up more on django cache here: https://docs.djangoproject.com/en/1.9/topics/cache/
edit: then in your profile area, you can clear the cache on upload of an image to get it to display faster.
I think you are looking for the cached_property decorator. It behaves exactly the same like the solution you rolled out for yourself (with the distinction that url_profile_picture is now a property):
from django.utils.functional import cached_property
class Personne(BaseModel):
#cached_property
def url_profile_picture(self):
a = PersonnePhoto.objects.filter(personne=self,
photo_type=PersonnePhoto.PHOTO_PROFIL)
if len(a):
a = reverse('url_public', kwargs={'path': a[0].photo})
else:
a = staticfiles.static('img/no-picture-yet.png')
return a

Google App Engine NDB post_create hook

I wanted to create a proper post_create (also post_get and post_put) hooks, similar to the ones I had on the DB version of my app.
Unfortunately I can't use has_complete_key.
The problem is quite known: lack of is_saved in a model.
Right now I have implemented it like this:
class NdbStuff(HooksInterface):
def __init__(self, *args, **kwds):
super(NdbStuff, self).__init__(*args, **kwds)
self._is_saved = False
def _put_async(self, post_hooks=True, **ctx_options):
""" Implementation of pre/post create hooks. """
if not self._is_saved:
self._pre_create_hook()
fut = super(NdbStuff, self)._put_async(**ctx_options)
if not self._is_saved:
fut._immediate_callbacks.insert(
0,
(
self._post_create_hook,
[fut],
{},
)
)
self._is_saved = True
if post_hooks is False:
fut._immediate_callbacks = []
return fut
put_async = _put_async
#classmethod
def _post_get_hook(cls, key, future):
obj = future.get_result()
if obj is not None:
obj._is_saved = True
cls._post_get(key, future)
def _post_put_hook(self, future):
if future.state == future.FINISHING:
self._is_saved = True
else:
self._is_saved = False
self._post_put(future)
Everything except the post_create hook seems to work.
The post_create is triggered every time the I use put_async without retrieving the object first.
I would really appreciate a clue on how to trigger the post_create_hook only once after the object was created.
I am not sure why you are creating the NDBStuff class.
Any way if you creating an instance of a class, and you want to track _is_saved or something similar , use a factory to control creation and setting of the property, in this case it makes more sense to track _is_new for example.
class MyModel(ndb.Model):
some_prop = ndb.StringProperty()
def _pre_put_hook(self):
if getattr(self,'_is_new',None):
self._pre_create_hook()
# do something
def _pre_create_hook(self):
# do something on first save
log.info("First put for this object")
def _post_create_hook(self, future):
# do something
def _post_put_hook(self, future);
if getattr(self,'_is_new', None):
self._post_create_hook(future)
# Get rid of the flag on successful put,
# in case you make some changes and save again.
delattr(self,'_is_new')
#classmethod
def factory(cls,*args,**kwargs):
new_obj = cls(*args,**kwargs)
settattr(new_obj,'_is_new',True)
return new_obj
Then
myobj = MyModel.factory(someargs)
myobj.put()
myobj.some_prop = 'test'
myobj.put()
Will call the _pre_create_hook on the first put, and not on the second.
Always create the entities through the factory then you will always have the to call to _pre_create_hook executed.
Does that make sense ?

using datetime.utcnow() with DjangoTables2 render_FOO

I am trying to display the age of a post(in hours) with djangotables2. My code is given below
class PostTable(tables.Table):
current_Time = datetime.utcnow().replace(tzinfo=utc)
published= tables.Column()
def render_published(self, value,record):
tdelta = self.current_Time - record.published
#Some logic
With this code, 'current_Time' is only updated when the apache server restart. If I change my code to
tdelta = datetime.utcnow().replace(tzinfo=utc) - record.published
it works, but calculates datetime.utcnow() for every row which is not efficient. I want 'current_Time' to be updated only once for table. What is the best way to achieve that?
Try setting the current time in the table's __init__ method. Then self.current_Time will be set each time the table is initiated, rather than when the table is defined.
class PostTable(tables.Table):
def __init__(self, *args, **kwargs):
super(PostTable, self).__init__(*args, **kwargs)
self.current_Time = datetime.utcnow().replace(tzinfo=utc)
def render_published(self, value,record):
tdelta = self.current_Time - record.published
current_Time is a field on your class which is installed when your class deffinition is read in. This happens once when your class is initially defined. In your case, this happens at server startup. The value for current_Time is set then and only once.
You will want to move current_Time = datetime.utcnow().replace(tzinfo=utc) into the def render_published(self, value,record):
class PostTable(tables.Table):
published= tables.Column()
def render_published(self, value,record):
current_Time = datetime.utcnow().replace(tzinfo=utc)
tdelta = current_Time - record.published
#Some logic
This way, current_Time will be populated every time the render_published method is called.

Create a Python User() class that both creates new users and modifies existing users

I'm trying to figure out the best way to create a class that can modify and create new users all in one. This is what I'm thinking:
class User(object):
def __init__(self,user_id):
if user_id == -1
self.new_user = True
else:
self.new_user = False
#fetch all records from db about user_id
self._populateUser()
def commit(self):
if self.new_user:
#Do INSERTs
else:
#Do UPDATEs
def delete(self):
if self.new_user == False:
return False
#Delete user code here
def _populate(self):
#Query self.user_id from database and
#set all instance variables, e.g.
#self.name = row['name']
def getFullName(self):
return self.name
#Create a new user
>>u = User()
>>u.name = 'Jason Martinez'
>>u.password = 'linebreak'
>>u.commit()
>>print u.getFullName()
>>Jason Martinez
#Update existing user
>>u = User(43)
>>u.name = 'New Name Here'
>>u.commit()
>>print u.getFullName()
>>New Name Here
Is this a logical and clean way to do this? Is there a better way?
Thanks.
You can do this with metaclasses. Consider this :
class MetaCity:
def __call__(cls,name):
“”“
If it’s in the database, retrieve it and return it
If it’s not there, create it and return it
““”
theCity = database.get(name) # your custom code to get the object from the db goes here
if not theCity:
# create a new one
theCity = type.__call__(cls,name)
return theCity
class City():
__metaclass__ = MetaCity
name = Field(Unicode(64))
Now you can do things like :
paris = City(name=u"Paris") # this will create the Paris City in the database and return it.
paris_again = City(name=u"Paris") # this will retrieve Paris from the database and return it.
from : http://yassinechaouche.thecoderblogs.com/2009/11/21/using-beaker-as-a-second-level-query-cache-for-sqlalchemy-in-pylons/
Off the top of my head, I would suggest the following:
1: Use a default argument None instead of -1 for user_id in the constructor:
def __init__(self, user_id=None):
if user_id is None:
...
2: Skip the getFullName method - that's just your Java talking. Instead use a normal attribute access - you can convert it into a property later if you need to.
What you are trying to achieve is called Active Record pattern. I suggest learning existing systems providing this sort of things such as Elixir.
Small change to your initializer:
def __init__(self, user_id=None):
if user_id is None:

Categories

Resources