Exemple #1
0
 def disconnect(self):
     try:
         is_chap = self.settings.config.portal.chap in (1, '1', 'chap')
         userIp = self.current_user.ipaddr
         nas = self.get_nas(self.current_user.nasaddr)
         ac_addr = nas['ip_addr']
         ac_port = int(nas['ac_port'])
         secret = utils.safestr(nas['bas_secret'])
         _vendor = utils.safestr(nas['portal_vendor'])
         if _vendor not in ('cmccv1', 'cmccv2', 'huaweiv1', 'huaweiv2'):
             defer.returnValue('not support vendor %s' % _vendor)
         send_portal = functools.partial(client.send,
                                         secret,
                                         log=self.syslog,
                                         debug=self.settings.config.debug,
                                         vendor=_vendor)
         vendor = client.PortalClient.vendors.get(_vendor)
         logout_req = vendor.proto.newReqLogout(userIp,
                                                secret,
                                                chap=is_chap)
         logout_resp = yield send_portal(data=logout_req,
                                         host=ac_addr,
                                         port=ac_port)
         if logout_resp.errCode > 0:
             _err_msg = u'{0},{1}'.format(
                 vendor.mod.AckLogoutErrs[logout_resp.errCode],
                 utils.safeunicode(logout_resp.get_text_info()[0] or ''))
             logger.error(_err_msg)
         defer.returnValue('disconnect done!')
     except Exception as err:
         defer.returnValue(err)
Exemple #2
0
 def send_sms(self, phone, tplid, args = [], kwargs = {}):
     smspwd = md5(utils.safestr('%s%s' % (self.apiuser, self.apikey))).hexdigest()
     _params = dict(ac='send', uid=utils.safestr(apikey), pwd=smspwd, mobile=utils.safestr(phone), content=utils.safestr(json.dumps(kwargs, ensure_ascii=False)))
     sms_api_url = '%s?%s' % (self.url, urlencode(_params))
     resp = yield httpclient.fetch(sms_api_url, followRedirect=True)
     if '200' != str(resp.status_code):
         defer.returnValue(True)
     else:
         ret = json.loads(resp.body)
         if self.debug:
             logger.info(ret)
         defer.returnValue(ret['stat'] == 0)
Exemple #3
0
    def post(self):
        try:
            if os.environ.get('DEMO_VER'):
                self.write(u'这是一个演示版本,不提供此功能')
                return
            file_path = os.path.join(os.path.dirname(taurusxradius.__file__),
                                     'static/dnsv')
            try:
                if not os.path.exists(file_path):
                    os.makedirs(file_path)
            except:
                pass

            f = self.request.files['Filedata'][0]
            filename = os.path.basename(utils.safestr(f['filename']))
            save_path = os.path.join(file_path, filename)
            tf = open(save_path, 'wb')
            filestr = f['body']
            tf.write(filestr.strip())
            tf.close()
            logger.info('write {0}'.format(save_path))
            self.write(u'上传完成')
        except Exception as err:
            logger.error(err)
            self.write(u'上传失败 %s' % utils.safeunicode(err))
Exemple #4
0
    def post(self):
        try:
            pic_path = os.path.join(os.path.dirname(taurusxradius.__file__),
                                    'static/pics')
            try:
                if not os.path.exists(pic_path):
                    os.makedirs(pic_path)
            except:
                pass

            f = self.request.files['Filedata'][0]
            filename = os.path.basename(utils.safestr(f['filename']))
            savename = 'pic{0}_{1}'.format(tools.gen_num_id(13), filename)
            save_path = os.path.join(pic_path, savename)
            tf = open(save_path, 'wb')
            tf.write(f['body'])
            tf.close()
            if not safefile.isimg(save_path):
                os.remove(save_path)
                logger.error('error upload file %s' % save_path)
                self.write(u'上传的文件不是图片类型')
                return
            logger.info('write {0}'.format(save_path))
            self.write(u'upload ok')
        except Exception as err:
            logger.error(err)
            self.write(u'上传失败 %s' % utils.safeunicode(err))
Exemple #5
0
 def event_sms_account_expire(self, account_number):
     userinfo = self.get_customer_info(account_number)
     tplid = self.get_tpl_id(ExpireNotify)
     if not tplid:
         return
     args = [
         utils.safestr(userinfo.realname), account_number,
         utils.safestr(userinfo.product_name), userinfo.expire_date
     ]
     kwargs = {}
     kwargs['customer'] = utils.safestr(userinfo.realname)
     kwargs['username'] = account_number
     kwargs['product'] = utils.safestr(userinfo.product_name)
     kwargs['expire'] = userinfo.expire_date
     dispatch.pub(EVENT_SENDSMS,
                  userinfo.mobile,
                  tplid,
                  args=args,
                  kwargs=kwargs)
