def legalize_ws(account: SsoAccount, sso: WorkspaceSso) -> requests.Session: """ 使用该账号认证该工作空间 :param account: :param sso: :return: session """ logger.info("{} 工作空间认证:".format(account.username, sso.ws_id)) session = requests.Session() try: rest = session.get(sso.portal_site, proxies=proxies, verify=False, timeout=timeout) session.post(rest.url, data={ 'username': account.username, 'password': account.password, 'confirm': 'yes' }, proxies=proxies, verify=False, timeout=timeout) except Exception as e: raise AccountException(e) return session
def wrapper(*args, **kwargs): if 'username' not in session: return redirect(url_for("web.login")) if not method or request.method == method: # 不设置method或当前请求方法匹配时 for r in policies: if r.value not in session['role']: return redirect(url_for("web.login")) logger.info("{} {}".format(session.get("username"), request.url)) return func(*args, **kwargs)
def status_clear(): """ 刷新状态 :return: """ logger.info("job status_clear ...") # 工作空间状态 Workspace.objects(Workspace.status == Workspace.STATUS_START).update( status=Workspace.STATUS_STOP)
def watch_hosts(portal_site): """ 获取url下的所有hosts,以及sso认证时所需要的一些信息 可根据自己实际情况获取,可能会有前后端分离的情况,可以自己去解析 本示例比较简单,只简单获取当前url中的host :param portal_site: 首页url :return: (redirect_url, system_type, hosts, portal_site) """ logger.info("watch hosts: {} begin...".format(portal_site)) hs = re.findall(r'http[s]?://([\w.:-]+).*$', portal_site) rest = requests.get(portal_site) system_type = Workspace.TYPE_SSO logger.info("watch hosts: {} -> {}".format(portal_site, hs)) return rest.url, system_type, hs, portal_site
def wrapper(*args, **kwargs): if 'username' not in session: return redirect(url_for("web.login")) logger.info("{} {}".format(session.get('username'), request.url)) return func(*args, **kwargs)
def deal_with_direct(header: HeaderModel, body: BodyModel, name, packet_record: PacketRecord, auth: WorkspaceAuth): """ 手动录入认证信息 :param header: :param body: :param name: :param packet_record: :param auth: :return: """ logger.info("{} deal with direct: {}".format(name, header.url)) for auth_info in auth.auth_info: assert isinstance(auth_info, AuthInfo) if auth_info.url_pattern and not re.match(auth_info.url_pattern, header.url): # url_pattern continue _header = copy.copy(header) _body = copy.copy(body) try: if auth_info.auth_args: _header.update_args(auth_info.auth_args) if auth_info.auth_header: _header.update_headers(auth_info.auth_header) if auth_info.auth_param: _body.update_param(auth_info.auth_param) if _body.type == BodyModel.TYPE_JSON: raw_rest = requests_request(_header.method, _header.url, json=_body.body(), headers=_header.header) elif _body.type in [BodyModel.TYPE_FORM, BodyModel.TYPE_BYTE]: raw_rest = requests_request(_header.method, _header.url, data=_body.body(), headers=_header.header) else: raise ParserException("illegal body type {}".format( _body.type)) except Exception as e: logger.error("{} processing error!".format(auth_info.describe), exc_info=True) packet_data = PacketData(banner=gen_banner(auth_info.describe, _header.method, _header.url, str(e)), role_describe=auth_info.describe) packet_data.save() packet_record.per_packets.append(packet_data) else: resp_body = BodyModel(raw_rest.content, charset=raw_rest.encoding) packet_data = PacketData( banner=gen_banner(auth_info.describe, _header.method, _header.url, raw_rest.text), role_describe=auth_info.describe, request=Request(url=_header.url, method=_header.method, header=_header.header, body_content=_body.content, body_type=_body.type), response=Response(status_code=raw_rest.status_code, header=raw_rest.headers, body_content=resp_body.content, body_type=resp_body.type)) packet_data.save() packet_record.per_packets.append(packet_data)
def deal_with_sso(header: HeaderModel, body: BodyModel, name, packet_record: PacketRecord, sso: WorkspaceSso, ws: Workspace): """ 处理sso认证的系统 :param header: :param body: :param name: :param packet_record: :param sso: :param ws: :return: """ rs = redis.Redis(connection_pool=redis_pool) hm_key = "{}:{}".format(name, ws.id) # session logger.info("{} deal with sso: {}".format(name, header.url)) _header = header.header if 'Cookie' in _header.keys(): _header.pop('Cookie') for account_id, describe in sso.roles.items(): account = SsoAccount.objects(id=account_id) if len(account) == 0: logger.error("no {}->{}!".format(account_id, describe)) continue account = account[0] assert isinstance(account, SsoAccount) _r = describe if describe else account.describe if account.describe else account.username try: if account.username == '-': # 空角色 if body.type == BodyModel.TYPE_JSON: raw_rest = requests_request(header.method, header.url, json=body.body(), headers=_header) elif body.type in [BodyModel.TYPE_FORM, BodyModel.TYPE_BYTE]: raw_rest = requests_request(header.method, header.url, json=body.body(), headers=_header) else: raise ParserException("Illegal body type{}".format( body.type)) else: # 正常账号 auth_session = rs.hmget(hm_key, str(account.id))[0] if not auth_session: session = legalize_ws(account, sso) auth_session = AuthSession(session, account) rs.hset(hm_key, str(account.id), pickle.dumps(auth_session)) else: auth_session = pickle.loads(auth_session) rs.expire(hm_key, 60 * session_timeout) # 重设超时时间 if body.type == body.TYPE_JSON: raw_rest = auth_session.request(header.method, header.url, json=body.body(), headers=_header) elif body.type in [BodyModel.TYPE_FORM, BodyModel.TYPE_BYTE]: raw_rest = auth_session.request(header.method, header.url, data=body.body(), headers=_header) else: raise ParserException('Illegal body type {}'.format( body.type)) except Exception as e: logger.error("{} {} processing error!".format( account_id, describe), exc_info=True) if isinstance(e, AccountException): # 账号失效 account.status = SsoAccount.STATUS_INVALID account.save() packet_data = PacketData(banner=gen_banner(_r, header.method, header.url, str(e)), role_describe=_r) packet_data.save() packet_record.per_packets.append(packet_data) else: resp_body = BodyModel(raw_rest.content, charset=raw_rest.encoding) packet_data = PacketData( banner=gen_banner(_r, header.method, header.url, raw_rest.text), role_describe=_r, request=Request(url=header.url, method=header.method, header=raw_rest.request.headers, body_content=body.content, body_type=body.type), response=Response(status_code=raw_rest.status_code, header=raw_rest.headers, body_content=resp_body.content, body_type=resp_body.type)) packet_data.save() packet_record.per_packets.append(packet_data)