Exemplo n.º 1
0
 def invite_content(self, email, tenant_name, identity, eid):
     if settings.MODULES.get('SSO_LOGIN'):
         domain = SSO_BASE_URL
         mail_body = AuthCode.encode(
             ','.join(['invite_tenant', email, tenant_name, identity, eid]),
             'goodrain')
         link_url = '{0}/api/invite?key={1}'.format(domain, mail_body)
     else:
         domain = self.request.META.get('HTTP_HOST')
         mail_body = AuthCode.encode(
             ','.join([email, tenant_name, identity, eid]), 'goodrain')
         link_url = 'http://{0}/invite?key={1}'.format(domain, mail_body)
     content = render_to_string('mail_invite.html', {
         'link_url': link_url,
         'inviter': tenant_name
     })
     return content
Exemplo n.º 2
0
    def post(self, request, *args, **kwargs):
        """微信通知处理入口, 云帮不做处理只是转发请求给云市处理"""
        body_raw = request.body
        logger.debug("account.wechat",
                     "recv wechat notify: {}".format(body_raw))
        # 将xml转成dict
        data = dict(
            (child.tag, child.text) for child in ET.fromstring(body_raw))
        logger.debug("account.wechat", "format to map: {}".format(data))
        msg_type = data["MsgType"]
        # 非事件类消息不处理
        if msg_type != "event":
            return HttpResponse("")

        # 当前只处理公众号订阅跟扫码消息
        event_type = data["Event"]
        if event_type not in self.ALLOW_EVENT:
            return HttpResponse("")

        post_data = {}
        if event_type == "subscribe":
            # 只处理qrscene_xxxx类型的场景关注通知
            if "EventKey" not in data:
                return HttpResponse("")

            user_id = data["EventKey"].split("_")[1]
            open_id = data["FromUserName"]
            user_id, open_id = self.bind_wechat_user_to_goodrain(
                user_id, open_id)
            post_data = {
                "user_id": user_id,
                "open_id": open_id,
                "event_type": "subscribe"
            }
        elif event_type == "SCAN":
            user_id = data["EventKey"]
            open_id = data["FromUserName"]
            user_id, open_id = self.bind_wechat_user_to_goodrain(
                user_id, open_id)
            post_data = {
                "user_id": user_id,
                "open_id": open_id,
                "event_type": "scan"
            }

        # 不管上面绑定关系如何, 用户确实完成对公众号的关注,所以将事件推送到关注的监听者
        for url in self.REGISTER_LISTENER:
            try:
                body_encode = AuthCode.encode(json.dumps(post_data),
                                              "goodrain")
                logger.debug("account.wechat",
                             "post {} with data {}".format(url, post_data))
                # 微信端5秒内需要返回
                requests.post(url, data={"body": body_encode}, timeout=4)
            except Exception as e:
                logger.exception("push event to market failed!", e)

        return HttpResponse("")
Exemplo n.º 3
0
    def export_group_backup(self, tenant, backup_id):
        backup_record = backup_record_repo.get_record_by_backup_id(tenant.tenant_id, backup_id)
        if not backup_record:
            return 404, "不存在该备份记录", None
        if backup_record.mode == "full-offline":
            return 409, "本地备份数据暂不支持导出", None
        if backup_record.status == "starting":
            return 409, "正在备份中,请稍后重试", None

        data_str = AuthCode.encode(json.dumps(backup_record.to_dict()), KEY)
        return 200, "success", data_str
