def is_root(pid, user_acl): """check root for project 判断是否对项目有root权限 Args: pid: user_acl: dict Returns: AclCode """ p = Common.collection_find(user_acl, lambda s: s['pid'] == int(pid)) if p is not None: t = Common.collection_find(p['acl'], lambda s: s['tid'] == 0) if t is not None: return t['acl'] return 0
def get_acl_templates(pid, user_acl): """get acl for project """ plist = [] p = Common.collection_find(user_acl, lambda s: s['pid'] == int(pid)) if p is None: return plist return copy.deepcopy(p['acl'])
def _checkACL(self,mod,action): pid = self.get_argument('pid','0') tid = self.get_argument('tid','0') #print self.session.get('userinfo') acl = json.loads(self.session.get('userinfo'))['acl'] acl_code = self.__get_acl_code(mod,action) #print "ACL:",acl,acl_code #无ACL的直接跳出 if acl_code==0: return True #超级管理员跳出 pacl = Common.collection_find(acl,lambda s:s['pid']==0) if pacl is not None: return True #项目鉴权 pacl = Common.collection_find(acl,lambda s:s['pid']==int(pid)) #print 'PACL',pacl,acl_code if pacl is None: self.__go_to(Error.ACLERROR) return False tacl = Common.collection_find(pacl['acl'],lambda s:s['tid']==0) if tacl is None: tacl = Common.collection_find(pacl['acl'],lambda s:s['tid']==int(tid)) print('TACL',tid) if tacl is None: self.__go_to(Error.ACLERROR) return False else: print('TACL:',tacl,acl_code) if (tacl['acl']&acl_code)==acl_code: return True else: self.__go_to(Error.ACLERROR) return False else: if (tacl['acl']&acl_code)==acl_code: return True else: self.__go_to(Error.ACLERROR) return False
def get_api_info(self, corp, apiname): """get api info 获取API信息 Args: corp:组织机构 apiname:api名称 Returns: dict """ if corp not in self.third_party_cfg: return None return Common.collection_find(self.third_party_cfg[corp], lambda s: s['name'] == apiname)
def get_field_list(self, **kwargv): """get fulltext fields by tid,pid 获取可用全文字段列表 Args: kwargv: curent:当前fl字段 available:做可用过滤 pid:pid tid:tid fid:fid Returns: recode """ curent = '' if 'curent' not in kwargv else kwargv['curent'] available = False if 'available' not in kwargv else kwargv['available'] tid = 0 if 'tid' not in kwargv else int(kwargv['tid']) pid = 0 if 'pid' not in kwargv else int(kwargv['pid']) # fid = 0 if 'fid' not in kwargv else int(kwargv['fid']) if available and tid != 0: # 加载fl数据 sql = 'select distinct `fl_field` from `cms_template_field` where `template_id`=' + str( tid) + " and fl_field<>''" n, data = self.webapp.db.executeQuery(pid, sql) if n < 0: return copy.deepcopy(Error.MODPARAMERR) fl_fields = [] for row in data: fl_fields.append(row[0]) pass target_fl_fields = [] fl_schema = self.webapp.cfg['fulltext']['schema'] for item in fl_schema: k = list(item.items())[0][0] if curent == k: target_fl_fields.append({'fl_name': k, 'selected': True}) elif (curent[-2:] in ('_i', '_s')) or (curent[-5:] in ('_text', '_date')): target_fl_fields.append({'fl_name': curent, 'selected': True}) elif Common.collection_find(fl_fields, lambda s: s == k) is None: target_fl_fields.append({'fl_name': k, 'selected': False}) recode = copy.deepcopy(Error.SUCC) recode['data'] = target_fl_fields return recode
def __update_project(self, action, isapi=False): """ add/update project controller 创建/修改项目的路由 Argument: isapi:是否为操作接口,False为view路由,True为API操作 """ pass if isapi == False: if action == 'add': self.render('admin_project.html', action='add', project_id=0, userinfo=self.userinfo) if action == 'update': self.write('not supported') else: # 项目入库并初始化 proj = ModProject(self.application) name = self.get_argument('name', '') domain = self.get_argument('domain', '') rsync = self.get_argument('rsync', '') mysql = self.get_argument('mysql', '') enable = int(self.get_argument('enable', '1')) pid = int(self.get_argument('pid', '0')) if action == 'add': _proj = Common.collection_find(self.application.cfg['db'], lambda s: s['project'] == name) if _proj is not None: self.write(json.dumps(Error.MODDATAEXISTED)) return result = proj.add(project_id=pid, project_name=name, domain=domain, rsync_uri=rsync, mysql_uri=mysql, enable=enable) self.write(json.dumps(result)) return if action == 'update': self.write('not supported')
def remove_template(self, pid, tid): """ remove template 删除模板,删除前会备份至安全区目录./safearea Args: pid: tid: Returns: """ _cfg = Common.collection_find(self.conf['db'], lambda s: s['pid'] == int(pid)) if _cfg is None: return Error.DATANOTEXISTED _cfg['tid'] = tid cmd = "mysqldump -h " + _cfg['host'] + " -u " + _cfg['user'] + " -p" + _cfg['passwd'] + " cms_site_" + str( pid) + " cms_tbl_" + str(tid) + " >./safearea/" + str(pid) + "_" + str(tid) + ".sql" child = subprocess.Popen([cmd], shell=True) child.wait() cmd = 'mysql -h{$host} -P{$port} -u {$user} -p{$passwd} --execute="select * from cms_template where template_id={$tid}" cms_site_{$pid} >./safearea/template_cfg_{$pid}_{$tid}.bak' cmd = Common.exp_render(cmd, _cfg) child = subprocess.Popen([cmd], shell=True) child.wait() cmd = 'mysql -h{$host} -P{$port} -u {$user} -p{$passwd} --execute="select * from cms_template_field where template_id={$tid}" cms_site_{$pid} >./safearea/template_field_{$pid}_{$tid}.bak' cmd = Common.exp_render(cmd, _cfg) child = subprocess.Popen([cmd], shell=True) child.wait() sql = "DROP TABLE IF EXISTS `cms_tbl_" + str(tid) + "`;\n" sql = sql + "delete from `cms_template_field` where template_id=" + str(tid) + ";\n" sql = sql + "delete from `cms_template` where template_id=" + str(tid) + ";" n, data = self.db.execute(pid, sql, mutiline=True) if n < 0: return data return Error.SUCC
def __list_documents(self): """list all document for template 列出指定模板下的所有文档 Args: Returns: List[] """ pid = int(self.get_argument('pid', 0)) tid = int(self.get_argument('tid', 0)) pageindex = int(self.get_argument('page', 1)) pflag = int(self.get_argument('pflag', -1)) fl = "1" display_status = '全部' if pflag == 0: fl = "(publish_url is NULL or publish_url='')" display_status = '未发布' if pflag == 1: fl = "(publish_url is not NULL or publish_url<>'')" display_status = '已发布' if pid == 0 or tid == 0: self.write(json.dumps(Error.CGIREQUESTERR)) # 构建Component Tag列表 ctag = self.get_argument('ctag', '') with_data = [] if ctag != '': with_data.append(ctag) _component = ModComponent(self.application) n, tag_data = _component.get_component_tags(pid, tid) if n < 0: return Error.DBERROR # 构建筛选器 dk:关键词 df:所选模板域(field) dk = self.get_argument('dk', '') df = self.get_argument('df', '') field = ModField(self.application) _n, field_list = field.get_field_list(pid, tid, detail=False, with_system=True) if dk != '' and df != '': # 对时间类型、数值类型、字符串类型特殊处理 if df in ('create_time', 'publish_time'): dk = Common.filter_digit(dk) dk = "" if len( dk) != 8 else dk[:4] + "-" + dk[4:6] + "-" + dk[6:8] if dk != "": fl = fl + " and " + df + ">'" + dk + " 00:00:00' and " + df + "<='" + dk + " 23:59:59'" elif df in ('document_id'): dk = Common.filter_digit(dk) dk = "0" if dk == "" else dk fl = fl + "document_id=" + dk else: fl = fl + " and " + df + " like '%" + dk + "%'" # 构建文档列表 page = int(self.get_argument('page', 1)) doc = ModDocument(self.application) pagesize = 30 count, data = doc.get_document_list(pid, tid, pagesize, pageindex, fl, ' document_id desc', True, with_data) if count < 0: self.write(json.dumps(data)) return p_cfg = Common.collection_find(self.application.cfg['db'], lambda s: s['pid'] == int(pid)) domain = '' if p_cfg is None else p_cfg['domain'] pageinfo = Common.make_page(count, pageindex, pagesize, 20) self.render_ex('editor_document_list.html', project_id=pid, template_id=tid, data=data, domain=domain, pageinfo=pageinfo, pflag=pflag, display_status=display_status, field_list=field_list, tags=tag_data, ctag=ctag, dk=dk, df=df)
def render(algorithm_type, **kwargv): """rend field by algorithm """ global redis pid = kwargv['project_id'] tid = kwargv['template_id'] fid = kwargv['field_id'] field_type = kwargv['field_type'] field_algorithm = kwargv['field_algorithm'] data_key = kwargv['data_key'] if 'field_value' in kwargv: field_value = kwargv['field_value'] else: field_value = '' algorithm_type = 'script' if algorithm_type == 'script' else 'input' logging.info('[Compiler]: start render') # print "Source Code:",field_algorithm _algorithm = Algorithm.parse_algorithm(field_algorithm) # print "ALGORITHM:",_algorithm lang_cfg = Common.collection_find( kwargv['lang_cfg'], lambda s: s['lang'] == _algorithm[algorithm_type]['lang']) cms_assert( (lang_cfg is None and _algorithm[algorithm_type]['lang'] != 'raw'), 500, 'not support ' + _algorithm[algorithm_type]['lang']) if _algorithm[algorithm_type]['lang'] == 'raw': # 判断算法类型,input则只读取raw配套的data,script则需要优先使用raw,如raw配套为空,则使用用户数据field_value if _algorithm[algorithm_type]['data'].strip() != '': print('===>', _algorithm[algorithm_type]['data'], '<====') logging.warning('=====>INPUT RAW DATA<======' + str(_algorithm[algorithm_type]['data'])) return _algorithm[algorithm_type]['data'] elif algorithm_type == 'script': return field_value else: return '' root = os.path.split(os.path.realpath(__file__))[0] cmd = lang_cfg['cfg']['run'].replace('{$root}', root) cmd = cmd.replace('%1', data_key) logging.info('[Compiler]:CMD**' + cmd) # 构建算法文件input类型前缀为developer_ script类型前缀为user_ # prefix = 'user_' if algorithm_type=='script' else 'devloper_' prefix = algorithm_type + '_' path = root + '/plugins/script/' + lang_cfg[ 'lang'] + '/usr/' + prefix + str(pid) + '_' + str(tid) + '_' + str( fid) + '.' + lang_cfg['cfg']['extname'] logging.info('[Compiler]: ALGOR PATH:' + path) algo = Algorithm() _ready = False if os.path.exists(path): fp = open(path, 'r') _code = fp.read() fp.close() target_hash = Common.md5(_code) source_hash = Common.md5(_algorithm[algorithm_type]['data']) # print target_hash,source_hash if target_hash == source_hash: _ready = True # __out = algo.execute(cmd) # logging.info('[Compiler]:'+__out) # logging.info('[Compiler]:end render') # return __out if not _ready: fp = open(path, 'w') fp.write(_algorithm[algorithm_type]['data']) fp.close() _ready = True logging.info('[Compiler]:end render') _out = algo.execute(cmd) cms_assert(_out == 'algorithm time out', 500, 'algorith time out!!!') # 解析算法stdio输出结果,注意渲染结果和错误信息均在share memory中,stdio只有对应的key值 # 解析错误信息 _p = re.compile(r"\[CMSERRKEY=.*?\]") _errkey = _p.findall(_out) if len(_errkey) >= 1: _script_errinfo = json.loads( redis.get(_errkey[0].replace('[CMSERRKEY=', '').replace(']', ''))) cms_assert( _script_errinfo['errcode'] == Error.ALGORITHMABORT['code'], 500, Error.ALGORITHMABORT['errmsg'] + " Detail:" + _script_errinfo['errmsg']) # 解析渲染结果信息 _p = re.compile(r"\[CMSDATAKEY=.*?\]") _key = _p.findall(_out) # print '@@@@@@@@@',_key if len(_key) == 1: return redis.get(_key[0].replace('[CMSDATAKEY=', '').replace(']', '')) else: return _out
exit(1) print('continue-2') # 获取任务信息 algorithm_type = header_mail['tag'] pid = header_mail['pid'] tid = header_mail['tid'] did = header_mail['did'] smid = header_mail['smid'] curent_user = header_mail['user'] preview = header_mail['preview'] # logging.info(str(cfg['db'])) logging.info(str(pid) + " ready!") db_cfg = Common.collection_find(cfg['db'], lambda s: s['pid'] == int(pid)) print(header_mail) logging.info('DB:' + str(db_cfg)) cms_assert(db_cfg is None, 404, "can't find db cfg") db = DbManager() db.initConn([db_cfg]) pid = str(pid) proj = Common.collection_find(project_cfg, lambda s: s['pid'] == int(pid)) cms_assert((proj is None and preview == 'N'), 404, "can't find publish domain,please check cfg") domain = proj['domain'] # 获取模板信息 sql = "select `template_view`,`publish_callback`,`publish_url` from `cms_template` where `template_id`=" + str(
def __update_user_acl(self, action, isapi=False): """update user template acl 更新用户模板详细设置 Args: action: isapi Returns: """ uid = int(self.get_argument('uid', 0)) pid = int(self.get_argument('pid', 0)) if uid == 0 or pid == 0: self.write(json.dumps(Error.CGIREQUESTERR)) return _usr = ModUser(self.application) if isapi == False: _template = ModTemplate(self.application) n, data = _template.get_template_list(pid) if n < 0: self.write(json.dumps(Error.MODPARAMERR)) return uinfo = _usr.get_user_info(uid=uid) uinfo = { 'uid': '', 'username': '', 'avator': '', 'status': 1, 'acl': '[]' } if uinfo is None else uinfo tlist = ACL.get_acl_templates(pid, json.loads(uinfo['acl'])) # 检查root_acl user_acl = Common.collection_find(tlist, lambda s: s['tid'] == 0) project_root_acl = 0 if user_acl is None else user_acl['acl'] templates = [{ 'template_id': 0, 'template_name': '*', 'acl': project_root_acl }] # 获取普通模板acl for row in data: _item = { 'template_id': int(row[0]), 'template_name': row[2], 'acl': 0 } user_acl = Common.collection_find( tlist, lambda s: s['tid'] == int(row[0])) if user_acl is not None: _item['acl'] = user_acl['acl'] templates.append(_item) self.render('system_user_detail.html', templates=templates, acl=ACL.AclCode, target=uinfo, project_id=pid, userinfo=self.userinfo) else: acl = self.get_arguments('acl') uinfo = _usr.get_user_info(uid=uid) if uinfo is None: self.write(json.dumps(Error.ACL_NOTFOUNDUSER)) return _uacl = json.loads(uinfo['acl']) # item:tid_DOC_E .... # 构建一个需要追加权限的list _new_template_acl = [] _tid_set = [] for item in acl: _tid = item.split('_')[0] if _tid not in _tid_set: _tid_set.append(_tid) _tacl = Common.collection_find(_new_template_acl, lambda s: s['tid'] == int(_tid)) if _tacl is not None: # 这里修改的是引用值,不是深拷贝 _index = _new_template_acl.index(_tacl) _new_template_acl[_index] = { 'tid': int(_tid), 'acl': _tacl['acl'] | ACL.AclCode[item.replace(_tid + '_', '')] } else: # 没有的就追加 _new_template_acl.append({ 'tid': int(_tid), 'acl': ACL.AclCode[item.replace(_tid + '_', '')] }) # 修改template表的allow _template = ModTemplate(self.application) recode = _template.update_template_allow(pid, uinfo['username'], _tid_set) if recode['code'] != 0: self.write(json.dumps(recode)) return # 改写pacl _pacl = Common.collection_find(_uacl, lambda s: s['pid'] == pid) if _pacl is None: _uacl.append({'pid': pid, 'acl': _new_template_acl}) else: _pacl['acl'] = _new_template_acl recode = _usr.update_user_info(uid=uid, acl=json.dumps(_uacl)) if recode['code'] == 0: self.set_status(302) self.set_header('Location', '/system/user?action=list') return else: self.write(json.dumps(recode)) return
def __update_user(self, action, isapi=False): """create/update user base info 创建更改用户基本信息 Args: action isapi Returns: """ uid = self.get_argument('uid', '0') print(self.application.cfg['db']) projects = copy.deepcopy(self.application.cfg['db']) projects.reverse() projects.pop() projects.reverse() projects.append({'pid': 0, 'project': '*'}) mod = ModUser(self.application) if not isapi: uinfo = mod.get_user_info(uid=uid) uinfo = { 'uid': '', 'username': '', 'nickname': '', 'avator': '', 'status': 1, 'acl': '[]' } if uinfo is None else uinfo date = [] plist = ACL.get_acl_projects(json.loads(uinfo['acl'])) for i in range(0, len(projects)): if uinfo is None: projects[i]['enable'] = 0 else: p = Common.collection_find( plist, lambda s: s == int(projects[i]['pid'])) projects[i]['enable'] = p is not None # projects[i]['acl'] = ACL.get_acl_projects(json.loads(uinfo['acl'])) self.render('system_user.html', projects=projects, target=uinfo, userinfo=self.userinfo) else: # 处理post username = self.get_argument('username', '') nickname = self.get_argument('nickname', '') avator = self.get_argument('avator', '') pid_set = self.get_arguments('projects') uinfo = mod.get_user_info(uid=uid) acl = [] if uinfo is not None: acl = json.loads(uinfo['acl']) # 扫2次,对比差异 new_acl = [] for item in acl: if Common.collection_find( pid_set, lambda s: s == str(item['pid'])) is not None: new_acl.append(item) for i in range(0, len(pid_set)): p = Common.collection_find( new_acl, lambda s: s['pid'] == int(pid_set[i])) if p is None: new_acl.append({'pid': int(pid_set[i]), 'acl': []}) # 完成构建 recode = mod.update_user_info(uid=uid, username=username, nickname=nickname, avator=avator, acl=json.dumps(new_acl)) if recode['code'] == 0: self.set_status(302) self.set_header('Location', '/system/user?action=list') else: self.write(json.dumps(recode))
def __compile_schema(self, schema_cfg): """convert schema config 编译callback配置,按照事件来区分,把相同事件和配置的回调合并,统一处理 结构描述: 旧: [ {'pid':pid,'onTimer:[{'setting':'****-**-** **:**','action':'publish(1,1 ,1)'}]' 'onPublish':[{'setting':'','action':'publish(1,1,1)'},.....] } ] 新: [{"onTimer":[ {"setting":"T5","action":"publish_local(1,2,3,4...)"}, {"setting":"T30","action":"publish_external(19,12,31)"}], "onPublish":[ {"setting":"{$did}==1","action":"publish_external(19,12,31)"}, {"setting":"{$did}==2","action":"publish_external(19,12,32)"}] } ] 说明:事件函数存在CMS私有环境变量,主要为pid,tid,did。引用格式为{$pid}... Args: schema_cfg:callback config<list> Return: {"onTimer": [{"setting":"T5","callback":[ {"env":{"pid":1,"tid":1},"action":"publish_local(1,2,3,4,5,6,7...)"}, {"env":{"pid":1,"tid":2},"action":"publish_local(1,2,3,4,5,6,7...)"} ]}, {"setting":"T10","callback":[ {"env":{"pid":1,"tid":1},"action":"publish_local(1,2,3,4,5,6,7...)"}, {"env":{"pid":1,"tid":2},"action":"publish_local(1,2,3,4,5,6,7...)"} ]} ] , "onPublish": [{"setting":"{$pid}==1 and {$tid}==1 and {$did}==1","callback":[ {"action":"publish_external(1,2,3)"}, {"action":"publish_external(1,2,4)"} ]}, {"setting":"{$pid}==1 and {$tid}==1 and {$did}==2","callback":[ {"action":"publish_external(1,2,3)"}, {"action":"publish_external(1,2,4)"} ]} ] , "onOtherEvent":.... 注意:回调发生时需要传递环境变量pid tid did,否则无法获取相关参数. """ compile_result = {'onTimer': [], 'onPublish': []} for proj in schema_cfg: # _proj_event = {'onTimer':[],'onPublish':[]} _env_pid = proj['pid'] for callback in proj['schema']: _env_tid = callback['tid'] # callback的key为tid、config,后者为入库内容 for event in callback['config']: # print 'EVENT',event for k, v in event.items(): # k为事件名,v为事件描述,包括setting/action # 校验事件和事件配置 if self.__vaild(k, v): # print "DEBUG====>",callback # 遍历各种setting for _setting in v: if type(_setting ) is dict and 'setting' in _setting: _target_setting = Common.collection_find( compile_result[k], lambda s: s[ 'setting'] == _setting['setting']) if _target_setting is None: # print '@@',compile_result[k],'$$',_setting compile_result[k].append({ "setting": _setting['setting'], "callback": [{ "env": { "pid": _env_pid, "tid": _env_tid }, "action": _setting['action'] }], "last_call": datetime.datetime.now() }) else: _target_setting['callback'].append({ "env": { "pid": _env_pid, "tid": _env_tid }, "action": _setting['action'] }) _target_setting[ 'last_call'] = datetime.datetime.now( ) pass else: logging.warning("Error callback:" + str(_setting)) # v['tid'] = callback['tid'] # v['last_call'] = datetime.datetime.now() # _proj_event[k].append(v) else: logging.warning('callback schema config error:' + str(v)) pass pass pass # compile_result.append(_proj_event) pass return compile_result