def promote_user(self, from_jid, nick): ji_ref = api.actor_lookup_im(api.ROOT, from_jid.base()) if jid_ref: # TODO(tyler): Should we tell the user who they are? raise exception.ValidationError( "You already have an account and are signed in.") if not NICK_RE.match(nick): raise exception.ValidationError( "Invalid screen name, can only use letters or numbers, 3 to 16 " "characters") # Create the user. (user_create will check to see if the account has # already been created.) password = util.generate_uuid()[:8] # TODO(termie): Must have a first/last name. :( actor = api.user_create(api.ROOT, nick=nick, password=password, given_name=nick, family_name=nick) # link this im account to the user's account (equivalent of SIGN IN) self.sign_in(from_jid, nick, password) # Inform the user of their new password welcome = '\n'.join([ HELP_WELCOME_NICK % nick, HELP_PASSWORD % password, HELP_POST, HELP_CHANNEL_POST, HELP_COMMENT, HELP_FOLLOW, HELP_STOP, HELP_MORE, HELP_FOOTER ]) self.send_message([from_jid], welcome)
def avatar_photo_size(file): # file.size is in bytes if file.size > (settings.MAX_AVATAR_PHOTO_KB << 10): raise exception.ValidationError( "Avatar photo size must be under %s kilobytes" % (settings.MAX_AVATAR_PHOTO_KB, )) pass
def password_and_confirm(password, confirm, message="Your password", field=None): if password != confirm: raise exception.ValidationError('The passwords do not match', field) length_password(password, 6, 16, message, 'password')
def error_nonce(request, message=''): expected_now = util.create_nonce(None, message) expected_older = util.create_nonce(None, message, offset=-1) given = request.REQUEST.get('_error') if given not in (expected_now, expected_older): raise exception.ValidationError('Could not validate nonce')
def presence_extra(d, message=None): allowed_keys = set([ 'status', 'availability', 'location', 'senders_timestamp', 'activity', 'profile', 'presenceline', 'presenceline', 'bt', 'calendar', 'generated', 's60_settings' ]) if len(allowed_keys.union(set(d.keys()))) != len(allowed_keys): raise exception.ValidationError('illegal keys in presence')
def start_notifications(self, from_jid): jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base()) if not jid_ref: raise exception.ValidationError("You are not signed in.") actor_ref = api.settings_change_notify(api.ROOT, jid_ref.nick, im=True) self.send_message([from_jid], HELP_START_NOTIFICATIONS)
def sign_out(self, sender): sender_ref = api.actor_lookup_mobile(api.ROOT, sender) if not sender_ref: raise exception.ValidationError(HELP_SIGN_IN) mobile_ref = api.mobile_disassociate(api.ROOT, sender_ref.nick, sender) self.send_message([sender], HELP_SIGNED_OUT)
def sign_out(self, from_jid): jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base()) if not jid_ref: raise exception.ValidationError("You are not signed in.") im_ref = api.im_disassociate(api.ROOT, jid_ref.nick, from_jid.base()) self.send_message([from_jid], "signed out")
def channel_post(self, sender, channel_nick, message): sender_ref = api.actor_lookup_mobile(api.ROOT, sender) if not sender_ref: raise exception.ValidationError(HELP_SIGN_IN) comment_ref = api.channel_post(sender_ref, message=message, nick=sender_ref.nick, channel=channel_nick)
def mobile(value): if not value.startswith('+'): value = '+%s' % value match = MOBILE_RE_COMPILED.match(value) if not match: raise exception.ValidationError('Invalid mobile number') return value
def stop_notifications(self, sender): sender_ref = api.actor_lookup_mobile(api.ROOT, sender) if not sender_ref: raise exception.ValidationError(HELP_SIGN_IN) actor_ref = api.settings_change_notify(api.ROOT, sender_ref.nick, sms=False) self.send_message([sender], HELP_STOP_NOTIFICATIONS)
def bg_image(value, message='Invalid background image path'): """bg_image should always be in the form returned from api.background_upload. The case where this wouldn't happen is if the user is calling directly into the API (hence why clean.bg_image() is still necessary). """ if not value: return value if not BG_IMAGE_COMPILED.match(value): raise exception.ValidationError(message) return value
def channel_post(self, from_jid, channel_nick, message): jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base()) if not jid_ref: raise exception.ValidationError( "You must be signed in to post, please SIGN IN") comment_ref = api.channel_post(jid_ref, message=message, nick=jid_ref.nick, channel=channel_nick)
def mobile_number(mobile): # The standard mobile number validation method django.core.validators.isValidPhone # is not suitable for us, as it expects only US numbers in hyphen-format. field = "mobile" if len(mobile) < 9: raise exception.ValidationError( "Your mobile phone should be at least 9 digits long including the '+'", field) if not _international.match(mobile): raise exception.ValidationError( "Your mobile number must be in the international format with a '+' in front of it.", field) if not _numeric.match(mobile): raise exception.ValidationError( "Your mobile number can only be numbers besides the '+'", field) if _italian.match(mobile): raise exception.ValidationError( "Sorry, Italian numbers are currently blocked due to abuse.", field)
def nonce(request, action=''): user = request.user expected_now = util.create_nonce(user, action) expected_older = util.create_nonce(user, action, offset=-1) # TODO(termie): we should probably only accept these in POST in the future given = request.REQUEST.get('_nonce') if given not in (expected_now, expected_older): raise exception.ValidationError('Could not validate nonce')
def sign_in(self, sender, nick, password): sender_ref = api.actor_lookup_mobile(api.ROOT, sender) if sender_ref: raise exception.ValidationError( "You are already signed in, please SIGN OUT first") user_ref = user.authenticate_user_login(nick, password) if not user_ref: raise exception.ValidationError( "Username or password is incorrect") mobile_ref = api.mobile_associate(api.ROOT, user_ref.nick, sender) # if they need to double opt in send them the confirmation message welcome = ' '.join([ HELP_WELCOME_NICK % user_ref.display_nick(), HELP_POST, HELP_START, HELP_CHARGES ]) self.send_message([sender], welcome)
def login_login(request): redirect_to = request.REQUEST.get('redirect_to', '/') redirect_to = clean.redirect_to(redirect_to) if request.POST: try: login = request.POST.get('log', None) password = request.POST.get('pwd', None) rememberme = request.POST.get('rememberme', None) # TODO validate current_user = user.lookup_user_by_login(login, password) if current_user: if redirect_to == '/': redirect_to = current_user.url('/overview') # Attempt to do some cleanup on the user if necessary api.user_cleanup(api.ROOT, current_user.nick) # if we aren't hosted or aren't ssl just set the cookie and go home if (not settings.HOSTED_DOMAIN_ENABLED or not settings.SSL_LOGIN_ENABLED): response = http.HttpResponseRedirect(redirect_to) response = user.set_user_cookie(response, current_user, rememberme) return response # otherwise, we're going to have to redirect to set the cookie on # the proper domain sso_token = util.generate_uuid() cache.set('sso/%s' % sso_token, (current_user.nick, rememberme), timeout=10) sso_url = 'http://%s/login/noreally' % (settings.DOMAIN) sso_url = util.qsa(sso_url, { 'redirect_to': redirect_to, 'sso_token': sso_token }) return http.HttpResponseRedirect(sso_url) else: raise exception.ValidationError("Invalid username or password") except: exception.handle_exception(request) if request.user: if redirect_to == '/': redirect_to = request.user.url('/overview') return http.HttpResponseRedirect(redirect_to) c = template.RequestContext(request, locals()) t = loader.get_template('login/templates/login.html') return http.HttpResponse(t.render(c))
def sign_in(self, from_jid, nick, password): jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base()) if jid_ref: raise exception.ValidationError( "You are already signed in, please SIGN OUT first") user_ref = user.authenticate_user_login(nick, password) if not user_ref: raise exception.ValidationError( "Username or password is incorrect") im_ref = api.im_associate(api.ROOT, user_ref.nick, from_jid.base()) welcome = '\n'.join([ HELP_WELCOME_NICK % user_ref.display_nick(), HELP_POST, HELP_CHANNEL_POST, HELP_COMMENT, HELP_FOLLOW, HELP_STOP, HELP_MORE, HELP_FOOTER ]) self.send_message([from_jid], welcome)
def common_photo_upload(request, success="/", nick=None): if not nick: nick = request.user.nick if request.FILES: try: # we're going to handle a file upload, wee validate.nonce(request, 'change_photo') img = request.FILES.get('imgfile') if not img: raise exception.ValidationError('imgfile must be set') validate.avatar_photo_size(img) img_url = api.avatar_upload(request.user, nick, img.read()) api.avatar_set_actor(request.user, nick, img_url) return util.RedirectFlash(success, "Avatar uploaded") except: exception.handle_exception(request) elif 'avatar' in request.POST: try: validate.nonce(request, 'change_photo') avatar_path = request.POST.get('avatar') if not avatar_path: raise exception.ValidationError('avatar must be set') rv = api.avatar_set_actor(request.user, nick, avatar_path) if not rv: raise exception.ValidationError('failed to set avatar') return util.RedirectFlash(success, "Avatar changed") except: exception.handle_exception(request) if 'delete' in request.REQUEST: try: validate.nonce(request, 'delete_photo') validate.confirm_dangerous(request, 'Delete your photo?') rv = api.avatar_clear_actor(request.user, nick) return util.RedirectFlash(success, "Avatar deleted") except: exception.handle_exception(request)
def add_comment(self, sender, nick, message): sender_ref = api.actor_lookup_mobile(api.ROOT, sender) if not sender_ref: raise exception.ValidationError(HELP_SIGN_IN) logging.debug("comment: %s %s %s", nick, sender_ref.nick, message) nick = clean.nick(nick) stream_entry = api.reply_get_cache(sender=nick, target=sender_ref.nick, service='sms') if not stream_entry: # Well, or memcache timed it out... Or we crashed... Or... Or... raise exception.ValidationError( 'The message to which you tried to respond doesn\'t exist') api.entry_add_comment(sender_ref, entry=stream_entry.keyname(), content=message, nick=sender_ref.nick, stream=stream_entry.stream)
def add_comment(self, from_jid, nick, message): jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base()) if not jid_ref: raise exception.ValidationError( "You must be signed in to post, please SIGN IN") logging.debug("comment: %s %s %s", nick, jid_ref.nick, message) nick = clean.nick(nick) stream_entry = api.reply_get_cache(sender=nick, target=jid_ref.nick, service='im') if not stream_entry: # Well, or memcache timed it out... Or we crashed... Or... Or... raise exception.ValidationError( 'The message to which you tried to respond doesn\'t exist') api.entry_add_comment(jid_ref, entry=stream_entry.keyname(), content=message, nick=jid_ref.nick, stream=stream_entry.stream)
def channel_join(self, sender, nick): sender_ref = api.actor_lookup_mobile(api.ROOT, sender) if not sender_ref: raise exception.ValidationError(HELP_SIGN_IN) channel = clean.channel(nick) try: api.channel_join(sender_ref, sender_ref.nick, channel) self.send_message( (sender, ), "%s joined %s" % (sender_ref.display_nick(), nick)) except: self.send_message((sender, ), "Failed to join %s" % nick)
def url(value, message='Invalid url'): # If no URL scheme given, assume http:// if value and '://' not in value: value = u'http://%s' % value # If no URL path given, assume / if value and not urlparse.urlsplit(value)[2]: value += '/' match = URL_RE.match(value) if not match: raise exception.ValidationError(message) return value
def confirm(self, sender): """ confirm something if something needs to be confirmed otherwise, just post the message """ sender_ref = api.actor_lookup_mobile(api.ROOT, sender) if not sender_ref: raise exception.ValidationError(HELP_SIGN_IN) if sender_ref.extra.get('sms_double_opt_in', None): api.mobile_confirm_doubleoptin(api.ROOT, sender_ref.nick) self.start_notifications(sender)
def actor_remove_contact(self, sender, nick): sender_ref = api.actor_lookup_mobile(api.ROOT, sender) if not sender_ref: raise exception.ValidationError(HELP_SIGN_IN) clean_nick = clean.nick(nick) try: api.actor_remove_contact(sender_ref, sender_ref.nick, clean_nick) self.send_message( (sender, ), "%s stopped following %s" % (sender_ref.dispaly_nick(), nick)) except: self.send_message((sender, ), "Failed to stop following %s" % nick)
def actor_remove_contact(self, from_jid, nick): jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base()) if not jid_ref: raise exception.ValidationError( "You must be signed in to post, please SIGN IN") nick = clean.nick(nick) try: api.actor_remove_contact(jid_ref, jid_ref.nick, nick) self.send_message((from_jid, ), "%s stopped following %s" % (jid_ref.nick, nick)) except: self.send_message((from_jid, ), "Leave FAILED: %s" % nick)
def channel_join(self, from_jid, nick): jid_ref = api.actor_lookup_im(api.ROOT, from_jid.base()) if not jid_ref: raise exception.ValidationError( "You must be signed in to join a channel, please SIGN IN") channel = clean.channel(nick) try: api.channel_join(jid_ref, jid_ref.nick, channel) self.send_message((from_jid, ), "%s joined %s" % (jid_ref.nick, channel)) except: self.send_message((from_jid, ), "Join FAILED: %s" % channel)
def user(value, message='Invalid nick'): """ expects to get a nick in one of the following forms: popular [email protected] """ value = encoding.smart_unicode(value) if not value.endswith('@%s' % settings.NS_DOMAIN): value = '%s@%s' % (value, settings.NS_DOMAIN) match = USER_COMPILED.match(value) if not match: raise exception.ValidationError(message) return value
def start_notifications(self, sender): sender_ref = api.actor_lookup_mobile(api.ROOT, sender) if not sender_ref: raise exception.ValidationError(HELP_SIGN_IN) if sender_ref.extra.get('sms_double_opt_in', None): message = ' '.join([HELP_DOUBLE_OPT_IN, HELP_CHARGES]) self.send_message([sender], message) return actor_ref = api.settings_change_notify(api.ROOT, sender_ref.nick, sms=True) message = ' '.join([HELP_START_NOTIFICATIONS, HELP_CHARGES]) self.send_message([sender], message)
def send(to_email, subject, message, on_behalf=None, html_message=None): on_behalf = on_behalf and on_behalf or settings.DEFAULT_FROM_EMAIL if is_allowed_to_send_email_to(to_email): email_message = mail.EmailMultiAlternatives(subject=subject, body=message, from_email=on_behalf, to=(to_email, )) if html_message: email_message.attach_alternative(html_message, mimetype="text/html") # uses the default email sender, see DEFAULT_FROM_EMAIL in settings.py # if on_behalf is None fail_silently = settings.MANAGE_PY return email_message.send(fail_silently) else: log_blocked_send(on_behalf, to_email, subject, message) raise exception.ValidationError("Cannot send to that email address")