Exemplo n.º 4
0
    def get(self, request, *args, **kwargs):
        if not settings.MODULES["WeChat_Module"]:
            index_url = settings.WECHAT_CALLBACK.get("index")
            return self.redirect_to(index_url)
        # 获取cookie中的corf
        csrftoken = request.COOKIES.get('csrftoken')
        if csrftoken is None:
            csrftoken = "csrf"
        # 判断登录来源,默认从微信上登录
        origin = request.GET.get("origin", "console")
        origin_url = request.GET.get("redirect_url", "redirect_url")
        logger.debug("account.wechat", "origin_url=" + origin_url)
        next_url = request.GET.get("next", "")
        if origin == "discourse":
            sig = request.GET.get("sig")
            next_url = "{0}&sig={1}".format(next_url, sig)
        config = WECHAT_GOODRAIN
        oauth2 = 'https://open.weixin.qq.com/connect/oauth2/authorize'
        scope = 'snsapi_userinfo'
        # 判断是否微信浏览器
        if not is_weixin(request):
            config = WECHAT_USER
            oauth2 = 'https://open.weixin.qq.com/connect/qrconnect'
            scope = 'snsapi_login'
        state = AuthCode.encode(
            ','.join([csrftoken, origin, next_url, config, origin_url]),
            'we_chat_login')
        logger.debug("account.wechat", state)
        # 存储state
        wechat_state = WeChatState(state=state)
        wechat_state.save()

        # 获取user对应的微信配置
        config = WeChatConfig.objects.get(config=config)
        app_id = config.app_id
        # 扫码后微信的回跳页面
        redirect_url = settings.WECHAT_CALLBACK.get("console_goodrain")
        if not is_weixin(request):
            redirect_url = settings.WECHAT_CALLBACK.get("console")

        redirect_url = urllib.urlencode({"1": redirect_url})[2:]
        # 微信登录扫码路径
        url = "{0}?appid={1}" \
              "&redirect_uri={2}" \
              "&response_type=code" \
              "&scope={3}" \
              "&state={4}#wechat_redirect".format(oauth2,
                                                  app_id,
                                                  redirect_url,
                                                  scope,
                                                  wechat_state.ID)
        logger.debug(url)
        return self.redirect_to(url)
Exemplo n.º 5
0
    def invite_content(self, email, tenant_name, service_alias, identity):
        if settings.MODULES.get('SSO_LOGIN'):
            domain = SSO_BASE_URL
            mail_body = AuthCode.encode(
                ','.join([
                    'invite_service', email, tenant_name, service_alias,
                    identity
                ]), 'goodrain')
            link_url = '{0}/api/invite?key={1}'.format(domain, mail_body)
        else:
            domain = self.request.META.get('HTTP_HOST')
            mail_body = AuthCode.encode(
                ','.join([email, tenant_name, service_alias, identity]),
                'goodrain')
            link_url = 'http://{0}/invite?key={1}'.format(domain, mail_body)

        content = u"尊敬的用户您好,"
        content = content + "<br/>"
        content = content + u"非常感谢您申请试用 好雨云平台! 请点击下面的链接完成注册:"
        content = content + "<br/>"
        content = content + u"注册链接: <a target='_blank' color='red' href=" + link_url + ">注册好雨云平台</a>"
        content = content + "<br/>"
        content = content + u"我们的服务在一定的资源范围内永久免费!内测阶段也可以申请增加免费资源,增加的资源在产品正式版上线后也不会另收费用哦!另外参与内测并提交问题报告的用户,正式上线后还会有更多的福利。"
        content = content + "<br/>"
        content = content + u"我们的文档及博客正在建设中,以后会陆续发布一系列好雨云平台的使用教程和技巧,欢迎关注!"
        content = content + "<br/>"
        content = content + u"您在使用过程中遇到的任何问题,或者对平台有任何建议,都可以通过以下途径提交反馈。对于提出高质量的反馈的用户,还有精美礼品等待您!"
        content = content + "<br/>"
        content = content + "Email: [email protected]"
        content = content + "<br/>"
        content = content + u"微信公众号:goodrain-cloud "
        content = content + "<br/>"
        content = content + u"联系电话:13621236261"
        content = content + "<br/>"
        content = content + u"QQ:78542636"
        content = content + "<br/>"
        content = content + u"再次感谢您关注我们的产品!"
        content = content + "<br/>"
        content = content + u"好雨科技 (Goodrain Inc.) CEO 刘凡"
        return content
