def forget_password(self, *args, **kw): try: email_address = kw['email_address'] user=DBSession.query(User).filter_by(email_address=email_address).first() if not user: return dict(success=False, error_code=ErrorCode.NONEXISTEDUSER) log.info("Reset password: %s"%email_address) reset_pwd = ResetPassword() reset_pwd.email_address=email_address reset_pwd.code = Registration.generate_code(email_address) DBSession.add(reset_pwd) DBSession.flush() email_data = {'sender':config['registration.email_sender'], 'subject':_('Message from Jminee'), 'body':''' Please click on this link to reset your password %s ''' % (url_for(self.mount_point+'/confirm_reset', code=reset_pwd.code, email=reset_pwd.email_address, qualified=True))} send_email(reset_pwd.email_address, email_data['sender'], email_data['subject'], email_data['body']) except Exception as e: log.exception('Got exception') return dict(success=False) return dict(success=True)
def activate(self, email, code): try: log.info('User activation email=%s code=%s'%(email, code)) Registration.clear_expired_user(email) reg = Registration.get_inactive(email, code) if not reg: user=DBSession.query(User).filter_by(email_address=email).first() if user: return dict() else: return redirect('/registration/error') u = User(user_name=reg.user_name, display_name=reg.user_name, email_address=reg.email_address, password=reg.password) DBSession.add(u) reg.user = u reg.password = '******' reg.activated = datetime.now() return dict() except: log.exception('Got exception') #TODO return error page return redirect('/registration/error', message='Sorry your account cannot be activated. Please send email to ...')
def index(self, *args, **kw): try: log.info('User registration: %s'%str(kw)) new_reg = Registration() new_reg.email_address = kw['email_address'] new_reg.user_name = kw['email_address'] new_reg.password = kw['password'] new_reg.code = Registration.generate_code(kw['email_address']) DBSession.add(new_reg) DBSession.flush() email_data = {'sender':config['registration.email_sender'], 'subject':_('Message from Jminee'), 'body':''' Please click on this link to confirm your registration %s ''' % (url_for(self.mount_point+'/activate', code=new_reg.code, email=new_reg.email_address, qualified=True))} send_email(new_reg.email_address, email_data['sender'], email_data['subject'], email_data['body']) except Exception as e: log.exception('Got exception') return dict(success=False) return dict(success=True, email=kw['email_address'])
def get_subjects(self, **kw): try: #check if user is a member of this topic user_id = request.identity['user'].user_id user = DBSession.query(MemberTopic).\ filter(MemberTopic.topic_id==kw['topic_id'], MemberTopic.member_id==user_id).\ first() if not user: #This should never happen log.error("User %s is not a member of topic %s or topic does not exist" %(user_id,kw['topic_id'])) return dict(success=False, error_code=ErrorCode.UNAUTHORIZED) if not kw.has_key('nums'): nums = self.MAX_MESSAGE_SIZE else: nums = kw['nums'] subjects = DBSession.query(Subject).\ filter(Subject.topic_id == kw['topic_id']).\ order_by(Subject.time.desc()).\ limit(nums).\ all() return dict(success=True, subjects=subjects) except: log.exception('Got exception') #traceback.print_exc(file=sys.stdout) return dict(success=False)
def validate_python(self, value, state): super(UniqueEmailValidator, self).validate_python(value, state) if re.match("^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$", value): reg = DBSession.query(User).filter_by(email_address=value).first() user = DBSession.query(User).filter_by(email_address=value).first() if reg or user: raise Invalid(_('Email address has already been taken'), value, state) else: raise Invalid(_('Invalid email'), value, state)
def validate_python(self, value, state): super(UniqueUserValidator, self).validate_python(value, state) if re.match("^[a-zA-Z0-9_-]*[a-zA-Z_-][a-zA-Z0-9_-]*$", value): reg = DBSession.query(User).filter_by(user_name=value).first() user = DBSession.query(User).filter_by(user_name=value).first() if reg or user: raise Invalid(_('Username already in use.'), value, state) else: raise Invalid(_('Invalid username'), value, state)
def create_comment(self, **kw): try: #check if this user can create a comment in this topic #for now every member of the topic can create a comment creator = DBSession.query(MemberTopic).\ filter(MemberTopic.topic_id==kw['topic_id'], MemberTopic.member_id==request.identity['user'].user_id).\ first() if not creator: #TODO: this should never happen, log this event and return only False return dict(success=False, error_code=ErrorCode.UNAUTHORIZED) comment = Comment() comment.subject_id = kw['subject_id'] comment.creator_id = request.identity['user'].user_id comment.content = kw['content'] DBSession.add(comment) DBSession.flush() #TODO: should not query then update, should only update topic = DBSession.query(Topic).\ filter(Topic.uid==kw['topic_id']).first() #TODO: need to rethink this time var, how about subject update_time topic.update_time = comment.time log.info("User %s creates comment %s"%(comment.creator_id, comment)) subject_title = DBSession.query(Subject.title).\ filter(Subject.uid==kw['subject_id']).first()[0] members = DBSession.query(User.email_address).\ filter(MemberTopic.topic_id==kw['topic_id'], MemberTopic.member_id!=creator.member_id, MemberTopic.deleted==False, MemberSubject.subject_id==kw['subject_id'], MemberSubject.muted==False).\ join(MemberTopic,MemberSubject).\ all() member_emails = [member[0] for member in members] #send notification to users notif=dict(type='new_comment',topic=topic.title,subject=subject_title,comment=comment.content, registered_users=member_emails,user_name=request.identity['user'].user_name) log.info('Sending SNS notification: %s'%notif) sns=SNSConnection(config.get('AWS_ACCESS_KEY_ID'), config.get("AWS_SECRET_ACCESS_KEY")) sns.publish(config.get('sqs_user_notification'),js.dumps(notif)) return dict(success=True, comment=dict(uid=comment.uid, time=comment.time)) except Exception as e: log.exception('Got exception %s'%e) #traceback.print_exc(file=sys.stdout) return dict(success=False)
def reset_password(self, *agrs, **kw): try: log.info('User reset password: %s'%str(kw)) ResetPassword.clear_expired_user(kw['email_address']) reset = ResetPassword.get_inactive(kw['email_address'], kw['code']) if not reset: return dict(success=False, error_code=ErrorCode.NORESETRECORD) user=DBSession.query(User).filter_by(email_address=kw['email_address']).first() user.password = kw['password'] reset.email = kw['email_address'] reset.reset = datetime.now() DBSession.flush() return dict(success=True) except Exception as e: log.exception('Got exception') return dict(success=False, error_code=ErrorCode.OTHERS)
def generate_code(cls, email): code_space = string.ascii_letters + string.digits def _generate_code_impl(): base = ''.join(random.sample(code_space, 8)) base += email base += str(time.time()) return sha256(base).hexdigest() code = _generate_code_impl() while DBSession.query(cls).filter_by(code=code).first(): code = _generate_code_impl() return code
def email_exist(self, *agrs, **kw): try: log.info('Check email existence: %s'%str(kw)) user=DBSession.query(User).filter_by(email_address=kw['email']).first() if user: return dict(success=True, email_exist=True) return dict(success=True, email_exist=False) except Exception as e: log.exception('Got exception') return dict(success=False, error_code=ErrorCode.OTHERS)
def get_comments(self, **kw): try: #check if user is a member of this topic user_id = request.identity['user'].user_id user = DBSession.query(MemberTopic).\ filter(MemberTopic.topic_id==kw['topic_id'], MemberTopic.member_id==user_id).\ first() if not user: #This should never happen log.error("User %s is not a member of topic %s or topic does not exist" %(user_id,kw['topic_id'])) return dict(success=False, error_code=ErrorCode.UNAUTHORIZED) if not kw.has_key('nums'): nums = self.MAX_MESSAGE_SIZE else: nums = kw['nums'] comments = DBSession.query(Comment,User.user_name).\ filter(Comment.subject_id == kw['subject_id'], Comment.deleted == False).\ join("creator").\ order_by(Comment.time).\ limit(nums).\ all() #TODO: there should be a better way to do this new_comments = [] for comment in comments: new_comments.append(comment[0]) new_comments[-1].creator_name = comment[1] return dict(success=True, comments=new_comments) except: log.exception('Got exception') #traceback.print_exc(file=sys.stdout) return dict(success=False)
def setUp(self): """Prepare model test fixture.""" try: new_attrs = {} new_attrs.update(self.attrs) new_attrs.update(self.do_get_dependencies()) self.obj = self.klass(**new_attrs) DBSession.add(self.obj) DBSession.flush() return self.obj except: DBSession.rollback() raise
def test_query_obj(self): """Model objects can be queried""" obj = DBSession.query(self.klass).one() for key, value in self.attrs.iteritems(): assert_equals(getattr(obj, key), value)
def clear_expired_user(cls, email_address): expired = DBSession.query(cls).filter_by(email_address=email_address)\ .filter(Registration.time<datetime.now()-timedelta(7)).delete()
def clear_expired(cls): expired = DBSession.query(cls).filter(Registration.time<datetime.now()-timedelta(7)).delete()
def clear_expired_user(cls, email_address): expired = DBSession.query(cls).filter_by(reset=None)\ .filter_by(email_address=email_address)\ .filter(ResetPassword.time<datetime.now()-timedelta(0,300)).delete()
def get_inactive(cls, email_address, code): return DBSession.query(cls).filter_by(activated=None)\ .filter_by(code=code)\ .filter_by(email_address=email_address).first()
def by_user_name(cls, username): """Return the user object whose user name is ``username``.""" return DBSession.query(cls).filter_by(user_name=username).first()
def get_inactive(cls, email_address, code): return DBSession.query(ResetPassword).filter_by(reset=None)\ .filter_by(code=code)\ .filter_by(email_address=email_address).first()
def by_email_address(cls, email): """Return the user object whose email address is ``email``.""" return DBSession.query(cls).filter_by(email_address=email).first()
def create_topic(self, *args, **kw): topic = Topic() topic.creator_id = request.identity['user'].user_id log.debug("Query string: %s"%kw) if kw.has_key('title'): topic.title = kw['title'] else: #TODO: create topic named after all member return dict(success=False) if kw.has_key('logourl'): topic.logourl = kw['logourl'] #creator is always a member of the topic membertopic = MemberTopic(role='c', local_title=topic.title, member_id=topic.creator_id) topic.members.append(membertopic) #do not change the order of the following if clause members = [] if kw.has_key('members'): if isinstance(kw['members'], list): members = kw['members'] elif kw['members']!='' and isinstance(kw['members'], unicode): members = [kw['members']] try: # check if each member is in the User table # if not add him to nonexists list nonregistered_users = [] registered_users = DBSession.query(User.email_address, User.user_id)\ .filter(User.email_address.in_(members)).all() registered_email_address = [user[0] for user in registered_users] registered_user_ids = [user[1] for user in registered_users] log.debug(registered_users) if len(registered_users)!=len(members): for user in members: if user not in registered_email_address: log.info("User %s is not in the database"%user) nonregistered_users.append(user) for member_id in registered_user_ids: if member_id == topic.creator_id: continue member_topic = MemberTopic(role='c', local_title=topic.title, member_id=member_id) topic.members.append(member_topic) DBSession.add(topic) DBSession.flush() main_res = dict() #if there is subject to be created, then create it, return error_code if failed if kw.has_key('subject'): if kw.has_key('message'): res=self.create_subject(topic_id=topic.uid, title=kw['subject'], content=kw['message']) else: res=self.create_subject(topic_id=topic.uid, title=kw['subject']) if res['success']==False: main_res['error_code'] = ErrorCode.CREATSUBJECTFAILED #TODO: check main_res before sending notification #send notification to users notif=dict(type='new_topic',topic=topic.title,registered_users=members, user_name=request.identity['user'].user_name) log.info('Sending SNS notification: %s'%notif) sns=SNSConnection(config.get('AWS_ACCESS_KEY_ID'), config.get("AWS_SECRET_ACCESS_KEY")) sns.publish(config.get('sqs_user_notification'),js.dumps(notif)) if len(nonregistered_users): main_res.update(dict(success=True, topic=dict(uid=topic.uid, time=topic.time), nonregistered_users=nonregistered_users)) else: main_res.update(dict(success=True, topic=dict(uid=topic.uid, time=topic.time, creator_id=topic.creator_id, update_time=topic.time, title=topic.title, logourl=topic.logourl))) return main_res except Exception as e: log.exception("Got exception: %s"%e) return dict(success=False)
def get_topics(self, **kw): """ Get a number of topic in a range of date or indices inputs: optional string title; //topic title optional int nums; //numbers of topics optional date max_time; optional date min_time; """ try: if not kw.has_key('nums'): nums = self.MAX_TOPIC_SIZE + 1 # see: https://github.com/bachbui2/Jminee/issues/7 else: #TODO: make sure kw['num'] is an int nums = int(kw['nums']) + 1 # see: https://github.com/bachbui2/Jminee/issues/7 user_id = request.identity['user'].user_id log.info("User %s get topics %s"%(user_id, str(kw))) if kw.has_key('title'): topics = DBSession.query(Topic).\ join(MemberTopic).\ filter(Topic.title==kw['title']).\ filter(MemberTopic.member_id==user_id).\ order_by(Topic.update_time.desc()).\ limit(nums).\ all() elif kw.has_key('max_time') and kw.has_key('min_time'): max_time = kw['max_time'] min_time = kw['min_time'] topics = DBSession.query(Topic).\ join(MemberTopic).\ filter(sql.between(Topic.time, min_time, max_time)).\ filter(MemberTopic.member_id==user_id).\ order_by(Topic.update_time.desc()).\ limit(nums).\ all() elif kw.has_key('max_time'): max_time = kw['max_time'] topics = DBSession.query(Topic).\ join(MemberTopic).\ filter(Topic.time<=max_time).\ filter(MemberTopic.member_id==user_id).\ order_by(Topic.update_time.desc()).\ limit(nums).\ all() elif kw.has_key('min_time'): min_time = kw['min_time'] topics = DBSession.query(Topic).\ join(MemberTopic).\ filter(Topic.time>=min_time).\ filter(MemberTopic.member_id==user_id).\ order_by(Topic.update_time.desc()).\ limit(nums).\ all() else: topics = DBSession.query(Topic).\ join(MemberTopic).\ filter(MemberTopic.member_id==user_id).\ order_by(Topic.update_time.desc()).\ limit(nums).\ all() more = False if len(topics) == nums: topics = topics[:nums-1] more = True for topic in topics: new_msg_cnt = DBSession.query(MemberSubject).\ join(Subject).\ filter(MemberSubject.member_id==user_id).\ filter(Subject.topic_id==topic.uid).count() topic.new_msg = new_msg_cnt log.info(new_msg_cnt) return dict(success=True, topics=topics, more=more) except Exception as e: #traceback.print_exc(file=sys.stdout) log.exception('Got exception') return dict(success=False)
def tearDown(self): """Finish model test fixture.""" DBSession.rollback()
def create_subject(self, **kw): try: #check if this user can create a subject in this topic creator = DBSession.query(MemberTopic).\ filter(MemberTopic.topic_id==kw['topic_id'], MemberTopic.member_id==request.identity['user'].user_id, 'role = "c" or role = "s"').\ first() if not creator: #TODO: this should never happen, log this event and return only False return dict(success=False, error_code=ErrorCode.UNAUTHORIZED) #add new subject to the database subject = Subject() subject.topic_id = kw['topic_id'] subject.title = kw['title'] subject.creator_id = request.identity['user'].user_id DBSession.add(subject) DBSession.flush() comment = None if kw.has_key('content'): comment = Comment() comment.subject_id = subject.uid comment.creator_id = request.identity['user'].user_id comment.content = kw['content'] DBSession.add(comment) DBSession.flush() #add creator to member_subject if comment: member_subject = MemberSubject(member_id = creator.member_id, subject_id = subject.uid, last_read = comment.uid) else: member_subject = MemberSubject(member_id = creator.member_id, subject_id = subject.uid, last_read = 0) subject.members.append(member_subject) # registered_users = DBSession.query(User.email_address).filter(User.email_address.in_(members)).all() members = DBSession.query(MemberTopic.member_id,User.email_address).\ filter(MemberTopic.topic_id==kw['topic_id'], MemberTopic.member_id!=creator.member_id, MemberTopic.deleted == False).\ join(User).\ all() #add other members to member_subject table member_ids = [member[0] for member in members] for member_id in member_ids: member_subject = MemberSubject(member_id = member_id, subject_id = subject.uid, last_read = 0) subject.members.append(member_subject) topic = DBSession.query(Topic).\ filter(Topic.uid==kw['topic_id']).first() #TODO: need to rename/rethink this time vars topic.update_time = subject.time log.info("User %s creates subject %s"%(creator.member_id, subject)) member_emails = [member[1] for member in members] #send notification to users if len(member_emails)>0: notif=dict(type='new_subject',topic=topic.title,subject=subject.title, registered_users=member_emails,user_name=request.identity['user'].user_name) log.info('Sending SNS notification: %s'%notif) sns=SNSConnection(config.get('AWS_ACCESS_KEY_ID'), config.get("AWS_SECRET_ACCESS_KEY")) sns.publish(config.get('sqs_user_notification'),js.dumps(notif)) return dict(success=True, subject=dict(uid=subject.uid, time=subject.time)) except Exception as e: log.exception('Got exception %s'%e) #traceback.print_exc(file=sys.stdout) return dict(success=False)