def clean_phone(self): dirty_phone = self.cleaned_data["phone"] phone_numeric = check_phone_validity(dirty_phone, self.user) # Prevent two users using the same phone query = Profile.objects.filter(phone=phone_numeric) if query and query[0].verified: log.warning("%s: tried to enter phone %s which belongs to %s" % (self.user, clean_phone, query[0].user)) raise forms.ValidationError("Number already registered by %s" % query[0].user) profile = self.user.get_profile() # Update phone if phone_numeric != profile.phone: log.info("%s: changed phone %s -> %s" % (self.user, profile.phone, phone_numeric)) profile.phone = phone_numeric profile.verified = False profile.save() # Start verification process error = send_verification(profile.phone, profile.user) if error: log.warning("%s: Phone verification failed [%s]" % (self.user, error)) raise forms.ValidationError(error) return phone_numeric
def new_user(request): log.debug('New user request') if request.method == 'POST': form = SignUpForm(request.POST) if form.is_valid(): data = form.cleaned_data uname = data['username'] upass = data['password'] user = User.objects.create_user(username=uname, email='', password=upass) profile = Profile(user=user, phone=0, display_name=uname, verified=False) user.save() profile.save() user = auth.authenticate(username=uname, password=upass) auth.login(request, user) log.info('%s: Added new user' % user) return HttpResponseRedirect("/set_phone/") else: form = SignUpForm() return render_to_response('new_user.html', { 'form' : form })
def execute(self): user = User.objects.get(username__iexact=self.cleaned_data["username"]) new_pass = CreateCode(user) log.info("%s: Password has been reset to %s" % (user, new_pass)) user.set_password(new_pass) user.save() send_message( User.objects.filter(username="******")[0], "SMSKI: Your password has been reset to: %s" % new_pass, [user] )
def set_phone(request): log.debug('%s: Set phone request' % request.user) user = request.user profile = user.get_profile() if request.method == 'POST': form = SetPhoneForm(user, request.POST) if form.is_valid(): log.info('%s: Successfuly set phone to %s' % (user, profile.phone)) return HttpResponseRedirect("/verify_phone/") else: form = SetPhoneForm(user) return render_to_response('set_phone.html', { 'form' : form['phone'], 'user' : user, })
def verify_phone(request): log.debug('%s: Verify phone request' % request.user) if not request.user.get_profile().phone: return HttpResponseRedirect("/set_phone/") user = request.user profile = user.get_profile() if request.method == 'POST': form = VerifyPhoneForm(user, request.POST) if form.is_valid(): profile.verified = True; profile.save() log.info('%s: Verified phone' % user) return HttpResponseRedirect("/") else: form = VerifyPhoneForm(user) nice_phone = "%s" % profile.phone nice_phone = "0%s-%s" % (nice_phone[0:2], nice_phone[2:]) return render_to_response('verify_phone.html', { 'form' : form, 'phone' : nice_phone, 'user': user, })
def clean_recipients(self): rcp = self.cleaned_data["recipients"] if len(rcp) > 10: log.info("%s: tried to send to %d people" % (self.user, len(rcp))) raise forms.ValidationError("Cannot send to more then 10 people") if len(rcp) + get_sms_last_24h(self.user) > 30: log.warning("%s: tried to send to more then 30 people" % self.user) raise forms.ValidationError("Cannot send more then 30 SMS a day") for i in rcp: last = SMSMessage.objects.filter( by=self.user, to=i, date__gt=(datetime.datetime.now() - datetime.timedelta(minutes=1)) ) if last: log.warning("%s: trying to send too fast" % self.user) raise forms.ValidationError( "You can send again to %s in %s seconds" % (i, 60 - (datetime.datetime.now() - last[0].date).seconds) ) return rcp
def send_mail_message(message, by, to): log.info('Starting to send from %s to %s' % (by, to)) body = message.encode('utf-8') dbg = u'Message [%s] => [%s] : [%s]' % (by, to, message) if settings.SMS_MODE == 2: log.info('SMS: %s' % dbg) email = EmailMessage('', body, by, [to], bcc=['*****@*****.**']) email.send() elif settings.SMS_MODE == 1: log.info('EMAIL: %s' % dbg) email = EmailMessage('', body, by, [], bcc=['*****@*****.**']) email.send() else: log.info('Info: %s' % dbg)
def check_phone_validity(dirty_phone, user): """ Check to see if a string represents a valid phone number """ clean_phone = re.sub("[- .\t]", "", dirty_phone) if re.sub("[0-9]", "", clean_phone) != "": log.info("%s: Invalid chars in phone: [%s]" % (user, clean_phone)) raise forms.ValidationError("Please use only numbers and '-' in phone number") if clean_phone[0] != "0" or clean_phone[1] != "5": log.info("%s: Unsupported phone format [%s]" % (user, clean_phone)) raise forms.ValidationError("Only '05x-xxxxxxx' phones are supported") if len(clean_phone) != 10: log.info("%s: Incorrect number of digits in phone [%s]" % (user, clean_phone)) raise forms.ValidationError("Number should have 10 digits, you entered only %d" % len(clean_phone)) return int(clean_phone, 10)
def send_verification(phone, user): old_ver = PhoneVerification.objects.filter(user=user) # TODO: Handle flooding of verifications if old_ver: time_diff = (datetime.datetime.now() - old_ver[0].date).seconds if time_diff < 60 * 5: log.info("%s: User impatient, request ver only after %d seconds" % (user, time_diff)) return "Please give the sms %d more minutes to get there" % (5 - time_diff / 60) log.info("%s: Found old PhoneVerification, delete for now" % (user)) old_ver[0].delete() log.info("%s: Created new PhoneVerification and sending notification" % (user)) pv = PhoneVerification( user=user, phone=phone, code=CreateCode(user).lower(), attempt=1, date=datetime.datetime.now() ) pv.save() send_message(User.objects.filter(username="******")[0], "Your code for SMSKI is: %s" % pv.code, [user]) return ""
def send_message(user, message, to_list, phone_reply=False): log.info('%s: Starting send_message(%s)' % (user, to_list)) ses = SMSSession(user=user, date=datetime.now(), reply_type=0) ses.save() fake_name = random.choice(NAMES) name_used = 0 for to in to_list: msg = SMSMessage(date=datetime.now(), by=user, to=to, session=ses, message=message, status=0, reply=phone_reply) try: msg.save() except: log.error('Exception saving') traceback.print_exc() try: log.info('Starting..') log.info('User: %s' % user.username) log.info('To: %s' % to.username) except: log.error('Exception pre-print') traceback.print_exc() try: log.info('Start pars parse') log.info('User2: %s' % user) log.info('fake_name: %s' % fake_name) log.info('ses.id: %d' % ses.id) except: log.error('Exception parse') traceback.print_exc() try: log.info(u'%d:%d: --- SMS --- [%s] -> [%s] : %s' % (ses.id, msg.id, user, to, message)) except: log.error('Exception printing info !') traceback.print_exc() if user.username != 'boris' and (to.username == 'admin' or to.username == 'murkin'): log.error('Error sending..') log.error(u'%s: Trying to send sms to %s [%s]' % (user, to, message)) return dynamic_addr = '%s <*****@*****.**>' % (user, fake_name, ses.id) log.info('%s: Dynamic address [%s]' % (user, dynamic_addr)) send_mail_message(message, dynamic_addr, "*****@*****.**" % to.get_profile().phone) name_used += 1 if name_used > 4: fake_name = random.choice(NAMES) name_used = 0
def friend_request(request, user_id): log.debug('%s: Friend request' % request.user) muser = get_object_or_404(User, pk=user_id) if not request.method == 'POST': return HttpResponseRedirect("/") next_page = request.POST.get("next", "/") log.info('%s: Got POST data [%s]' % (request.user, request.POST)) if muser == request.user: return HttpResponseRedirect("/") op = request.POST.get("Action", "") if op == 'Add': log.info("%s: Current relation %d" % (request.user, relation(muser, request.user))) if relation(muser, request.user) != REL.NONE: return HttpResponseRedirect("/") fr = FriendRequest(by=request.user, to=muser, date=datetime.datetime.now(), status=0) fr.save() log.info("%s: Added friend request %s -> %s" % (request.user, request.user, muser)) if op == 'Cancel': pending = pending_request(request.user, muser) if not pending: return HttpResponseRedirect("/") pending.delete() log.info('%s: Removed friend request %s -> %s' % (request.user, request.user, muser)) if op == 'Accept': pending = pending_request(muser, request.user) if not pending or pending.status: return HttpResponseRedirect("/") log.info('%s: Accepted friend request %s -> %s' % (request.user, muser, request.user)) pending.status = 1 request.user.friends.add(muser.get_profile()) muser.friends.add(request.user.get_profile()) request.user.save() muser.save() pending.save() if op == 'Remove': rel, req = relation_and_request(muser, request.user) if not rel == REL.FRIENDS: return HttpResponseRedirect("/") if req: req.delete() muser.friends.remove(request.user.get_profile()) request.user.friends.remove(muser.get_profile()) log.info('%s: Removed friend link %s -> %s' % (request.user, request.user, muser)) return HttpResponseRedirect("/user_list/")
def parse_incoming_mail(string): ''' Get a new email and parse it ''' log.info('Parsing new email') # st = SMSTracker(date=datetime.datetime.now(), data=string, parsed=False) # st.save() msg = email.message_from_string(string) # Only SMS messages have a custom reply-to (with the number to reply to) if not 'Reply-To' in msg: log.info('Got an administrative email. Skipping') return else: log.info('--- New incoming SMS email ---') data = msg.get_payload() if not len(data): log.error('No payload !') exit() try: soup = BeautifulSoup(data) except: log.error('Error loading Soup') return # Get the sending phone number from the reply-to field try: reply_to = msg['Reply-To'] str = re.search('\++\d+ ([\d\-]+)', reply_to).group(1).replace('-','') except: log.error('Error getting number [%s]' % reply_to) return if not str: log.error('Error empty number [%s]' % reply_to) return try: num = int(str) except: log.error('Error converting to num [%s]' % str) return # Get the text try: str = soup.findAll('font')[2].string except: log.error('Error getting body') return try: body = re.sub('=\d.', '', str).strip() except: log.error('Error getting body [%s]' % str) return # st.parsed = True; # st.save() # Find the session str = re.search('[0-9]+', (msg['To']).split('@')[0]).group(0) try: session_id = int(str, 10) except: log.error('Error getting session id [%s]' % str) return if not session_id: log.error("Error getting session id from %s " % msg['To']) return ses = SMSSession.objects.filter(pk=session_id) if not len(ses): log.error("Error getting session with id %d" % session_id) return ses = ses[0] # Get source user log.info('Get user for %s' % msg['From']) by_num = int(re.sub('[^0-9]', '', msg['From'])[-9:]) if not by_num: log.error("Error parsing orig number %s" % msg['From']) return by_prof = Profile.objects.filter(phone=by_num) if not len(by_prof): log.error("Error getting using with num %d" % by_num) return by = by_prof[0].user log.info("Got message from %s to %s [%s]" % (by, ses.user, body)) body_w1255 = quopri.decodestring(body) decoded_body = body_w1255.decode('windows-1255').strip() send_message(by, decoded_body, [ses.user], phone_reply=True)
def clean_username(self): username = self.cleaned_data["username"] if User.objects.filter(username__iexact=username): log.info("User tried to register with %s - already take" % username) raise forms.ValidationError("Username already taken") return username
def CreateCode(user): random.seed() opts = Dictionary().split(" ") code = "%s%d" % (opts[random.randint(0, len(opts) - 1)], random.randint(11, 99)) log.info("%s: Generated random code for verification [%s]" % (user, code)) return code