Exemplo n.º 6
0
 def post(self, request, *args, **kwargs):
     """
     发送忘记密码邮件
     ---
     parameters:
         - name: email
           description: 邮箱
           required: true
           type: string
           paramType: form
     """
     email = request.POST.get("email", None)
     code = 200
     try:
         if email:
             if len(email) > 5:
                 rerule = "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$"
                 if re.match(rerule, email):
                     if Users.objects.filter(email=email).exists():
                         # TODO 生成 url 并发送一封邮件
                         domain = self.request.META.get('HTTP_HOST')
                         timestamp = str(int(time.time()))
                         tag = AuthCode.encode(','.join([email, timestamp]),
                                               'password')
                         link_url = 'http://%s/console/users/begin_password_reset?tag=%s' % (
                             domain, tag)
                         content = "请点击下面的链接重置您的密码,%s" % link_url
                         try:
                             send_reset_pass_mail(email, content)
                         except Exception as e:
                             logger.error(
                                 "account.passwdreset",
                                 "send email to {0} failed".format(email))
                             logger.exception("account.passwdreset", e)
                         result = general_message(code, "success", "邮件发送成功")
                     else:
                         code = 400
                         result = general_message(code, "failed!",
                                                  "当前用户没有注册!")
                     return Response(result, status=code)
                 else:
                     code = 400
                     result = general_message(code, "failed", "邮箱不合法!")
                     return Response(result, status=code)
         else:
             code = 400
             result = general_message(code, "failed", "邮件发送失败")
             return Response(result, status=code)
     except Exception as e:
         logger.exception(e)
         result = error_message(e.message)
         return Response(result, status=500)
Exemplo n.º 7
0
    def import_group_backup(self, tenant, region, group_id, upload_file):
        group = group_repo.get_group_by_id(group_id)
        if not group:
            return 404, "需要导入的组不存在", None
        services = group_service.get_group_services(group_id)
        if services:
            return 409, "请确保需要导入的组中不存在组件", None
        content = upload_file.read().strip()
        data = json.loads(AuthCode.decode(content, KEY))
        current_backup = backup_record_repo.get_record_by_group_id_and_backup_id(
            group_id, data["backup_id"])
        if current_backup:
            return 412, "当前团队已导入过该备份", None
        event_id = make_uuid()
        group_uuid = make_uuid()
        params = {
            "event_id": event_id,
            "group_id": group_uuid,
            "status": data["status"],
            "version": data["version"],
            "source_dir": data["source_dir"],
            "source_type": data["source_type"],
            "backup_mode": data["mode"],
            "backup_size": data["backup_size"]
        }
        body = region_api.copy_backup_data(region, tenant.tenant_name, params)

        bean = body["bean"]
        record_data = {
            "group_id": group.ID,
            "event_id": event_id,
            "group_uuid": group_uuid,
            "version": data["version"],
            "team_id": tenant.tenant_id,
            "region": region,
            "status": bean["status"],
            "note": data["note"],
            "mode": data["mode"],
            "backup_id": bean["backup_id"],
            "source_dir": data["source_dir"],
            "source_type": data["source_type"],
            "backup_size": data["backup_size"],
            "user": data["user"],
            "total_memory": data["total_memory"],
            "backup_server_info": data["backup_server_info"]
        }

        new_backup_record = backup_record_repo.create_backup_records(
            **record_data)
        return 200, "success", new_backup_record
Exemplo n.º 8
0
 def post(self, request, *args, **kwargs):
     """
     忘记密码
     ---
     parameters:
         - name: password
           description: 新密码
           required: true
           type: string
           paramType: form
         - name: password_repeat
           description: 确认密码
           required: true
           type: string
           paramType: form
     """
     try:
         tag = str(request.GET.get('tag'))
         email, old_timestamp = AuthCode.decode(tag, 'password').split(',')
         timestamp = int(time.time())
         if (timestamp - int(old_timestamp)) > 3600:
             logger.info(
                 "account.passwdreset",
                 "link expired, email: {0}, link_timestamp: {1}".format(
                     email, old_timestamp))
             result = general_message(400, "failed", "链接已失效")
             return Response(result, status=400)
         user = Users.objects.get(email=email)
         form = PasswordResetForm(request.POST)
         if form.is_valid():
             raw_password = request.POST.get('password')
             user.set_password(raw_password)
             user.save()
             result = general_message(200, "success", "修改密码成功")
             return Response(result, status=200)
         else:
             error = {
                 "error":
                 list(json.loads(form.errors.as_json()).values())[0][0].get(
                     "message", "参数错误")
             }
             result = general_message(400, "failed",
                                      "参数错误,{}".format(error["error"]))
             return Response(result, status=400)
     except Exception as e:
         logger.exception(e)
         result = error_message(e.message)
         return Response(result, status=500)
