Skip to content

Commit cdd5374

Browse files
committed
staring the user profile page
1 parent 2ad7304 commit cdd5374

File tree

12 files changed

+245
-23
lines changed

12 files changed

+245
-23
lines changed

TODO.rst

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ speleo.frontend
44

55
* I18N
66
* testing (performance, memory leaks)
7-
* add one page routing (server/frontend/both?)
8-
* save page state between switches (service)
97
* attach link to hue(configure)
108

9+
- pluggable utilities
10+
1111
--------------------------------------------------------
1212
common ui components
1313
--------------------------------------------------------
@@ -25,8 +25,16 @@ user profile page
2525
--------------------------------------------------------
2626

2727
* past dashboards
28-
* blocks
28+
* blocks /queries
2929
* information (readonly)
30+
* roles
31+
32+
--------------------------------------------------------
33+
user admin page
34+
--------------------------------------------------------
35+
36+
* user management
37+
* roles apply
3038

3139
--------------------------------------------------------
3240
plugins
@@ -42,7 +50,6 @@ Speleo Settings
4250
--------------------------------------------------------
4351

4452
* add chicken test to shutdown/delete
45-
* add roles
4653
* add all possible settings and bind them
4754

4855
========================================================
@@ -59,6 +66,8 @@ elastic search proxy
5966
- index schema
6067
- analyzers
6168

69+
* analyzer api dsl
70+
6271
--------------------------------------------------------
6372
service api
6473
--------------------------------------------------------
@@ -74,7 +83,7 @@ service alerts
7483
--------------------------------------------------------
7584

7685
* configure via service
77-
* monitoring service to send
86+
* speleo.monitor (percolations)
7887

7988
- email
8089
- sms
@@ -118,7 +127,6 @@ Speleo Dashboard
118127
Speleo Search
119128
--------------------------------------------------------
120129

121-
* query builder -> convert query to elastic search
122130
* click on chart and chart filter
123131
* sidebar for suggested tag filter
124132
* speed up slow updates

speleo.service/service/common.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from tornado.options import define, options
2+
3+
def dict_to_options(**kwargs):
4+
''' A helper method to quickly convert a dict to options
5+
6+
:param kwargs: The arguments to convert to options
7+
'''
8+
for key, value in kwargs.items():
9+
define(key, default=value, type=type(value))
10+
return options
11+

speleo.service/service/handlers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from service.handlers.error_handler import *
12
from service.handlers.root_handler import *
23
from service.handlers.contact_handler import *
34
from service.handlers.search_handler import *
@@ -7,3 +8,4 @@
78
from service.handlers.auth_handler import *
89
from service.handlers.simple_handler import *
910
from service.handlers.elastic_handler import *
11+
from service.handlers.profile_handler import *

speleo.service/service/handlers/auth_handler.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,28 @@
33
import tornado.auth
44
import tornado.web
55
from service.handlers.common import BaseHandler
6+
from service.models import User
7+
8+
9+
# ------------------------------------------------------------
10+
# helper methods
11+
# ------------------------------------------------------------
12+
def save_user(database, attributes):
13+
''' Given a user, save if the user doesn't exist
14+
otherwise update its data.
15+
16+
:param database: The database to save to
17+
:param attributes: The attributes to update with
18+
:returns: The user identifier
19+
'''
20+
user = database.query(User
21+
).filter_by(username=attributes['username']).first()
22+
if not user:
23+
user = User(**attributes)
24+
database.add(user)
25+
database.commit()
26+
logging.debug('saved new user %s' % user.id)
27+
return u"%s" % user.id
628

729

830
# ------------------------------------------------------------
@@ -20,7 +42,7 @@ def post(self):
2042
password = self.get_argument('password', '')
2143
session = self.security.authenticate(username, password)
2244
if session:
23-
self.set_secure_cookie('user', tornado.escape.json_encode(session))
45+
self.set_secure_cookie('user', save_user(self.db, session))
2446
self.redirect(self.get_argument('next', '/'))
2547
else: self.redirect('/auth/login')
2648

