def error(message,**kwargs): if not isinstance(message, unicode): message = safeunicode(message) if EVENT_ERROR in dispatch.dispatch.callbacks: dispatch.pub(EVENT_ERROR,message,**kwargs) else: default_log.error(message)
def process(self, *args, **kwargs): dispatch.pub(logger.EVENT_INFO, "process ddns update task..") with make_db(self.db) as db: try: nas_list = db.query(models.TrBas) for nas in nas_list: if not nas.dns_name: continue results, _, _ = yield client.lookupAddress(nas.dns_name) if not results: dispatch.pub(logger.EVENT_INFO, "domain {0} resolver empty".format(nas.dns_name)) if results[0].type == dns.A: ipaddr = ".".join(str(i) for i in struct.unpack("BBBB", results[0].payload.address)) if ipaddr: nas.ip_addr = ipaddr db.commit() dispatch.pub( logger.EVENT_INFO, "domain {0} resolver {1} success".format(nas.dns_name, ipaddr) ) else: dispatch.pub( logger.EVENT_INFO, "domain {0} no ip address,{1}".format(nas.dns_name, repr(results)) ) except Exception as err: dispatch.pub(logger.EVENT_ERROR, "ddns process error %s" % utils.safeunicode(err.message)) defer.returnValue(60)
def render_json(self, **template_vars): if not template_vars.has_key("code"): template_vars["code"] = 0 resp = json.dumps(template_vars, ensure_ascii=False) if self.settings.debug: dispatch.pub(logger.EVENT_DEBUG,"[api debug] :: %s response body: %s" % (self.request.path, utils.safeunicode(resp))) self.write(resp)
def info(message,trace="info",**kwargs): if not isinstance(message, unicode): message = safeunicode(message) if EVENT_INFO in dispatch.dispatch.callbacks: dispatch.pub(EVENT_INFO,message,**kwargs) if EVENT_TRACE in dispatch.dispatch.callbacks: dispatch.pub(EVENT_TRACE,trace,message,**kwargs)
def info(message,**kwargs): if not isinstance(message, unicode): message = safeunicode(message) if EVENT_INFO in dispatch.dispatch.callbacks: dispatch.pub(EVENT_INFO,message,**kwargs) else: default_log.info(message)
def debug(message, **kwargs): if not isinstance(message, unicode): message = safeunicode(message) if EVENT_DEBUG in dispatch.dispatch.callbacks: dispatch.pub(EVENT_DEBUG, message, **kwargs) if EVENT_TRACE in dispatch.dispatch.callbacks: dispatch.pub(EVENT_TRACE, "debug", message, **kwargs)
def post(self): try: request = self.parse_form_request() account_number = request.get('account_number') if not account_number: raise Exception("account_number is empty") account = self.db.query(models.TrAccount).filter_by(account_number=account_number).first() if not account: raise Exception("account is not exists") self.db.query(models.TrAcceptLog).filter_by(account_number=account.account_number).delete() self.db.query(models.TrAccountAttr).filter_by(account_number=account.account_number).delete() self.db.query(models.TrBilling).filter_by(account_number=account.account_number).delete() self.db.query(models.TrTicket).filter_by(account_number=account.account_number).delete() self.db.query(models.TrOnline).filter_by(account_number=account.account_number).delete() self.db.query(models.TrAccount).filter_by(account_number=account.account_number).delete() self.db.query(models.TrCustomerOrder).filter_by(account_number=account.account_number).delete() self.add_oplog(u'API删除用户账号%s' % (account.account_number)) self.db.commit() dispatch.pub(ACCOUNT_DELETE_EVENT, account.account_number, async=True) dispatch.pub(cache.CACHE_DELETE_EVENT,account_cache_key(account.account_number), async=True) return self.render_result(code=0, msg='success') except Exception as err: self.render_result(code=1, msg=utils.safeunicode(err.message)) import traceback traceback.print_exc() return
def info(message, trace="info", **kwargs): if not isinstance(message, unicode): message = safeunicode(message) if EVENT_INFO in dispatch.dispatch.callbacks: dispatch.pub(EVENT_INFO, message, **kwargs) if EVENT_TRACE in dispatch.dispatch.callbacks: dispatch.pub(EVENT_TRACE, trace, message, **kwargs)
def acctounting(self): if not self.account: return dispatch.pub(logger.EVENT_ERROR, "[Acct] Received an accounting update request but user[%s] not exists"% self.request.account_number) ticket = Storage(**self.request) online = self.get_online(ticket.nas_addr,ticket.acct_session_id) if not online: sessiontime = ticket.acct_session_time updatetime = datetime.datetime.now() _starttime = updatetime - datetime.timedelta(seconds=sessiontime) online = Storage( account_number = self.account.account_number, nas_addr = ticket.nas_addr, acct_session_id = ticket.acct_session_id, acct_start_time = _starttime.strftime( "%Y-%m-%d %H:%M:%S"), framed_ipaddr = ticket.framed_ipaddr, mac_addr = ticket.mac_addr, nas_port_id = ticket.nas_port_id, billing_times = ticket.acct_session_time, input_total = self.get_input_total(), output_total = self.get_output_total(), start_source = STATUS_TYPE_UPDATE ) self.add_online(online) self.billing(online) dispatch.pub(logger.EVENT_INFO,'%s Accounting update request, update online'% self.account.account_number)
def acctounting(self): if not self.account: return dispatch.pub(logger.EVENT_ERROR, "[Acct] Received an accounting update request but user[%s] not exists"% self.request.account_number) ticket = Storage(**self.request) _datetime = datetime.datetime.now() online = self.get_online(ticket.nas_addr,ticket.acct_session_id) if not online: session_time = ticket.acct_session_time stop_time = _datetime.strftime( "%Y-%m-%d %H:%M:%S") start_time = (_datetime - datetime.timedelta(seconds=int(session_time))).strftime( "%Y-%m-%d %H:%M:%S") ticket.acct_start_time = start_time ticket.acct_stop_time = stop_time ticket.start_source= STATUS_TYPE_STOP ticket.stop_source = STATUS_TYPE_STOP self.add_ticket(ticket) else: self.del_online(ticket.nas_addr,ticket.acct_session_id) ticket.acct_start_time = online.acct_start_time ticket.acct_stop_time= _datetime.strftime( "%Y-%m-%d %H:%M:%S") ticket.start_source = online.start_source ticket.stop_source = STATUS_TYPE_STOP self.add_ticket(ticket) self.billing(online) dispatch.pub(logger.EVENT_INFO,'%s Accounting stop request, remove online'% self.account.account_number)
def error(message, **kwargs): if not isinstance(message, unicode): message = safeunicode(message) if EVENT_ERROR in dispatch.dispatch.callbacks: dispatch.pub(EVENT_ERROR, message, **kwargs) if EVENT_TRACE in dispatch.dispatch.callbacks: dispatch.pub(EVENT_TRACE, "error", message, **kwargs)
def bill_botimes(self, online, product): #买断时长 dispatch.pub( logger.EVENT_INFO, '%s > Buyout long time billing ' % self.account.account_number) time_length = self.get_user_time_length() sessiontime = self.request.acct_session_time billing_times = online.billing_times acct_times = sessiontime - billing_times user_time_length = time_length - acct_times if user_time_length < 0: user_time_length = 0 self.update_billing( Storage(account_number=online.account_number, nas_addr=online.nas_addr, acct_session_id=online.acct_session_id, acct_start_time=online.acct_start_time, acct_session_time=self.request.acct_session_time, input_total=self.get_input_total(), output_total=self.get_output_total(), acct_times=acct_times, acct_flows=0, acct_fee=0, actual_fee=0, balance=0, time_length=user_time_length, flow_length=0, is_deduct=1, create_time=datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S"))) if user_time_length == 0: self.disconnect(online)
def debug(message,**kwargs): if not isinstance(message, unicode): message = safeunicode(message) if EVENT_DEBUG in dispatch.dispatch.callbacks: dispatch.pub(EVENT_DEBUG,message,**kwargs) else: default_log.debug(message)
def debug(message,**kwargs): if not isinstance(message, unicode): message = safeunicode(message) if EVENT_DEBUG in dispatch.dispatch.callbacks: dispatch.pub(EVENT_DEBUG,message,**kwargs) if EVENT_TRACE in dispatch.dispatch.callbacks: dispatch.pub(EVENT_TRACE,"debug",message,**kwargs)
def acctounting(self): self.unlock_online(self.request.nas_addr,None) dispatch.pub(logger.EVENT_INFO,'bas accounting onoff success')
def error(message,**kwargs): if not isinstance(message, unicode): message = safeunicode(message) if EVENT_ERROR in dispatch.dispatch.callbacks: dispatch.pub(EVENT_ERROR,message,**kwargs) if EVENT_TRACE in dispatch.dispatch.callbacks: dispatch.pub(EVENT_TRACE,"error",message,**kwargs)
def bill_botimes(self,online, product): #买断时长 logger.info('%s > Buyout long time billing ' % self.account.account_number) time_length = self.get_user_time_length() sessiontime = self.request.acct_session_time billing_times = online.billing_times acct_times = sessiontime - billing_times if acct_times < 0: acct_times = 0 user_time_length = time_length - acct_times if user_time_length < 0 : user_time_length = 0 self.update_billing(Storage( account_number = online.account_number, nas_addr = online.nas_addr, acct_session_id = online.acct_session_id, acct_start_time = online.acct_start_time, acct_session_time = self.request.acct_session_time, input_total = self.get_input_total(), output_total = self.get_output_total(), acct_times = acct_times, acct_flows = 0, acct_fee = 0, actual_fee = 0, balance = 0, time_length = user_time_length, flow_length = 0, is_deduct = 1, create_time = datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S") )) if user_time_length == 0 : dispatch.pub(UNLOCK_ONLINE_EVENT, online.account_number,online.nas_addr, online.acct_session_id,async=True)
def get(self): account_number = self.get_argument("account_number") if not account_number: self.render_error(msg=u'account_number is empty') for online in self.db.query( models.TrOnline).filter_by(account_number=account_number): dispatch.pub(UNLOCK_ONLINE_EVENT, account_number, online.nas_addr, online.acct_session_id) account = self.db.query(models.TrAccount).get(account_number) customer_id = account.customer_id self.db.query(models.TrAcceptLog).filter_by( account_number=account.account_number).delete() self.db.query(models.TrAccountAttr).filter_by( account_number=account.account_number).delete() self.db.query(models.TrBilling).filter_by( account_number=account.account_number).delete() self.db.query(models.TrTicket).filter_by( account_number=account.account_number).delete() self.db.query(models.TrOnline).filter_by( account_number=account.account_number).delete() self.db.query(models.TrAccount).filter_by( account_number=account.account_number).delete() self.db.query(models.TrCustomerOrder).filter_by( account_number=account.account_number).delete() self.add_oplog(u'删除用户账号%s' % (account_number)) self.db.commit() dispatch.pub(ACCOUNT_DELETE_EVENT, account.account_number, async=True) dispatch.pub(settings.CACHE_DELETE_EVENT, account_cache_key(account_number), async=True) return self.redirect("/admin/customer")
def post(self): account_number = self.get_argument("account_number") account = self.db.query(models.TrAccount).get(account_number) if account.status != 2: return self.render_json(code=1, msg=u"用户当前状态不允许复机") account.status = 1 _datetime = datetime.datetime.now() _pause_time = datetime.datetime.strptime(account.last_pause, "%Y-%m-%d %H:%M:%S") _expire_date = datetime.datetime.strptime(account.expire_date + ' 23:59:59', "%Y-%m-%d %H:%M:%S") days = (_expire_date - _pause_time).days new_expire = (_datetime + datetime.timedelta(days=int(days))).strftime("%Y-%m-%d") account.expire_date = new_expire accept_log = models.TrAcceptLog() accept_log.accept_type = 'resume' accept_log.accept_source = 'console' accept_log.accept_desc = u"用户复机:上网账号:%s" % (account_number) accept_log.account_number = account.account_number accept_log.accept_time = utils.get_currtime() accept_log.operator_name = self.current_user.username self.db.add(accept_log) self.db.commit() dispatch.pub(db_cache.CACHE_DELETE_EVENT,account_cache_key(account.account_number), async=True) return self.render_json(msg=u"操作成功")
def bill_boflows(self, online, product): #买断流量 dispatch.pub(logger.EVENT_INFO,'%s > Buyout flow billing ' % self.account.account_number) flow_length = self.get_user_flow_length() output_total = self.get_output_total() billing_output_total = online.output_total acct_flows = output_total - billing_output_total user_flow_length = flow_length - acct_flows if user_flow_length < 0 : user_flow_length = 0 self.update_billing(Storage( account_number = online.account_number, nas_addr = online.nas_addr, acct_session_id = online.acct_session_id, acct_start_time = online.acct_start_time, acct_session_time = self.request.acct_session_time, input_total = self.get_input_total(), output_total = self.get_output_total(), acct_times = 0, acct_flows = acct_flows, acct_fee = 0, actual_fee = 0, balance = 0, time_length = 0, flow_length = user_flow_length, is_deduct = 1, create_time = datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S") )) if user_flow_length == 0 : self.disconnect(online)
def post(self): account_number = self.get_argument("account_number") account = self.db.query(models.TrAccount).get(account_number) if account.status != 1: return self.render_json(code=1, msg=u"用户当前状态不允许停机") _datetime = utils.get_currtime() account.last_pause = _datetime account.status = 2 accept_log = models.TrAcceptLog() accept_log.accept_type = "pause" accept_log.accept_source = "console" accept_log.accept_desc = u"用户停机:上网账号:%s" % (account_number) accept_log.account_number = account.account_number accept_log.accept_time = _datetime accept_log.operator_name = self.current_user.username self.db.add(accept_log) self.db.commit() dispatch.pub(ACCOUNT_PAUSE_EVENT, account.account_number, async=True) dispatch.pub(db_cache.CACHE_DELETE_EVENT, account_cache_key(account.account_number), async=True) return self.render_json(msg=u"操作成功")
def post(self): self.settings.config['syslog']['enable'] = int(self.get_argument("enable")) self.settings.config['syslog']['server'] = self.get_argument("server") self.settings.config['syslog']['port'] = int(self.get_argument("port",514)) self.settings.config['syslog']['level'] = self.get_argument("level") self.settings.config.save() dispatch.pub(logger.EVENT_SETUP,self.settings.config) self.redirect("/admin/config?active=syslog")
def post(self): backup_path = self.settings.config.database.backup_path bakfs = self.get_argument("bakfs") try: os.remove(os.path.join(backup_path, bakfs)) return self.render_json(code=0, msg="delete done!") except Exception as err: dispatch.pub(logger.EVENT_EXCEPTION, err) return self.render_json(code=1, msg="delete fail! %s" % (err))
def post(self): backup_path = self.settings.config.database.backup_path backup_file = "toughradius_db_%s.json.gz" % utils.gen_backep_id() try: self.db_backup.dumpdb(os.path.join(backup_path, backup_file)) return self.render_json(code=0, msg="backup done!") except Exception as err: dispatch.pub(logger.EVENT_EXCEPTION, err) return self.render_json(code=1, msg="backup fail! %s" % (err))
def post(self): backup_path = self.settings.config.database.backup_path backup_file = "toughradius_db_%s.json.gz" % utils.gen_backep_id() try: self.db_backup.dumpdb(os.path.join(backup_path, backup_file)) return self.render_json(code=0, msg="backup done!") except Exception as err: dispatch.pub(logger.EVENT_EXCEPTION,err) return self.render_json(code=1, msg="backup fail! %s" % (err))
def render_json(self, **template_vars): if not template_vars.has_key("code"): template_vars["code"] = 0 resp = json.dumps(template_vars, ensure_ascii=False) if self.settings.debug: dispatch.pub( logger.EVENT_DEBUG, "[api debug] :: %s response body: %s" % (self.request.path, utils.safeunicode(resp))) self.write(resp)
def post(self): backup_path = self.settings.config.database.backup_path bakfs = self.get_argument("bakfs") try: os.remove(os.path.join(backup_path, bakfs)) return self.render_json(code=0, msg="delete done!") except Exception as err: dispatch.pub(logger.EVENT_EXCEPTION,err) return self.render_json(code=1, msg="delete fail! %s" % (err))
class RADIUS(protocol.DatagramProtocol): def __init__(self, config, dbengine): self.config = config self.dict = dictionary.Dictionary( os.path.join(os.path.dirname(toughradius.__file__), 'dictionarys/dictionary')) self.db_engine = dbengine or get_engine(config) self.aes = utils.AESCipher(key=self.config.system.secret) self.mcache = mcache.Mcache() def get_nas(self, ip_addr): def fetch_result(): table = models.TrBas.__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(bas_cache_key(ip_addr), fetch_result, expire=600) def processPacket(self, pkt, bas=None): pass def createPacket(self, **kwargs): raise NotImplementedError('Attempted to use a pure base class') @timecast def datagramReceived(self, datagram, (host, port)): try: bas = self.get_nas(host) if not bas: dispatch.pub( logger.EVENT_INFO, '[Radiusd] :: Dropping packet from unknown host ' + host) return secret, vendor_id = bas['bas_secret'], bas['vendor_id'] radius_request = self.createPacket(packet=datagram, dict=self.dict, secret=six.b(str(secret)), vendor_id=vendor_id) dispatch.pub( logger.EVENT_INFO, "[Radiusd] :: Received radius request: %s" % (repr(radius_request))) if self.config.system.debug: dispatch.pub(logger.EVENT_DEBUG, radius_request.format_str()) reply = self.processPacket(radius_request, bas) self.reply(reply, (host, port)) except Exception as err: errstr = 'RadiusError:Dropping invalid packet from {0} {1},{2}'.format( host, port, utils.safeunicode(err)) dispatch.pub(logger.EVENT_ERROR, errstr) import traceback traceback.print_exc()
def get(self): bas_id = self.get_argument("bas_id") basip = self.db.query(models.TrBas).get(form.d.id).ip_addr self.db.query(models.TrBas).filter_by(id=bas_id).delete() self.add_oplog(u'删除接入设备信息:%s' % bas_id) self.db.commit() dispatch.pub(redis_cache.CACHE_DELETE_EVENT,bas_cache_key(basip), async=True) self.redirect("/admin/bas",permanent=False)
def post(self): account_number = self.get_argument('account_number') user = self.db.query(models.TrAccount).filter_by(account_number=account_number).first() user.mac_addr = '' user.vlan_id1 = 0 user.vlan_id2 = 0 self.add_oplog(u'释放用户账号(%s)绑定信息'%(account_number)) self.db.commit() dispatch.pub(settings.CACHE_DELETE_EVENT,account_cache_key(account_number), async=True) return self.render_json(msg=u"解绑成功")
def post(self): try: f = self.request.files['Filedata'][0] save_path = os.path.join(self.settings.config.database.backup_path, f['filename']) tf = open(save_path, 'wb') tf.write(f['body']) tf.close() self.write("upload success") except Exception as err: dispatch.pub(logger.EVENT_EXCEPTION,err) self.write("upload fail %s" % str(err))
def init_route_permit(self): with make_db(self.db) as conn: try: oprs = conn.query(models.TrOperator) for opr in oprs: if opr.operator_type > 0: for rule in self.db.query(models.TrOperatorRule).filter_by(operator_name=opr.operator_name): permit.bind_opr(rule.operator_name, rule.rule_path) elif opr.operator_type == 0: # 超级管理员授权所有 permit.bind_super(opr.operator_name) except Exception as err: dispatch.pub(logger.EVENT_ERROR,"init route error , %s" % str(err))
def post(self): backup_path = self.settings.config.database.backup_path backup_file = "toughradius_db_%s.before_restore.json.gz" % utils.gen_backep_id() rebakfs = self.get_argument("bakfs") try: self.db_backup.dumpdb(os.path.join(backup_path, backup_file)) if 'trv1' in rebakfs: self.db_backup.restoredbv1(os.path.join(backup_path, rebakfs)) else: self.db_backup.restoredb(os.path.join(backup_path, rebakfs)) return self.render_json(code=0, msg="restore done!") except Exception as err: dispatch.pub(logger.EVENT_EXCEPTION,err) return self.render_json(code=1, msg="restore fail! %s" % (err))
def billing(self, online): product = self.get_product_by_id(self.account.product_id) if not product: dispatch.pub(logger.EVENT_ERROR,'product <%s> not exists' % self.account.product_id) return if product.product_policy not in (PPTimes,BOTimes,PPFlow,BOFlows): self.update_online(self.request.nas_addr, self.request.acct_session_id, billing_times=self.request.acct_session_time, input_total=self.get_input_total(), output_total=self.get_output_total()) else: self.bill_funcs[product.product_policy](online, product)
def billing(self, online): product = self.get_product_by_id(self.account.product_id) if not product: dispatch.pub(logger.EVENT_ERROR, 'product <%s> not exists' % self.account.product_id) return if product.product_policy not in (PPTimes, BOTimes, PPFlow, BOFlows): self.update_online(self.request.nas_addr, self.request.acct_session_id, billing_times=self.request.acct_session_time, input_total=self.get_input_total(), output_total=self.get_output_total()) else: self.bill_funcs[product.product_policy](online, product)
def get_error_html(self, status_code=500, **kwargs): dispatch.pub(logger.EVENT_ERROR,"http error : [status_code:{0}], {1}".format(status_code, utils.safestr(kwargs))) if self.settings.debug: traceback.print_exc() if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest': return self.render_json(code=1, msg=u"%s:服务器处理失败,请联系管理员" % status_code) if status_code == 404: return self.render_error(msg=u"404:页面不存在") elif status_code == 403: return self.render_error(msg=u"403:非法的请求") elif status_code == 500: return self.render_error(msg=u"500:服务器处理失败,请联系管理员") else: return self.render_error(msg=u"%s:服务器处理失败,请联系管理员" % status_code)
def process(self, *args, **kwargs): logger.info("process expire notify task..") with make_db(self.db) as db: _enable = int(self.get_param_value("expire_notify_enable",0)) if not _enable: return 120.0 _ndays = self.get_param_value("expire_notify_days") notify_tpl = self.get_param_value("expire_notify_tpl") notify_url = self.get_param_value("expire_notify_url") notify_interval = self.get_notify_interval() if notify_interval > 3: return notify_interval _now = datetime.datetime.now() _date = (datetime.datetime.now() + datetime.timedelta(days=int(_ndays))).strftime("%Y-%m-%d") expire_query = db.query( models.TrAccount.account_number, models.TrAccount.expire_date, models.TrCustomer.email, models.TrCustomer.mobile ).filter( models.TrAccount.customer_id == models.TrCustomer.customer_id, models.TrAccount.expire_date <= _date, models.TrAccount.expire_date >= _now.strftime("%Y-%m-%d"), models.TrAccount.status == 1 ) logger.info('expire_notify total: %s'%expire_query.count()) for account,expire,email,mobile in expire_query: dispatch.pub('account_expire',account, async=False) ctx = notify_tpl.replace('#account#',account) ctx = ctx.replace('#expire#',expire) topic = ctx[:ctx.find('\n')] if email: self.send_mail(email, topic, ctx).addCallbacks(self.syslog.info,self.syslog.error) url = notify_url.replace('{account}',account) url = url.replace('{expire}',expire) url = url.replace('{email}',email) url = url.replace('{mobile}',mobile) url = url.encode('utf-8') url = quote(url,":?=/&") httpclient.get(url).addCallbacks(logger.info,logger.error) return self.get_notify_interval() + 120
def post(self): form = bas_forms.bas_update_form() if not form.validates(source=self.get_params()): return self.render("base_form.html", form=form) bas = self.db.query(models.TrBas).get(form.d.id) bas.dns_name = form.d.dns_name bas.bas_name = form.d.bas_name bas.time_type = form.d.time_type bas.vendor_id = form.d.vendor_id bas.bas_secret = form.d.bas_secret bas.coa_port = form.d.coa_port self.add_oplog(u'修改接入设备信息:%s' % bas.ip_addr) self.db.commit() dispatch.pub(redis_cache.CACHE_DELETE_EVENT,bas_cache_key(bas.ip_addr), async=True) self.redirect("/admin/bas",permanent=False)
def post(self): account_number = self.get_argument("account_number") account = self.db.query(models.TrAccount).get(account_number) user = self.query_account(account_number) form = account_forms.account_cancel_form() if account.status != 1: return self.render("account_form.html", user=user, form=form, msg=u"无效用户状态") if not form.validates(source=self.get_params()): return self.render("account_form.html", user=user, form=form) accept_log = models.TrAcceptLog() accept_log.accept_type = 'cancel' accept_log.accept_source = 'console' accept_log.account_number = form.d.account_number accept_log.accept_time = utils.get_currtime() accept_log.operator_name = self.current_user.username accept_log.accept_desc = u"用户销户退费%s(元);%s" % ( form.d.fee_value, utils.safeunicode(form.d.operate_desc)) self.db.add(accept_log) self.db.flush() self.db.refresh(accept_log) old_expire_date = account.expire_date order = models.TrCustomerOrder() order.order_id = utils.gen_order_id() order.customer_id = user.customer_id order.product_id = user.product_id order.account_number = form.d.account_number order.order_fee = 0 order.actual_fee = -utils.yuan2fen(form.d.fee_value) order.pay_status = 1 order.order_source = 'console' order.accept_id = accept_log.id order.create_time = utils.get_currtime() order.order_desc = accept_log.accept_desc self.db.add(order) account.status = 3 self.db.commit() dispatch.pub(ACCOUNT_CHANNEL_EVENT, account.account_number, async=True) self.redirect(self.detail_url_fmt(account_number))
def process(self, *args, **kwargs): dispatch.pub(logger.EVENT_INFO, "process expire notify task..") with make_db(self.db) as db: _enable = int(self.get_param_value("expire_notify_enable", 0)) if not _enable: return 120.0 _ndays = self.get_param_value("expire_notify_days") notify_tpl = self.get_param_value("expire_notify_tpl") notify_url = self.get_param_value("expire_notify_url") notify_interval = int( self.get_param_value("expire_notify_interval", 1440)) * 60.0 _now = datetime.datetime.now() _date = (datetime.datetime.now() + datetime.timedelta(days=int(_ndays))).strftime("%Y-%m-%d") expire_query = db.query( models.TrAccount.account_number, models.TrAccount.expire_date, models.TrCustomer.email, models.TrCustomer.mobile).filter( models.TrAccount.customer_id == models.TrCustomer.customer_id, models.TrAccount.expire_date <= _date, models.TrAccount.expire_date >= _now.strftime("%Y-%m-%d"), models.TrAccount.status == 1) dispatch.pub(logger.EVENT_INFO, 'expire_notify total: %s' % expire_query.count()) for account, expire, email, mobile in expire_query: ctx = notify_tpl.replace('#account#', account) ctx = ctx.replace('#expire#', expire) topic = ctx[:ctx.find('\n')] if email: self.send_mail(email, topic, ctx).addCallbacks(self.syslog.info, self.syslog.error) url = notify_url.replace('{account}', account) url = url.replace('{expire}', expire) url = url.replace('{email}', email) url = url.replace('{mobile}', mobile) url = url.encode('utf-8') url = quote(url, ":?=/&") httpclient.get(url).addCallbacks(self.syslog.info, self.syslog.error) return notify_interval
def init_route(self): handler_path = os.path.join(os.path.abspath(os.path.dirname(__file__))) load_handlers(handler_path=handler_path, pkg_prefix="toughradius.manage", excludes=['views','webserver','radius']) conn = self.db() try: oprs = conn.query(models.TrOperator) for opr in oprs: if opr.operator_type > 0: for rule in self.db.query(models.TrOperatorRule).filter_by(operator_name=opr.operator_name): permit.bind_opr(rule.operator_name, rule.rule_path) elif opr.operator_type == 0: # 超级管理员授权所有 permit.bind_super(opr.operator_name) except Exception as err: dispatch.pub(logger.EVENT_ERROR,"init route error , %s" % str(err)) finally: conn.close()
def get_error_html(self, status_code=500, **kwargs): dispatch.pub( logger.EVENT_ERROR, "http error : [status_code:{0}], {1}".format( status_code, utils.safestr(kwargs))) if self.settings.debug: traceback.print_exc() if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest': return self.render_json(code=1, msg=u"%s:服务器处理失败,请联系管理员" % status_code) if status_code == 404: return self.render_error(msg=u"404:页面不存在") elif status_code == 403: return self.render_error(msg=u"403:非法的请求") elif status_code == 500: return self.render_error(msg=u"500:服务器处理失败,请联系管理员") else: return self.render_error(msg=u"%s:服务器处理失败,请联系管理员" % status_code)
def post(self): active = self.get_argument("active", "syscfg") for param_name in self.get_params(): if param_name in ("active", "submit"): continue param = self.db.query(models.TrParam).filter_by(param_name=param_name).first() if not param: param = models.TrParam() param.param_name = param_name param.param_value = self.get_argument(param_name) self.db.add(param) else: param.param_value = self.get_argument(param_name) dispatch.pub(db_cache.CACHE_SET_EVENT,param.param_name,param.param_value,600) self.add_oplog(u'操作员(%s)修改参数' % (self.current_user.username)) self.db.commit() self.redirect("/admin/param?active=%s" % active)
def post(self): @self.cache.cache(expire=60) def get_bas_by_addr(nasaddr): return self.db.query( models.TrBas).filter_by(ip_addr=nasaddr).first() try: req_msg = self.parse_request() if 'nasaddr' not in req_msg: raise ValueError(u"nasaddr is empty") except Exception as err: self.render_result(code=1, msg=utils.safeunicode(err.message)) return try: nasaddr = req_msg['nasaddr'] nas = get_bas_by_addr(nasaddr) if not nas: self.render_result(code=1, msg=u'nas {0} not exists'.format(nasaddr)) return api_addr = "{0}://{1}".format(self.request.protocol, self.request.host) result = { 'code': 0, 'msg': 'ok', 'ipaddr': nasaddr, 'secret': nas.bas_secret, 'vendor_id': nas.vendor_id, 'coa_port': int(nas.coa_port or 3799), 'nonce': str(int(time.time())), } self.render_result(**result) except Exception as err: dispatch.pub( logger.EVENT_ERROR, u"api fetch nas error, %s" % utils.safeunicode(traceback.format_exc())) self.render_result(code=1, msg=u"api error")
def init_route(self): handler_path = os.path.join(os.path.abspath(os.path.dirname(__file__))) load_handlers(handler_path=handler_path, pkg_prefix="toughradius.manage", excludes=['views', 'webserver', 'radius']) conn = self.db() try: oprs = conn.query(models.TrOperator) for opr in oprs: if opr.operator_type > 0: for rule in self.db.query(models.TrOperatorRule).filter_by( operator_name=opr.operator_name): permit.bind_opr(rule.operator_name, rule.rule_path) elif opr.operator_type == 0: # 超级管理员授权所有 permit.bind_super(opr.operator_name) except Exception as err: dispatch.pub(logger.EVENT_ERROR, "init route error , %s" % str(err)) finally: conn.close()
def bill_pptimes(self, online, product): # 预付费时长 dispatch.pub( logger.EVENT_INFO, '%s > Prepaid long time billing ' % self.account.account_number) user_balance = self.get_user_balance() sessiontime = decimal.Decimal(self.request.acct_session_time) billing_times = decimal.Decimal(online.billing_times) acct_times = sessiontime - billing_times fee_price = decimal.Decimal(product['fee_price']) usedfee = acct_times / decimal.Decimal(3600) * fee_price usedfee = actual_fee = int(usedfee.to_integral_value()) balance = user_balance - usedfee if balance < 0: balance = 0 actual_fee = user_balance self.update_billing( Storage(account_number=online.account_number, nas_addr=online.nas_addr, acct_session_id=online.acct_session_id, acct_start_time=online.acct_start_time, acct_session_time=self.request.acct_session_time, input_total=self.get_input_total(), output_total=self.get_output_total(), acct_times=int(acct_times.to_integral_value()), acct_flows=0, acct_fee=usedfee, actual_fee=actual_fee, balance=balance, time_length=0, flow_length=0, is_deduct=1, create_time=datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S"))) if balance == 0: self.disconnect(online)
def acctounting(self): if self.is_online(self.request.nas_addr,self.request.acct_session_id): return dispatch.pub(logger.EVENT_ERROR,'online %s is exists' % self.request.acct_session_id) if not self.account: return dispatch.pub(logger.EVENT_ERROR,'user %s not exists' % self.request.account_number) online = Storage( account_number = self.request.account_number, nas_addr = self.request.nas_addr, acct_session_id = self.request.acct_session_id, acct_start_time = datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S"), framed_ipaddr = self.request.framed_ipaddr, mac_addr = self.request.mac_addr, nas_port_id = self.request.nas_port_id, billing_times = 0, input_total = 0, output_total = 0, start_source = STATUS_TYPE_START ) self.add_online(online) dispatch.pub(logger.EVENT_INFO,'%s Accounting start request, add new online'%online.account_number)
def process(self, *args, **kwargs): dispatch.pub(logger.EVENT_INFO,"process ddns update task..") with make_db(self.db) as db: try: nas_list = db.query(models.TrBas) for nas in nas_list: if not nas.dns_name: continue results, _, _ = yield client.lookupAddress(nas.dns_name) if not results: dispatch.pub(logger.EVENT_INFO,"domain {0} resolver empty".format(nas.dns_name)) if results[0].type == dns.A: ipaddr = ".".join(str(i) for i in struct.unpack("BBBB", results[0].payload.address)) if ipaddr: nas.ip_addr = ipaddr db.commit() dispatch.pub(logger.EVENT_INFO,"domain {0} resolver {1} success".format(nas.dns_name,ipaddr)) else: dispatch.pub(logger.EVENT_INFO,"domain {0} no ip address,{1}".format(nas.dns_name, repr(results))) except Exception as err: dispatch.pub(logger.EVENT_ERROR,'ddns process error %s' % utils.safeunicode(err.message)) defer.returnValue(60)
def load_events(self, event_path=None, pkg_prefix=None): _excludes = ['__init__', 'settings'] evs = set(os.path.splitext(it)[0] for it in os.listdir(event_path)) evs = [it for it in evs if it not in _excludes] for ev in evs: try: sub_module = os.path.join(event_path, ev) if os.path.isdir(sub_module): dispatch.pub(logger.EVENT_INFO, 'load sub event %s' % ev) self.load_events(event_path=sub_module, pkg_prefix="{0}.{1}".format( pkg_prefix, ev)) _ev = "{0}.{1}".format(pkg_prefix, ev) dispatch.pub(logger.EVENT_INFO, 'load_event %s' % _ev) dispatch.register( importlib.import_module(_ev).__call__( dbengine=self.db_engine, mcache=self.mcache)) except Exception as err: dispatch.pub(logger.EVENT_EXCEPTION, err) dispatch.pub( logger.EVENT_ERROR, "%s, skip event %s.%s" % (str(err), pkg_prefix, ev)) continue
def processPacket(self, req, bas=None): if req.code != packet.AccessRequest: raise PacketError( 'non-AccessRequest packet on authentication socket') try: reply = req.CreateReply() reply.vendor_id = req.vendor_id aaa_request = dict(account_number=req.get_user_name(), domain=req.get_domain(), macaddr=req.client_mac, nasaddr=req.get_nas_addr(), vlanid1=req.vlanid1, vlanid2=req.vlanid2) auth_resp = RadiusAuth(self, aaa_request).authorize() print auth_resp if auth_resp['code'] > 0: reply['Reply-Message'] = auth_resp['msg'] reply.code = packet.AccessReject return reply if 'bypass' in auth_resp and int(auth_resp['bypass']) == 0: is_pwd_ok = True else: is_pwd_ok = req.is_valid_pwd(auth_resp.get('passwd')) if not is_pwd_ok: reply['Reply-Message'] = "password not match" reply.code = packet.AccessReject return reply else: if u"input_rate" in auth_resp and u"output_rate" in auth_resp: reply = rate_process.process( reply, input_rate=auth_resp['input_rate'], output_rate=auth_resp['output_rate']) attrs = auth_resp.get("attrs") or {} for attr_name in attrs: try: # todo: May have a type matching problem reply.AddAttribute(utils.safestr(attr_name), attrs[attr_name]) except Exception as err: errstr = "RadiusError:current radius cannot support attribute {0},{1}".format( attr_name, utils.safestr(err.message)) dispatch.pub(logger.EVENT_ERROR, errstr) for attr, attr_val in req.resp_attrs.iteritems(): reply[attr] = attr_val reply['Reply-Message'] = 'success!' reply.code = packet.AccessAccept if not req.VerifyReply(reply): raise PacketError('VerifyReply error') return reply except Exception as err: reply['Reply-Message'] = "auth failure, %s" % utils.safeunicode( err.message) reply.code = packet.AccessReject return reply
logger.EVENT_INFO, "[Radiusd] :: Received radius request: %s" % (repr(radius_request))) if self.config.system.debug: dispatch.pub(logger.EVENT_DEBUG, radius_request.format_str()) reply = self.processPacket(radius_request, bas) self.reply(reply, (host, port)) except Exception as err: errstr = 'RadiusError:Dropping invalid packet from {0} {1},{2}'.format( host, port, utils.safeunicode(err)) dispatch.pub(logger.EVENT_ERROR, errstr) import traceback traceback.print_exc() def reply(self, reply, (host, port)): dispatch.pub(logger.EVENT_INFO, "[Radiusd] :: Send radius response: %s" % repr(reply)) if self.config.system.debug: dispatch.pub(logger.EVENT_DEBUG, reply.format_str()) self.transport.write(reply.ReplyPacket(), (host, port)) ############################################################################### # Auth Server #### ############################################################################### class RADIUSAccess(RADIUS): """ Radius Access Handler """ def createPacket(self, **kwargs): vendor_id = kwargs.pop('vendor_id', 0)
def acctounting(self): self.unlock_online(self.request.nas_addr, None) dispatch.pub(logger.EVENT_INFO, 'bas accounting onoff success')
def exception(err, **kwargs): if EVENT_EXCEPTION in dispatch.dispatch.callbacks: dispatch.pub(EVENT_EXCEPTION, err, **kwargs) if EVENT_TRACE in dispatch.dispatch.callbacks: dispatch.pub(EVENT_TRACE, "exception", repr(err), **kwargs)