Exemple #6
0
    def make_message(self, param):
        param_keys = list(param.keys())
        param_keys.sort()
        param_str = ''
        for key in param_keys:
            param_str += key + u'=' + utils.safeunicode(param[key]) + u'&'

        param_str = param_str[:-1]
        sign_str = self.apikey + u'&' + param_str + u'&' + self.apikey
        param['signature'] = md5(utils.safestr(sign_str)).hexdigest()
        return param
Exemple #7
0
 def get_error_html(self, status_code=500, **kwargs):
     logger.info('http error : [status_code:{0}], {1}'.format(
         status_code, utils.safestr(kwargs)))
     if status_code == 404:
         return self.render_string('error.html', msg=u'404:页面不存在')
     elif status_code == 403:
         return self.render_string('error.html', msg=u'403:非法的请求')
     elif status_code == 500:
         return self.render_string('error.html', msg=u'500:服务器处理失败,请联系管理员')
     else:
         return self.render_string('error.html',
                                   msg=u'%s:服务器处理失败,请联系管理员' % status_code)
Exemple #8
0
 def get_menu_data(self, mps_apiurl):
     try:
         _fetch_result = lambda: self.wechat.get_menu().get('menu')
         menus_obj = self.cache.aget(self.MpsMenuCacheKey,
                                     _fetch_result,
                                     expire=86400)
         if isinstance(menus_obj, (str, unicode)):
             menus_obj = json.loads(menus_obj)
         logger.debug(menus_obj)
         return menus_obj
     except Exception as err:
         logger.exception(err)
         mstr = menutpl_str.replace('{mps_apiurl}', mps_apiurl)
         return json.loads(utils.safestr(mstr))
Exemple #9
0
 def render_string(self, template_name, **template_vars):
     template_vars['xsrf_form_html'] = self.xsrf_form_html
     template_vars['current_user'] = self.current_user
     template_vars['login_time'] = self.get_secure_cookie(
         'portal_logintime')
     template_vars['request'] = self.request
     template_vars['requri'] = '{0}://{1}'.format(self.request.protocol,
                                                  self.request.host)
     template_vars['handler'] = self
     template_vars['utils'] = utils
     try:
         mytemplate = self.tp_lookup.get_template('wlanportal/%s' %
                                                  template_name)
         return mytemplate.render(**template_vars)
     except Exception as err:
         logger.info('Render template error {0}'.format(utils.safestr(err)))
         raise
Exemple #10
0
def radius_process(resp=None, resp_attrs={}):
    try:
        if not resp_attrs:
            return resp
        attrs = resp_attrs.get('attrs', {})
        for attr_name, attr_value in attrs.iteritems():
            try:
                resp.AddAttribute(utils.safestr(attr_name), attr_value)
            except:
                errmsg = u'add radius attr error %s:%s, %s' % (
                    attr_name, attr_value, traceback.format_exc())
                logger.error(errmsg,
                             trace='radius',
                             tag='radius_attrs_process_error')

        return resp
    except Exception as err:
        logger.exception(err, trace='radius', tag='radius_attrs_process_error')
        return resp
Exemple #11
0
 def check_data(self, formdata):
     """
     用户开户数据校验
     """
     max_giftdays = self.db.query(
         models.TrProductAttr.attr_value).filter_by(
             product_id=formdata.product_id,
             attr_name='max_giftdays').scalar() or 0
     if int(max_giftdays) < int(formdata.get('giftdays', 0)):
         self.last_error = u'最大赠送天数不能超过%s天' % max_giftdays
         return False
     max_giftflows = self.db.query(
         models.TrProductAttr.attr_value).filter_by(
             product_id=formdata.product_id,
             attr_name='max_giftflows').scalar() or 0
     if float(max_giftflows) < float(formdata.get('giftflows', 0)):
         self.last_error = u'最大赠送流量不能超过%sG' % max_giftflows
         return False
     node = self.db.query(models.TrNode).get(formdata.node_id)
     if not node:
         self.last_error = u'区域节点不存在'
         return False
     account_count = self.db.query(models.TrAccount).filter_by(
         account_number=formdata.account_number).count()
     if account_count > 0:
         self.last_error = u'账号%s已经存在' % formdata.account_number
         return False
     _ip_address = formdata.get('ip_address')
     if _ip_address and self.db.query(models.TrAccount).filter_by(
             ip_address=_ip_address).count() > 0:
         self.last_error = u'ip%s已经被使用' % utils.safestr(_ip_address)
         return False
     if self.db.query(models.TrCustomer).filter_by(
             customer_name=formdata.account_number).count() > 0:
         if account_count == 0:
             self.db.query(models.TrCustomer).filter_by(
                 customer_name=formdata.account_number).delete()
         else:
             self.last_error = u'用户名%s已经存在' % formdata.account_number
             return False
     return True
