]>
git.ipfire.org Git - ipfire.org.git/blob - src/web/users.py
11 from . import ui_modules
13 COLOUR_LIGHT
= (237,232,232)
14 COLOUR_DARK
= (49,53,60)
16 class IndexHandler(base
.BaseHandler
):
17 @tornado.web
.authenticated
22 q
= self
.get_argument("q", None)
26 results
= self
.backend
.accounts
.search(q
)
28 self
.render("users/index.html", q
=q
, results
=results
)
31 class ShowHandler(base
.BaseHandler
):
32 @tornado.web
.authenticated
34 account
= self
.backend
.accounts
.get_by_uid(uid
)
36 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
38 self
.render("users/show.html", account
=account
)
41 class AvatarHandler(base
.BaseHandler
):
43 # Get the desired size of the avatar file
44 size
= self
.get_argument("size", None)
48 except (TypeError, ValueError):
51 logging
.debug("Querying for avatar of %s" % uid
)
54 account
= self
.backend
.accounts
.get_by_uid(uid
)
56 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
58 # Allow downstream to cache this for a year
59 self
.set_expires(31536000)
62 avatar
= account
.get_avatar(size
)
64 # If there is no avatar, we serve a default image
66 logging
.debug("No avatar uploaded for %s" % account
)
68 # Generate a random avatar with only one letter
69 avatar
= self
._get
_avatar
(account
, size
=size
)
72 type = imghdr
.what(None, avatar
)
74 # If we could not guess the type, we will try something else
76 # Could this be an SVG file?
77 if avatar
.startswith(b
"<"):
80 # Set headers about content
81 self
.set_header("Content-Disposition", "inline; filename=\"%s.%s\"" % (account
.uid
, type))
83 self
.set_header("Content-Type", "image/%s" % type)
88 def _get_avatar(self
, account
, size
=None, **args
):
89 letter
= ("%s" % account
)[0].upper()
94 # The generated avatar cannot be larger than 1024px
99 key
= "avatar:letter:%s:%s" % (letter
, size
)
101 # Fetch avatar from the cache
102 avatar
= self
.memcached
.get(key
)
104 avatar
= self
._make
_avatar
(letter
, size
=size
, **args
)
107 self
.memcached
.set(key
, avatar
)
111 def _make_avatar(self
, letter
, format
="PNG", size
=None, **args
):
112 # Generate an image of the correct size
113 image
= PIL
.Image
.new("RGBA", (size
, size
), COLOUR_LIGHT
)
116 draw
= PIL
.ImageDraw
.Draw(image
)
119 font
= PIL
.ImageFont
.truetype(os
.path
.join(
120 self
.application
.settings
.get("static_path", ""),
121 "fonts/Prompt-Bold.ttf"
122 ), size
, encoding
="unic")
124 # Determine size of the printed letter
125 w
, h
= font
.getsize(letter
)
127 # Mukta seems to be very broken and the height needs to be corrected
130 # Draw the letter in the center
131 draw
.text(((size
- w
) / 2, (size
- h
) / 2), letter
,
132 font
=font
, fill
=COLOUR_DARK
)
134 with io
.BytesIO() as f
:
135 # If writing out the image does not work with optimization,
136 # we try to write it out without any optimization.
138 image
.save(f
, format
, optimize
=True, **args
)
140 image
.save(f
, format
, **args
)
145 class PasswdHandler(base
.BaseHandler
):
146 @tornado.web
.authenticated
148 account
= self
.backend
.accounts
.get_by_uid(uid
)
150 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
152 # Check for permissions
153 if not account
.can_be_managed_by(self
.current_user
):
154 raise tornado
.web
.HTTPError(403, "%s cannot manage %s" % (self
.current_user
, account
))
156 self
.render("users/passwd.html", account
=account
)
158 @tornado.web
.authenticated
160 account
= self
.backend
.accounts
.get_by_uid(uid
)
162 raise tornado
.web
.HTTPError(404, "Could not find account %s" % uid
)
164 # Check for permissions
165 if not account
.can_be_managed_by(self
.current_user
):
166 raise tornado
.web
.HTTPError(403, "%s cannot manage %s" % (self
.current_user
, account
))
168 # Get current password
169 password
= self
.get_argument("password")
172 password1
= self
.get_argument("password1")
173 password2
= self
.get_argument("password2")
175 # Passwords must match
176 if not password1
== password2
:
177 raise tornado
.web
.HTTPError(400, "Passwords do not match")
179 # XXX Check password complexity
181 # Check if old password matches
182 if not account
.check_password(password
):
183 raise tornado
.web
.HTTPError(403, "Incorrect password for %s" % account
)
186 account
.passwd(password1
)
188 # Redirect back to user's page
189 self
.redirect("/users/%s" % account
.uid
)
192 class GroupIndexHandler(base
.BaseHandler
):
193 @tornado.web
.authenticated
195 # Only staff can see other groups
196 if not self
.current_user
.is_staff():
197 raise tornado
.web
.HTTPError(403)
199 self
.render("users/groups/index.html")
202 class GroupShowHandler(base
.BaseHandler
):
203 @tornado.web
.authenticated
205 # Only staff can see other groups
206 if not self
.current_user
.is_staff():
207 raise tornado
.web
.HTTPError(403)
210 group
= self
.backend
.groups
.get_by_gid(gid
)
212 raise tornado
.web
.HTTPError(404, "Could not find group %s" % gid
)
214 self
.render("users/groups/show.html", group
=group
)
217 class ListModule(ui_modules
.UIModule
):
218 def render(self
, accounts
, show_created_at
=False):
219 return self
.render_string("users/modules/list.html", accounts
=accounts
,
220 show_created_at
=show_created_at
)