Create sessions for anons as well, instead of just logged in.
It makes sense that anon sessions are still sessions. So @give_token will ensure that every request has a session. Logged in conditionals move from 'if session' to 'if session.user'.
This commit is contained in:
		
							parent
							
								
									8a1f2c65f9
								
							
						
					
					
						commit
						be0fca729f
					
				
					 4 changed files with 28 additions and 12 deletions
				
			
		|  | @ -51,7 +51,8 @@ def get_login(): | ||||||
| @session_manager.give_token | @session_manager.give_token | ||||||
| @decorators.required_fields(['username', 'password']) | @decorators.required_fields(['username', 'password']) | ||||||
| def post_login(): | def post_login(): | ||||||
|     if session_manager.get(request): |     session = session_manager.get(request) | ||||||
|  |     if session.user: | ||||||
|         exc = etiquette.exceptions.AlreadySignedIn() |         exc = etiquette.exceptions.AlreadySignedIn() | ||||||
|         response = etiquette.jsonify.exception(exc) |         response = etiquette.jsonify.exception(exc) | ||||||
|         return jsonify.make_json_response(response, status=403) |         return jsonify.make_json_response(response, status=403) | ||||||
|  | @ -94,7 +95,8 @@ def get_register(): | ||||||
| @decorators.catch_etiquette_exception | @decorators.catch_etiquette_exception | ||||||
| @decorators.required_fields(['username', 'password_1', 'password_2']) | @decorators.required_fields(['username', 'password_1', 'password_2']) | ||||||
| def post_register(): | def post_register(): | ||||||
|     if session_manager.get(request): |     session = session_manager.get(request) | ||||||
|  |     if session.user: | ||||||
|         exc = etiquette.exceptions.AlreadySignedIn() |         exc = etiquette.exceptions.AlreadySignedIn() | ||||||
|         response = etiquette.jsonify.exception(exc) |         response = etiquette.jsonify.exception(exc) | ||||||
|         return jsonify.make_json_response(response, status=403) |         return jsonify.make_json_response(response, status=403) | ||||||
|  |  | ||||||
|  | @ -6,6 +6,8 @@ import werkzeug.wrappers | ||||||
| 
 | 
 | ||||||
| import etiquette | import etiquette | ||||||
| 
 | 
 | ||||||
|  | SESSION_MAX_AGE = 86400 | ||||||
|  | 
 | ||||||
| def _generate_token(length=32): | def _generate_token(length=32): | ||||||
|     randbytes = os.urandom(math.ceil(length / 2)) |     randbytes = os.urandom(math.ceil(length / 2)) | ||||||
|     token = ''.join('{:02x}'.format(x) for x in randbytes) |     token = ''.join('{:02x}'.format(x) for x in randbytes) | ||||||
|  | @ -35,7 +37,7 @@ class SessionManager: | ||||||
| 
 | 
 | ||||||
|     def get(self, token): |     def get(self, token): | ||||||
|         token = _normalize_token(token) |         token = _normalize_token(token) | ||||||
|         session = self.sessions.get(token, None) |         session = self.sessions[token] | ||||||
|         return session |         return session | ||||||
| 
 | 
 | ||||||
|     def give_token(self, function): |     def give_token(self, function): | ||||||
|  | @ -54,6 +56,14 @@ class SessionManager: | ||||||
|                 request.cookies = dict(request.cookies) |                 request.cookies = dict(request.cookies) | ||||||
|                 request.cookies['etiquette_session'] = token |                 request.cookies['etiquette_session'] = token | ||||||
| 
 | 
 | ||||||
|  |             try: | ||||||
|  |                 session = self.get(token) | ||||||
|  |             except KeyError: | ||||||
|  |                 session = Session(request, user=None) | ||||||
|  |                 self.add(session) | ||||||
|  |             else: | ||||||
|  |                 session.maintain() | ||||||
|  | 
 | ||||||