Exemple #12
0
 def send(self, **kwargs):
     try:
         _ctime = self.tz.localize(datetime.datetime.now())
         ttl = kwargs.pop('ttl', '7d')
         reqmsg = dict(ver=__version__,
                       timestamp=_ctime.isoformat(),
                       tag=kwargs.pop('tag', 'normal'))
         reqmsg.update(kwargs)
         puturl = '{0}/{1}/taurusxr?ttl={2}'.format(self.apiurl, self.index,
                                                    ttl)
         user_and_pwd = '{0}:{1}'.format(self.apiuser, self.apipwd)
         headers = {
             'Authorization':
             ['Basic {0}'.format(base64.b64encode(user_and_pwd))]
         }
         postdata = utils.safestr(json.dumps(reqmsg, ensure_ascii=False))
         d = httpclient.fetch(puturl, postdata=postdata, headers=headers)
         d.addCallback(lambda r: logger.debug(r.body)).addErrback(
             lambda e: sys.stderr.write(repr(e)))
     except:
         traceback.print_exc()
Exemple #13
0
 def send_sms(self, phone, tplid, args = [], kwargs = {}):
     if self.debug:
         logger.info('send sms to phone %s' % phone)
     params = {'%{0}%'.format(k):v for k, v in kwargs.iteritems()}
     param = self.make_message({'smsUser': self.apiuser,
      'templateId': tplid,
      'msgType': 0,
      'phone': phone,
      'vars': utils.safestr(json.dumps(params, ensure_ascii=False))})
     if self.debug:
         logger.info(param)
     resp = yield httpclient.fetch(SmsApi.url, postdata=urlencode(param))
     ret = json.loads(resp.body)
     if self.debug:
         logger.info(ret)
     if ret['statusCode'] == 200:
         defer.returnValue(True)
     else:
         _err = 'Send sms failure, statusCode=%s,message=%s' % (ret['statusCode'], utils.safestr(ret['message']))
         logger.error(_err, trace='event')
         defer.returnValue(False)
Exemple #14
0
class PortalListen(protocol.DatagramProtocol):
    def __init__(self, config, dbengine=None, **kwargs):
        self.dbengine = dbengine
        self.config = config
        self.mcache = redis_cache.CacheManager(redis_conf(config),
                                               cache_name='Portald')
        self.actions = {huawei.NTF_LOGOUT: self.doAckNtfLogout}
        reactor.callLater(3.0, self.init_task)

    def get_nas(self, ip_addr):
        def fetch_result():
            table = models.TrwBas.__table__
            with self.db_engine.begin() as conn:
                return conn.execute(
                    table.select().where(table.c.ip_addr == ip_addr)).first()

        return self.mcache.aget(settings.wlanportal_cache_key(ip_addr),
                                fetch_result,
                                expire=600)

    def init_task(self):
        _task = task.LoopingCall(self.send_ntf_heart)
        _task.start(self.config.portal.ntf_heart)

    def send_ntf_heart(self):
        pass

    def doAckNtfLogout(self, req, vendor, secret, (host, port)):
        try:
            resp = vendor.proto.newMessage(vendor.ACK_NTF_LOGOUT,
                                           req.userIp, req.serialNo, req.reqId,
                                           str(secret))
            logger.info('Send portal packet to %s:%s: %s' %
                        (host, port, utils.safestr(req)))
            self.transport.write(str(resp), (host, port))
        except Exception as err:
            logger.exception(err)
Exemple #15
0
        try:
            resp = vendor.proto.newMessage(vendor.ACK_NTF_LOGOUT,
                                           req.userIp, req.serialNo, req.reqId,
                                           str(secret))
            logger.info('Send portal packet to %s:%s: %s' %
                        (host, port, utils.safestr(req)))
            self.transport.write(str(resp), (host, port))
        except Exception as err:
            logger.exception(err)

    def datagramReceived(self, datagram, (host, port)):
        try:
            nas = self.get_nas(host)
            ac_addr = nas['ip_addr']
            ac_port = int(nas['ac_port'])
            secret = utils.safestr(nas['bas_secret'])
            _vendor = utils.safestr(nas['portal_vendor'])
            if _vendor not in ('cmccv1', 'cmccv2', 'huaweiv1', 'huaweiv2'):
                self.render_error(
                    msg=u'AC server portal_vendor {0} not support '.format(
                        _vendor))
                return
            vendor = client.PortalClient.vendors.get(_vendor)
            req = vendor.proto(secret=secret,
                               packet=datagram,
                               source=(host, port))
            logger.info('Received portal packet from %s:%s: %s' %
                        (host, port, utils.safestr(req)))
            if req.type in self.actions:
                self.actions[req.type](req, vendor, secret, (host, port))
            else:
Exemple #16
0
 def post(self, pid):
     try:
         openid = self.session.get('mps_openid',
                                   os.environ.get('DEV_OPEN_ID'))
         realname = self.get_argument('realname', '').strip()
         node_id = self.get_argument('node_id', '').strip()
         mobile = self.get_argument('mobile', '').strip()
         address = self.get_argument('address', '').strip()
         idcard = self.get_argument('idcard', '').strip()
         username = self.get_argument('username', '').strip()
         password = self.get_argument('password', '').strip()
         months = int(self.get_argument('months', '1'))
         days = int(self.get_argument('days', '1'))
         wechat_bind = int(self.get_argument('wechat_bind', '0'))
         product = self.db.query(models.TrProduct).filter_by(id=pid).first()
         if not product:
             return self.render('error.html', msg=u'资费不存在')
         if not realname:
             return self.render('wxorder_form.html',
                                product=product,
                                msg=u'姓名不能为空',
                                **self.get_params())
         if not rules.is_alphanum2(6, 16).valid(utils.safestr(username)):
             return self.render('wxorder_form.html',
                                product=product,
                                msg=u'用户名校验错误,必须是长度为6-16位的英文字符数字',
                                **self.get_params())
         if not rules.is_alphanum2(6, 16).valid(password):
             return self.render('wxorder_form.html',
                                product=product,
                                msg=u'密码校验错误,必须是6-16为的英文字符数字',
                                **self.get_params())
         if wechat_bind == 1 and self.db.query(models.TrCustomer).filter_by(
                 wechat_oid=openid).count() > 0:
             return self.render('wxorder_form.html',
                                product=product,
                                msg=u'微信账号已绑定',
                                **self.get_params())
         fee_value, expire_date = self.calc_fee(product.id,
                                                months=months,
                                                charge_fee=utils.fen2yuan(
                                                    product.fee_price))
         order_id = tools.gen_num_id(16)
         formdata = Storage({'order_attach': 'neworder'})
         formdata['wxpay_body'] = u'套餐订购:%s' % product.product_name
         formdata['openid'] = openid
         formdata['order_id'] = order_id
         formdata['node_id'] = node_id
         formdata['area_id'] = ''
         formdata['realname'] = realname
         formdata['idcard'] = idcard
         formdata['mobile'] = mobile
         formdata['address'] = address
         formdata['account_number'] = username
         formdata['password'] = password
         formdata['ip_address'] = ''
         formdata['product_id'] = product.id
         formdata['agency_id'] = ''
         formdata['charge_code'] = ''
         formdata['months'] = months
         formdata['days'] = days
         formdata['giftdays'] = 0
         formdata['giftflows'] = 0
         formdata['fee_value'] = fee_value
         formdata['expire_date'] = expire_date
         formdata['status'] = 1
         formdata['builder_name'] = ''
         formdata['customer_desc'] = u'客户微信自助开户'
         formdata['billing_type'] = 1
         formdata['accept_source'] = 'wechat'
         if wechat_bind == 1:
             formdata['wechat_oid'] = openid
         self.paycache.set(order_wxpaycaache_key(order_id), formdata, 28800)
         self.redirect('/mps/wxorder/pay/%s' % order_id)
     except Exception as err:
         logger.exception(err, trace='wechat')
         self.render('error.html', msg=u'套餐订购失败,请联系客服 %s' % repr(err))