@@ -39,7 +61,7 @@ def get(self):
3961
def _on_auth(self, user):
4062
if not user:
4163
raise tornado.web.HTTPError(500, "Google authentication failed")
42-
self.set_secure_cookie("user", tornado.escape.json_encode(user))
64+
self.set_secure_cookie('user', save_user(self.db, session))
4365
self.redirect(self.get_argument("next", "/"))
4466

4567

@@ -57,7 +79,7 @@ def get(self):
5779
def _on_auth(self, user):
5880
if not user:
5981
raise tornado.web.HTTPError(500, "Twitter authentication failed")
60-
self.set_secure_cookie("user", tornado.escape.json_encode(user))
82+
self.set_secure_cookie('user', save_user(self.db, session))
6183
self.redirect(self.get_argument("next", "/"))
6284

6385

@@ -75,7 +97,7 @@ def get(self):
7597
def _on_auth(self, user):
7698
if not user:
7799
raise tornado.web.HTTPError(500, "Facebook authentication failed")
78-
self.set_secure_cookie("user", tornado.escape.json_encode(user))
100+
self.set_secure_cookie('user', save_user(self.db, session))
79101
self.redirect(self.get_argument("next", "/"))
80102

81103

speleo.service/service/handlers/common.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import tornado.web
22
import tornado.escape
3+
from service.models import User
34

45
class BaseHandler(tornado.web.RequestHandler):
56

@@ -20,6 +21,6 @@ def cache(self):
2021
return self.application.cache
2122

2223
def get_current_user(self):
23-
user_json = self.get_secure_cookie("user")
24-
if not user_json: return None
25-
return tornado.escape.json_decode(user_json)
24+
user_id = self.get_secure_cookie("user")
25+
if not user_id: return None
26+
return self.db.query(User).get(user_id)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import os
2+
import httplib
3+
import tornado.web
4+
5+
class ErrorHandler(tornado.web.RequestHandler):
6+
7+
_template = """
8+
<html>
9+
<head>
10+
<title>%(code)d %(message)s</title>
11+
<style>
12+
body { background: #fff; color: #000; }
13+
#main { padding: 10em; }
14+
#main h1 { font-size:40px; }
15+
#main img { opacity: 0.3; position:absolute; top:10em; left:30em; -webkit-transform:scale(1.5); }
16+
</style>
17+
</head>
18+
<body><div id='main'>
19+
<h1>%(code)d %(message)s</h1>
20+
<p>Not much else to see here...</p>
21+
<a href="/">Let's get you home</a>
22+
<img src='/static/img/helmet.png' />
23+
</div></body>
24+
</html>
25+
"""
26+
27+
def __init__(self, application, request, status_code):
28+
tornado.web.RequestHandler.__init__(self, application, request)
29+
self.set_status(status_code)
30+
31+
def get_error_html(self, status_code, **kwargs):
32+
return self._template % {
33+
"code": status_code,
34+
"message": httplib.responses[status_code],
35+
}
36+
37+
def prepare(self):
38+
raise tornado.web.HTTPError(self._status_code)
39+
40+
## override the tornado.web.ErrorHandler with our default ErrorHandler
41+
tornado.web.ErrorHandler = ErrorHandler
42+
43+
# ------------------------------------------------------------
44+
# exports
45+
# ------------------------------------------------------------
46+
__all__ = []
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import tornado.web
2+
from service.handlers.common import BaseHandler
3+
4+
class ProfileHandler(BaseHandler):
5+
6+
RoutePath = r'/profile/?'
7+
8+
def get(self):
9+
self.render('profile.html')
10+
11+
def post(self):
12+
pass
13+
14+
15+
# ------------------------------------------------------------
16+
# api methods
17+
# ------------------------------------------------------------
18+
class QueryApiHandler(BaseHandler):
19+
20+
RoutePath = r'/api/v1/user/query/(.*)'
21+
22+
@tornado.web.authenticated
23+
def get(self, qid):
24+
queries = self.get_current_user().queries
25+
if query:
26+
queries = [q for q in queries if q.id == qid]
27+
self.write({ 'data' : queries })
28+
29+
@tornado.web.authenticated
30+
def post(self, qid):
31+
# create or update
32+
pass
33+
34+
@tornado.web.authenticated
35+
def delete(self, qid):
36+
queries = self.get_current_user().queries
37+
for query in queries:
38+
if query.id == qid:
39+
queries.remove(query)
40+
if self.db.is_dirty(): self.db.commit()
41+
self.write({ 'data': 'OK' })
42+
43+
put = post
44+
45+
# ------------------------------------------------------------
46+
# exports
47+
# ------------------------------------------------------------
48+
__all__ = ['ProfileHandler']

