Beispiel #1
0
    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
Beispiel #2
0
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 })
Beispiel #3
0
    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]
        )
Beispiel #4
0
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, })
Beispiel #5
0
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, })
Beispiel #6
0
    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
Beispiel #7
0
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)
Beispiel #8
0
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)
Beispiel #9
0
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 ""
Beispiel #10
0
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
Beispiel #11
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/")
Beispiel #12
0
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)
Beispiel #13
0
 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
Beispiel #14
0
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