Exemple #17
0
    def post(self, **kwargs):
        qstr = self.get_argument('qstr', '')
        username = self.get_argument('username', None)
        password = self.get_argument('password', None)
        if 'qstr' in kwargs:
            qstr = kwargs['qstr']
        if 'username' in kwargs:
            username = kwargs['username']
        if 'password' in kwargs:
            password = kwargs['password']
        wlan_params = self.get_wlan_params(qstr)
        logger.info(u'post wlan params:{0}'.format(
            utils.safeunicode(wlan_params)))
        ssid = wlan_params.get('ssid', 'default')
        wlanacip = wlan_params.get('wlanacip', '127.0.0.1')
        nasid = wlan_params.get('nasid', 'default')
        wlanuserip = wlan_params.get('wlanuserip', self.request.remote_ip)
        is_chap = self.settings.config.portal.chap in (1, '1', 'chap')
        userIp = wlanuserip
        start_time = time.time()
        nas = self.get_nas(wlanacip, nasid=nasid)
        if not nas:
            self.render_error(
                msg=u'AC设备地址或ID {0},{1} 未在本系统注册 '.format(wlanacip, nasid))
            return
        else:
            ac_addr = nas['ip_addr']
            ac_port = int(nas['ac_port'])
            secret = utils.safestr(nas['bas_secret'])
            _vendor = utils.safestr(nas['portal_vendor'])
            if _vendor not in ('cmccv1', 'cmccv2', 'huaweiv1', 'huaweiv2'):
                logger.error(nas)
                self.render_error(
                    msg=u'AC设备 portal_vendor {0} 不支持 '.format(_vendor))
                return
            hm_mac = wlan_params.get('wlanstamac',
                                     '').replace('.', ':').replace('-', ':')
            macbstr = hm_mac and struct.pack(
                'BBBBBB', *[int(i, base=16)
                            for i in hm_mac.split(':')]) or None
            send_portal = functools.partial(client.send,
                                            secret,
                                            log=logger,
                                            debug=self.settings.debug,
                                            vendor=_vendor,
                                            timeout=5)
            vendor = client.PortalClient.vendors.get(_vendor)
            if self.settings.debug:
                logger.info(u'开始 [username:%s] Portal认证, 参数:%s' %
                            (username, utils.safeunicode(wlan_params)))
            tpl = self.get_template_attrs(ssid)
            firsturl = tpl.get('home_page', '/navigate')

            def back_login(msg=u''):
                self.render(self.get_login_template(tpl['tpl_path']),
                            tpl=tpl,
                            msg=msg,
                            qstr=qstr,
                            **wlan_params)

            if not username:
                back_login(msg=u'用户名不能为空')
                return
            try:
                challenge_resp = None
                if is_chap:
                    challenge_req = vendor.proto.newReqChallenge(userIp,
                                                                 secret,
                                                                 mac=macbstr,
                                                                 chap=is_chap)
                    challenge_resp = yield send_portal(data=challenge_req,
                                                       host=ac_addr,
                                                       port=ac_port)
                    if challenge_resp.errCode > 0:
                        if challenge_resp.errCode == 2:
                            self.set_remerber_user(username, password)
                            self.redirect(firsturl)
                            return
                        raise Exception(vendor.mod.AckChallengeErrs[
                            challenge_resp.errCode])
                if challenge_resp:
                    auth_req = vendor.proto.newReqAuth(
                        userIp,
                        username,
                        password,
                        challenge_resp.reqId,
                        challenge_resp.get_challenge(),
                        secret,
                        ac_addr,
                        serialNo=challenge_req.serialNo,
                        mac=macbstr,
                        chap=is_chap)
                else:
                    auth_req = vendor.proto.newReqAuth(userIp,
                                                       username,
                                                       password,
                                                       0,
                                                       None,
                                                       secret,
                                                       ac_addr,
                                                       chap=is_chap)
                auth_resp = yield send_portal(data=auth_req,
                                              host=ac_addr,
                                              port=ac_port)
                if auth_resp.errCode > 0:
                    if auth_resp.errCode == 2:
                        self.set_remerber_user(username, password)
                        self.redirect(firsturl)
                        return
                    text_info = auth_resp.get_text_info()
                    _err_msg = u'{0},{1}'.format(
                        vendor.mod.AckAuthErrs[auth_resp.errCode],
                        utils.safeunicode(text_info and text_info[0] or ''))
                    raise Exception(_err_msg)
                affack_req = vendor.proto.newAffAckAuth(userIp,
                                                        secret,
                                                        ac_addr,
                                                        auth_req.serialNo,
                                                        auth_resp.reqId,
                                                        mac=macbstr,
                                                        chap=is_chap)
                send_portal(data=affack_req,
                            host=ac_addr,
                            port=ac_port,
                            noresp=True)
                logger.info(u'用户 [username:{0}] 认证成功'.format(username))
                if self.settings.debug:
                    logger.debug(u'用户 [username:%s] 认证耗时 [cast:%s ms]' %
                                 (username, (time.time() - start_time) * 1000))
                self.set_remerber_user(username, password)
                self.redirect(firsturl)
            except Exception as err:
                import traceback
                traceback.print_exc()
                back_login(msg=u'用户认证失败,%s' % utils.safeunicode(err.message))

            return