speleo.service/service/models.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,29 @@ class User(Base):
4141
def __repr__(self):
4242
return "<User(%s)>" % (self.username)
4343

44+
45+
class Role(Base):
46+
47+
__tablename__ = 'roles'
48+
49+
id = Column(Integer, primary_key=True)
50+
name = Column(String(50), nullable=False)
51+
description = Column(String(100), nullable=False)
52+
53+
def __repr__(self):
54+
return "<Role(%s)>" % (self.name)
55+
56+
4457
class Query(Base):
4558

4659
__tablename__ = 'queries'
4760

4861
id = Column(Integer, primary_key=True)
49-
display = Column(String(250), nullable=False)
50-
compiled = Column(String(250), nullable=False)
62+
title = Column(String(50), nullable=False)
63+
display = Column(String(200), nullable=False)
64+
compiled = Column(String(200), nullable=True)
5165
user_id = Column(Integer, ForeignKey('users.id'))
5266
user = relationship("User", backref=backref('queries', order_by=id))
5367

5468
def __repr__(self):
55-
return "<Query(%s, %s)>" % (self.user.username, self.query)
69+
return "<Query(%s, %s)>" % (self.user.username, self.title)

speleo.service/service/security.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import crypt
2-
import pwd, spwd
2+
import pwd, spwd, grp
33
import logging
44

55
try:
@@ -23,8 +23,8 @@ def authenticate(self, username, password):
2323
'''
2424
logging.info("user %s logged in" % username)
2525
return {
26-
'name': username,
27-
'username': username,
26+
'name': username,
27+
'username': username,
2828
}
2929

3030

@@ -130,9 +130,9 @@ class UnixSecurity(object):
130130
__fields = {
131131
'name': { 'group': False, 'field': 'pw_name', },
132132
'username': { 'group': False, 'field': 'pw_name', },
133-
'uid': { 'group': False, 'field': 'pw_uid', },
134-
'gid': { 'group': False, 'field': 'pw_gid', },
135-
'comment': { 'group': False, 'field': 'pw_gecos', },
133+
#'id': { 'group': False, 'field': 'pw_uid', },
134+
'email': { 'group': False, 'field': 'pw_gecos', },
135+
#'gid': { 'group': False, 'field': 'pw_gid', },
136136
}
137137
__attrs = [m['field'] for m in __fields.values()]
138138

@@ -166,8 +166,15 @@ def _parse_fields(self, attrs):
166166
result = {}
167167
for key, meta in self.__fields.items():
168168
result[key] = getattr(attrs, meta['field'])
169+
#self._get_group_roles(result)
169170
return result
170171

172+
def _get_group_roles(self, user):
173+
user['roles'] = []
174+
for group in grp.getgrall():
175+
if user['username'] in group.gr_mem:
176+
user['roles'].append(group.gr_name)
177+
171178
def get_security(options):
172179
''' Factory for the security implementations
173180

speleo.service/static/css/main.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,7 @@ body {
193193
line-height:20px;
194194
padding: 10px;
195195
}
196+
197+
.profile-title {
198+
margin-bottom: 1em;
199+
}

0 commit comments

Comments
 (0)