Exemplo n.º 9
0
    def get(self, request, *args, **kwargs):
        """正常注册用户绑定微信"""
        # 获取cookie中的corf
        csrftoken = request.COOKIES.get('csrftoken')
        if csrftoken is None:
            csrftoken = "csrf"
        user_id = str(self.user.pk)
        next_url = request.GET.get('next', "/")

        # 获取user对应的微信配置
        config = WECHAT_GOODRAIN
        oauth2 = 'https://open.weixin.qq.com/connect/oauth2/authorize'
        scope = 'snsapi_userinfo'
        redirect_url = settings.WECHAT_CALLBACK.get("console_bind_goodrain")
        if not is_weixin(request):
            config = WECHAT_USER
            oauth2 = 'https://open.weixin.qq.com/connect/qrconnect'
            scope = 'snsapi_login'
            redirect_url = settings.WECHAT_CALLBACK.get("console_bind")
        state = AuthCode.encode(
            ','.join([csrftoken, user_id, next_url, config]), 'wechat')
        logger.debug("bind wechat, state:{0}".format(state))
        wechat_config = WeChatConfig.objects.get(config=config)
        app_id = wechat_config.app_id
        # 微信的回跳页面

        redirect_url = urllib.urlencode({"1": redirect_url})[2:]
        # 微信登录扫码路径
        url = "{0}?appid={1}" \
              "&redirect_uri={2}" \
              "&response_type=code" \
              "&scope={3}" \
              "&state={4}#wechat_redirect".format(oauth2,
                                                  app_id,
                                                  redirect_url,
                                                  scope,
                                                  state)
        return self.redirect_to(url)
Exemplo n.º 10
0
    def post(self, request, *args, **kwargs):
        try:
            # 获取sso的user_id
            sso_user_id = request.data.get('uid')
            sso_user_token = request.data.get('token')
            sso_enterprise_id = request.data.get('eid')
            rf = request.data.get('rf') or 'sso'
            market_client_id = request.data.get('eid')
            market_client_token = request.data.get('etoken')
            if not market_client_id or not market_client_token:
                msg = "no market_client_id or market_client_token"
                logger.debug('account.login', msg)
                return Response({'success': False, 'msg': msg})
            rf_username = request.data.get('rf_username') or ''
            logger.debug(
                'account.login',
                'request.sso_user_id:{0}  request.sso_user_token:{1}  request.sso_enterprise_id:{2}'
                .format(sso_user_id, sso_user_token, sso_enterprise_id))
            is_pass, msg = self.__check_params(sso_user_id, sso_user_token,
                                               sso_enterprise_id)
            if not is_pass:
                return Response({'success': False, 'msg': msg})
            is_pass, msg, sso_user = self.__get_auth_user_token(
                sso_user_id, sso_user_token)
            if not is_pass:
                return Response({'success': False, 'msg': msg})

            enterprise = enterprise_services.get_enterprise_by_enterprise_id(
                sso_user.get('eid'))
            if not enterprise:
                sso_company = sso_user.get('company')
                enterprise = enterprise_services.create_tenant_enterprise(
                    sso_user.get('eid'), sso_company, sso_company, True)
            user = self.__update_user_info(sso_user, sso_user_id,
                                           sso_user_token, rf)
            # 保存访问云市的token
            domain = os.getenv('GOODRAIN_APP_API',
                               settings.APP_SERVICE_API["url"])
            client_auth_service.save_market_access_token(
                enterprise.enterprise_id, domain, market_client_id,
                market_client_token)

            key = request.data.get('key')
            logger.debug('invite key: {0}'.format(key))
            if key:
                logger.debug('account.login',
                             'invite register: {}'.format(key))
                data = AuthCode.decode(str(key), 'goodrain').split(',')
                logger.debug(data)
                action = data[0]
                if action == 'invite_tenant':
                    self.__process_invite_tenant(user, data)
                elif action == 'invite_service':
                    self.__process_invite_service(user, data)
                user.is_active = True
                user.save()
                logger.debug('account.login',
                             'user invite register successful')
            else:
                logger.debug(
                    'account.login',
                    'register/login user.is_active:{}'.format(user.is_active))
                if not user.is_active:
                    # 如果注册用户是通过云市私有交付创建的企业客户, 则将厂商账户加入到其客户企业的管理员列表
                    agent_sso_user_id = request.data.get('agent_sid')
                    logger.debug('account.login',
                                 'agent_sid: {}'.format(agent_sso_user_id))
                    if agent_sso_user_id:
                        code, msg, team = self.__init_and_create_user_tenant(
                            user, enterprise)
                        if code != 200:
                            return Response({
                                'success': False,
                                'msg': msg
                            },
                                            status=500)

                        agent_user = user_services.get_user_by_sso_user_id(
                            agent_sso_user_id)
                        if agent_user:
                            # 创建用户在团队的权限
                            perm_info = {
                                "user_id": agent_user.user_id,
                                "tenant_id": team.ID,
                                "identity": "admin",
                                "enterprise_id": enterprise.pk
                            }
                            perm_services.add_user_tenant_perm(perm_info)
                            logger.debug(
                                'account.login',
                                'agent manage team success: {}'.format(
                                    perm_info))
                    else:
                        user_services.make_user_as_admin_for_enterprise(
                            user.user_id, enterprise.enterprise_id)
                user.is_active = True
                user.save()

            logger.debug('account.login',
                         "enterprise id {0}".format(enterprise.enterprise_id))
            teams = team_services.get_enterprise_teams(
                enterprise.enterprise_id)
            data_list = [{
                'uid': user.sso_user_id,
                'tenant_id': t.tenant_id,
                'tenant_name': t.tenant_name,
                'tenant_alias': t.tenant_alias,
                'eid': t.enterprise_id
            } for t in teams]
            return Response({'success': True, 'list': data_list}, status=200)

        except Exception as e:
            logger.exception(e)
            return Response({'success': False, 'msg': e.message}, status=500)
Exemplo n.º 11
0
    def post(self, request, *args, **kwargs):
        """
        SSO通知,用户信息同步回来
        """
        # 获取sso的user_id
        sso_user_id = request.POST.get('uid')
        sso_user_token = request.POST.get('token')
        sso_enterprise_id = request.POST.get('eid')

        logger.debug('request.sso_user_id:{}'.format(sso_user_id))
        logger.debug('request.sso_user_token:{}'.format(sso_user_token))
        logger.debug('request.sso_enterprise_id:{}'.format(sso_enterprise_id))

        if not sso_user_id or not sso_user_token or not sso_enterprise_id:
            logger.error('post params [uid] or [token] or [eid] not specified!')
            return JsonResponse({'success': False, 'msg': 'post params [uid] or [token] or [eid] not specified!'})

        if sso_user_id == 'null' or sso_user_token == 'null':
            logger.error('bad uid or token, value is null!')
            return JsonResponse({"success": False, 'msg': 'bad uid or token, value is null!'})

        api = GoodRainSSOApi(sso_user_id, sso_user_token)
        if not api.auth_sso_user_token():
            logger.error('Illegal user token!')
            return JsonResponse({"success": False, 'msg': 'auth from sso failed!'})

        sso_user = api.get_sso_user_info()
        logger.debug(sso_user)
        # 同步sso_id所代表的用户与企业信息,没有则创建
        sso_eid = sso_user.get('eid')
        sso_company = sso_user.get('company')
        sso_username = sso_user.get('name')
        sso_phone = sso_user.get('mobile')
        sso_pwd = sso_user.get('pwd')
        try:
            enterprise = TenantEnterprise.objects.get(enterprise_id=sso_eid)
            logger.debug('query enterprise does existed, updated!')
        except TenantEnterprise.DoesNotExist:
            logger.debug('query enterprise does not existed, created!')
            enterprise = TenantEnterprise()
            enterprise.enterprise_id = sso_eid
            enterprise.enterprise_name = sso_company
            enterprise.enterprise_alias = sso_company
            enterprise.is_active = 1
            enterprise.save()
            logger.info(
                'create enterprise[{0}] with name {1}'.format(enterprise.enterprise_id,
                                                              enterprise.enterprise_name))

        try:
            user = Users.objects.get(sso_user_id=sso_user_id)
            user.sso_user_token = sso_user_token
            user.password = sso_pwd or ''
            user.phone = sso_phone or ''
            user.nick_name = sso_username
            user.enterprise_id = sso_eid
            user.save()

            logger.debug('query user with sso_user_id existed, updated!')
        except Users.DoesNotExist:
            logger.debug('query user with sso_user_id does not existed, created!')
            user = Users.objects.create(nick_name=sso_username,
                                        email=sso_user.get('email') or '',
                                        phone=sso_phone or '',
                                        password=sso_pwd or '',
                                        sso_user_id=sso_user.get('uid'),
                                        enterprise_id=sso_eid,
                                        sso_user_token=sso_user_token,
                                        is_active=False,
                                        rf='sso')
            logger.info(
                'create user[{0}] with name [{1}] from [{2}] use sso_id [{3}]'.format(user.user_id, user.nick_name,
                                                                                      user.rf,
                                                                                      user.sso_user_id))
            monitor_hook.registerMonitor(user, 'register')

        logger.debug('user.is_active:{}'.format(user.is_active))
        if not user.is_active:
            tenant = enterprise_svc.create_and_init_team(user.user_id, enterprise_id=user.enterprise_id)
        else:
            tenant = user_svc.get_default_tenant_by_user(user.user_id)
        logger.info(tenant.to_dict())

        key = request.POST.get('key')
        logger.debug('invite key: {}'.format(key))
        if key:
            data = AuthCode.decode(str(key), 'goodrain').split(',')
            logger.debug(data)
            action = data[0]
            if action == 'invite_tenant':
                email, tenant_name, identity = data[1], data[2], data[3]
                tenant = Tenants.objects.get(tenant_name=tenant_name)
                if PermRelTenant.objects.filter(user_id=user.user_id, tenant_id=tenant.pk).count() == 0:
                    invite_enter = TenantEnterprise.objects.get(enterprise_id=tenant.enterprise_id)
                    PermRelTenant.objects.create(user_id=user.user_id, tenant_id=tenant.pk, identity=identity,
                                                 enterprise_id=invite_enter.pk)

            elif action == 'invite_service':
                email, tenant_name, service_alias, identity = data[1], data[2], data[3], data[4]
                tenant_service = TenantServiceInfo.objects.get(service_alias=service_alias)
                if PermRelService.objects.filter(user_id=user.user_id, service_id=tenant_service.pk).count() == 0:
                    PermRelService.objects.create(user_id=user.user_id, service_id=tenant_service.pk, identity=identity)

            logger.debug('user invite sucess')
        return JsonResponse({"success": True})
Exemplo n.º 12
0
    def get(self, request, *args, **kwargs):
        """正常注册用户绑定微信返回路径"""
        # 获取cookie中的csrf
        csrftoken = request.COOKIES.get('csrftoken')
        if csrftoken is None:
            csrftoken = "csrf"
        # 获取statue
        state = request.GET.get("state")
        # 解码
        oldcsrftoken, user_id, next_url, config = AuthCode.decode(
            str(state), 'wechat').split(',')
        # 判断是否微信浏览器
        if csrftoken != oldcsrftoken:
            logger.error("csrftoken check error!")
            return self.redirect_to(next_url)
        # 获取的code
        code = request.GET.get("code")
        if code is None:
            logger.error("wechat donot return code! you do not permissioned!")
            return self.redirect_to(next_url)
        # 根据code获取access_token
        wechat_config = WeChatConfig.objects.get(config=config)
        access_token, open_id = OpenWeChatAPI.access_token_oauth2_static(
            wechat_config.app_id, wechat_config.app_secret, code)
        if access_token is None:
            # 登录失败,重新跳转到授权页面
            logger.error("wechat oauth access token error!")
            return self.redirect_to(next_url)
        # 检查用户的open_id是否已经存在
        need_new = False
        wechat_user = None
        try:
            wechat_user = WeChatUser.objects.get(open_id=open_id)
        except WeChatUser.DoesNotExist:
            logger.warning("open_id is first to access console. now regist...")
            need_new = True
        # 添加wechatuser
        if need_new:
            jsondata = OpenWeChatAPI.query_userinfo_static(
                open_id, access_token)
            nick_name = jsondata.get("nickname")
            if nick_name:
                nick_name = nick_name.encode("utf-8")
            WeChatUser(open_id=jsondata.get("openid"),
                       nick_name=nick_name,
                       union_id=jsondata.get("unionid"),
                       sex=jsondata.get("sex"),
                       city=jsondata.get("city"),
                       province=jsondata.get("province"),
                       country=jsondata.get("country"),
                       headimgurl=jsondata.get("headimgurl"),
                       config=config).save()
        # 判断union_id是否已经绑定user

        # 根据微信的union_id判断用户是否已经注册
        try:
            old_user = Users.objects.get(union_id=wechat_user.union_id)
            num = WeChatUnBind.objects.filter(union_id=wechat_user.union_id,
                                              user_id=old_user.pk).count()
            if num == 0:
                count = WeChatUnBind.objects.filter(
                    union_id=wechat_user.union_id).count()
                WeChatUnBind.objects.create(user_id=old_user.pk,
                                            union_id=wechat_user.union_id,
                                            status=count)
            old_user.union_id = ""
            old_user.save()
        except Exception as e:
            logger.exception(e)

        user = Users.objects.get(pk=user_id)
        if user.status == 0:
            user.status = 1
        elif user.status == 4:
            user.status = 3
        user.union_id = wechat_user.union_id
        user.save()

        return self.redirect_to(next_url)
Exemplo n.º 13
0
    def get(self, request, *args, **kwargs):
        import datetime
        # 获取cookie中的csrf
        csrftoken = request.COOKIES.get('csrftoken')
        if csrftoken is None:
            csrftoken = "csrf"
        # 获取statue
        state = request.GET.get("state")
        # 解码toke, type
        logger.debug("account.wechat", state)
        logger.debug("account.wechat",
                     "is_weixin:{0}".format(str(is_weixin(request))))
        # 查询数据库
        err_url = settings.WECHAT_CALLBACK.get("index")
        try:
            wechat_state = WeChatState.objects.get(pk=state)
        except Exception as e:
            logger.exception("account.wechat", e)
            logger.error("account.wechat",
                         "wechatstate is missing,id={0}".format(state))
            return self.redirect_to(err_url)
        cry_state = wechat_state.state

        state_array = AuthCode.decode(str(cry_state),
                                      'we_chat_login').split(',')
        oldcsrftoken = state_array[0]
        origin = state_array[1]
        next_url = state_array[2]
        config = state_array[3]
        origin_url = None
        if len(state_array) == 5:
            origin_url = state_array[4]
        logger.debug("account.wechat", oldcsrftoken)
        logger.debug("account.wechat", origin)
        logger.debug("account.wechat", next_url)
        logger.debug("account.wechat", config)
        logger.debug("account.wechat", origin_url)

        if csrftoken != oldcsrftoken:
            return self.redirect_to(err_url)
        # 获取的code
        code = request.GET.get("code")
        logger.info(code)
        if code is None:
            return self.redirect_to(err_url)
        # 根据code获取access_token
        wechat_config = WeChatConfig.objects.get(config=config)
        access_token, open_id = OpenWeChatAPI.access_token_oauth2_static(
            wechat_config.app_id, wechat_config.app_secret, code)
        logger.info(access_token)
        if access_token is None:
            # 登录失败,跳转到失败页面
            return self.redirect_to(err_url)
        # 检查用户的open_id是否已经存在
        need_new = False
        wechat_user = None
        try:
            wechat_user = WeChatUser.objects.get(open_id=open_id)
        except WeChatUser.DoesNotExist:
            logger.warning(
                "account.wechat",
                "open_id is first to access console. now regist...")
            need_new = True

        # 添加wechatuser
        if need_new:
            jsondata = OpenWeChatAPI.query_userinfo_static(
                open_id, access_token)
            nick_name = jsondata.get("nickname")
            if nick_name:
                nick_name = nick_name.encode("utf-8")
            wechat_user = WeChatUser(open_id=jsondata.get("openid"),
                                     nick_name=nick_name,
                                     union_id=jsondata.get("unionid"),
                                     sex=jsondata.get("sex"),
                                     city=jsondata.get("city"),
                                     province=jsondata.get("province"),
                                     country=jsondata.get("country"),
                                     headimgurl=jsondata.get("headimgurl"),
                                     config=config)
            wechat_user.save()

        # 根据微信的union_id判断用户是否已经注册
        need_new = False
        user = None
        try:
            user = Users.objects.get(union_id=wechat_user.union_id)
        except Users.DoesNotExist:
            logger.warning(
                "account.wechat",
                "union id is first to access console. now create user...")
            need_new = True
        # 用户表中不存在对应用户,判断是否已经解绑
        if need_new:
            try:
                binding = WeChatUnBind.objects.get(
                    union_id=wechat_user.union_id, status=0)
                user = Users.objects.get(pk=binding.user_id)
                user.union_id = wechat_user.union_id
                user.save()
                need_new = False
            except WeChatUnBind.DoesNotExist:
                pass

        # 创建租户
        if need_new:
            union_id = wechat_user.union_id
            tmp_union_id = md5fun(union_id)
            begin_index = len(tmp_union_id) - 8
            tenant_name = tmp_union_id[begin_index:]
            tenant_name = tenant_name.replace("_", "-").lower()
            email = tenant_name + "@wechat.com"
            logger.debug(
                "account.wechat",
                "new wx regist user.email:{0} tenant_name:{1}".format(
                    email, tenant_name))
            # 创建用户,邮箱为openid后8位@wechat.comemail=email,
            # 统计当前wx数量
            count = Users.objects.filter(rf="open_wx").count()
            count += 1989
            nick_name = "wxgd0" + str(count)
            user = Users(nick_name=nick_name,
                         phone="",
                         client_ip=get_client_ip(request),
                         rf="open_wx",
                         status=2,
                         union_id=union_id)
            user.set_password("wechatpwd")
            user.save()
            monitorhook.registerMonitor(user, 'register')
            # 创建租户,默认为alish
            region = RegionInfo.register_choices()[0][0]

            # add by tanm
            regions = [region]
            enterprise_svc.create_and_init_tenant(user.user_id, tenant_name,
                                                  regions, user.enterprise_id)

            # create gitlab user
            if user.email is not None and user.email != "":
                codeRepositoriesService.createUser(user, email, password,
                                                   nick_name, nick_name)
        logger.info(user)
        if user is None:
            logger.error("account.wechat", "微信用户登录失败!")
            return self.redirect_to(err_url)
        # 微信用户登录
        user = authenticate(union_id=user.union_id)
        login(request, user)
        self.user = request.user

        # 回跳到云市
        if next_url is not None \
                and next_url != "" \
                and next_url != "none" \
                and next_url != "None":
            if origin == "app":
                logger.debug("account.wechat",
                             "now return to cloud market login..")
                if origin_url is None or origin_url == "redirect_url" or origin_url == "":
                    origin_url = settings.APP_SERVICE_API.get("url")
                if not origin_url.startswith("http://"):
                    origin_url = "http://" + origin_url
                # 返回参数
                payload = {
                    "nick_name": user.nick_name,
                    "user_id": str(user.user_id),
                    "next_url": next_url,
                    "action": "register" if need_new else "login"
                }
                if wechat_user is not None:
                    payload["wechat_name"] = wechat_user.nick_name
                ticket = AuthCode.encode(json.dumps(payload), "goodrain")
                next_url = "{0}/login/{1}/success?ticket={2}".format(
                    origin_url, sn.instance.cloud_assistant, ticket)
                # next_url = settings.APP_SERVICE_API.get("url") + '/login/goodrain/success?ticket=' + ticket
                logger.debug("account.wechat", next_url)
            return redirect(next_url)

        return self.redirect_view()