|             response = function(*args, **kwargs) |             response = function(*args, **kwargs) | ||||||
|             if not isinstance(response, (flask.Response, werkzeug.wrappers.Response)): |             if not isinstance(response, (flask.Response, werkzeug.wrappers.Response)): | ||||||
|                 response = flask.Response(response) |                 response = flask.Response(response) | ||||||
|  | @ -64,17 +74,15 @@ class SessionManager: | ||||||
|                 if headerkey == 'Set-Cookie' and value.startswith('etiquette_session='): |                 if headerkey == 'Set-Cookie' and value.startswith('etiquette_session='): | ||||||
|                     break |                     break | ||||||
|             else: |             else: | ||||||
|                 response.set_cookie('etiquette_session', value=token, max_age=86400) |                 response.set_cookie( | ||||||
|                 self.maintain(token) |                     'etiquette_session', | ||||||
|  |                     value=session.token, | ||||||
|  |                     max_age=SESSION_MAX_AGE, | ||||||
|  |                 ) | ||||||
| 
 | 
 | ||||||
|             return response |             return response | ||||||
|         return wrapped |         return wrapped | ||||||
| 
 | 
 | ||||||
|     def maintain(self, token): |  | ||||||
|         session = self.get(token) |  | ||||||
|         if session: |  | ||||||
|             session.maintain() |  | ||||||
| 
 |  | ||||||
|     def remove(self, token): |     def remove(self, token): | ||||||
|         token = _normalize_token(token) |         token = _normalize_token(token) | ||||||
|         if token in self.sessions: |         if token in self.sessions: | ||||||
|  | @ -88,5 +96,11 @@ class Session: | ||||||
|         self.user_agent = request.headers.get('User-Agent', '') |         self.user_agent = request.headers.get('User-Agent', '') | ||||||
|         self.last_activity = int(etiquette.helpers.now()) |         self.last_activity = int(etiquette.helpers.now()) | ||||||
| 
 | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         if self.user: | ||||||
|  |             return 'Session %s for user %s' % (self.token, self.user) | ||||||
|  |         else: | ||||||
|  |             return 'Session %s for anonymous' % self.token | ||||||
|  | 
 | ||||||
|     def maintain(self): |     def maintain(self): | ||||||
|         self.last_activity = int(etiquette.helpers.now()) |         self.last_activity = int(etiquette.helpers.now()) | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
|     <a class="header_element" href="/">Etiquette</a> |     <a class="header_element" href="/">Etiquette</a> | ||||||
|     <a class="header_element" href="/search">Search</a> |     <a class="header_element" href="/search">Search</a> | ||||||
|     <a class="header_element" href="/tags">Tags</a> |     <a class="header_element" href="/tags">Tags</a> | ||||||
|     {% if session %} |     {% if session.user %} | ||||||
|     <a class="header_element" href="/user/{{session.user.username}}">{{session.user.username}}</a> |     <a class="header_element" href="/user/{{session.user.username}}">{{session.user.username}}</a> | ||||||
|     <a class="header_element" href="/logout" style="flex:0">Logout</a> |     <a class="header_element" href="/logout" style="flex:0">Logout</a> | ||||||
|     {% else %} |     {% else %} | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ body, .nice_link | ||||||
|     <a class="nice_link" href="/tags">Browse tags</a> |     <a class="nice_link" href="/tags">Browse tags</a> | ||||||
|     <a class="nice_link" href="/albums">Browse albums</a> |     <a class="nice_link" href="/albums">Browse albums</a> | ||||||
|     <a class="nice_link" href="/bookmarks">Bookmarks</a> |     <a class="nice_link" href="/bookmarks">Bookmarks</a> | ||||||
|     {% if session %} |     {% if session.user %} | ||||||
|     <a class="nice_link" href="/user/{{session.user.username}}">{{session.user.username}}</a> |     <a class="nice_link" href="/user/{{session.user.username}}">{{session.user.username}}</a> | ||||||
|     {% else %} |     {% else %} | ||||||
|     <a class="nice_link" href="/login">Log in</a> |     <a class="nice_link" href="/login">Log in</a> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue