Exemple #1
0
def handle_member_join(request, event, destination):
    cdata = ChannelManager.get_channel_token(
        Platform.LINE, LineApiUtils.get_channel_id(event), auto_register=True)
    joined_names = []

    for user in event.joined.members:
        uid = user.user_id

        udata_result = RootUserManager.get_root_data_onplat(Platform.LINE, uid)

        if udata_result.success and cdata:
            ProfileManager.register_new_default_async(cdata.id,
                                                      udata_result.model.id)

            uname = RootUserManager.get_root_data_uname(
                udata_result.model.get_oid(), cdata).user_name
            if uname:
                joined_names.append(uname)

    LINE.temp_apply_format(event_dest_fmt,
                           logging.INFO,
                           "LINE Join Group.",
                           extra={
                               ExtraKey.Event: event,
                               ExtraKey.Destination: destination
                           })

    LineApiWrapper.reply_text(
        event.reply_token,
        _("{} joined the group.").format(" & ".join(joined_names)))
Exemple #2
0
    def process_request(self, request):
        qd = None

        if request.method == "GET":
            qd = request.GET
        elif request.method == "POST":
            qd = request.POST

        if qd is not None:
            user_token = qd.get(param.Common.USER_TOKEN)
            platform = qd.get(param.Common.PLATFORM)

            if user_token is not None and platform is not None:
                rt_result = RootUserManager.get_root_data_onplat(
                    platform, user_token)
                if rt_result.success:
                    request.session[Session.USER_ROOT_ID] = str(
                        rt_result.model.id)
                    return

            api_token = request.COOKIES.get(Cookies.USER_TOKEN) or qd.get(
                param.Common.API_TOKEN)

            if api_token is not None:
                rt_result = RootUserManager.get_root_data_api_token(api_token)
                if rt_result.success:
                    request.session[Session.USER_ROOT_ID] = str(
                        rt_result.model.id)
                    return
                else:
                    if Cookies.USER_TOKEN in request.COOKIES:
                        del request.COOKIES[Cookies.USER_TOKEN]
Exemple #3
0
    def process_request(self, request):
        root_oid = get_root_oid(request)

        if root_oid is None:
            timezone.activate(default_locale.to_tzinfo())
        else:
            timezone.activate(RootUserManager.get_tzinfo_root_oid(root_oid))
Exemple #4
0
    def setUpTestData(cls) -> None:
        from mongodb.factory import RootUserManager
        from extutils.gidentity import GoogleIdentityUserData

        MONGO_CLIENT.get_database("execode").get_collection(
            "main").delete_many({})
        MONGO_CLIENT.get_database("channel").get_collection(
            "dict").delete_many({})
        MONGO_CLIENT.get_database("channel").get_collection(
            "user").delete_many({})
        MONGO_CLIENT.get_database("channel").get_collection(
            "perm").delete_many({})
        MONGO_CLIENT.get_database("user").get_collection("api").delete_many({})
        MONGO_CLIENT.get_database("user").get_collection("root").delete_many(
            {})

        # Register Fake API Data
        reg = RootUserManager.register_google(
            GoogleIdentityUserData("Fake",
                                   "Fake",
                                   "Fake",
                                   "*****@*****.**",
                                   skip_check=True))
        if reg.success:
            cls.TEST_API_TOKEN = reg.idt_reg_result.model.token
        else:
            raise ValueError("Fake data registration failed.")

        ChannelManager.register(1, "channel1")
Exemple #5
0
    def integrate(old_oid: ObjectId, new_oid: ObjectId) -> bool:
        """
        :return: Integration succeed or not.
        """
        # In function import to prevent circular import
        from mongodb.factory import BaseCollection, get_collection_subclasses, MONGO_CLIENT, RootUserManager

        # Replace UID entries
        failed_names: List[str] = []

        cls: BaseCollection
        for cls in get_collection_subclasses():
            if cls.model_class:
                col = MONGO_CLIENT.get_database(
                    cls.database_name).get_collection(cls.collection_name)
                failed_names.extend(
                    cls.model_class.replace_uid(col, old_oid, new_oid))

        if failed_names:
            MailSender.send_email_async(
                f"Fields value replacements failed.<hr><pre>{'<br>'.join(failed_names)}</pre>",
                subject="User Data Integration Failed.")
            return False
        else:
            return RootUserManager.merge_onplat_to_api(old_oid,
                                                       new_oid).is_success
Exemple #6
0
    async def on_member_remove(self, member: Member):
        udata_result = RootUserManager.get_root_data_onplat(Platform.DISCORD, member.id, auto_register=True)
        cdata = ChannelManager.get_channel_token(Platform.DISCORD, member.guild.id, auto_register=True)

        if udata_result.success and cdata:
            ProfileManager.mark_unavailable_async(cdata.id, udata_result.model.id)

        sys_channel = member.guild.system_channel
        if sys_channel:
            await sys_channel.send(_("{} left the server.").format(member.mention))
Exemple #7
0
    def get(self, request, *args, **kwargs):
        config = RootUserManager.get_config_root_oid(get_root_oid(request))

        return render_template(
            self.request, _("Account Settings"), "account/settings.html", {
                "locale_list": sorted(locales,
                                      key=lambda item: item.description),
                "lang_list": sorted(languages, key=lambda item: item.code),
                "current_config": config
            })
Exemple #8
0
    def process_request(self, request):
        root_oid = get_root_oid(request)

        if root_oid:
            l_code = RootUserManager.get_lang_code_root_oid(root_oid)

            if l_code:
                activate(l_code)
                return

        deactivate()
Exemple #9
0
def get_root_oid(request) -> Optional[ObjectId]:
    oid_str = request.session.get(Session.USER_ROOT_ID)
    if oid_str:
        return ObjectId(oid_str)

    u_token = request.GET.get(Common.USER_TOKEN)
    if u_token:
        platform = Platform.cast(request.GET.get(Common.PLATFORM)) or Platform.UNKNOWN
        result = RootUserManager.get_root_data_onplat(platform, u_token, auto_register=False)

        if result.success:
            return result.model.id

    api_token = request.GET.get(Common.API_TOKEN)
    if api_token:
        result = RootUserManager.get_root_data_api_token(api_token)

        if result.success:
            return result.model.id

    return None
Exemple #10
0
    def post(self, request, *args, **kwargs):
        s = str(_("An unknown error occurred."))
        s_contact = " " + str(_("Contact the administrator of the website."))
        token = None

        try:
            result = RootUserManager.register_google(
                get_identity_data(request.POST.get("idtoken")))
            if result.outcome.is_success:
                s = AccountLoginView.PASS_SIGNAL
                token = result.idt_reg_result.token
            elif result.outcome == WriteOutcome.X_NOT_EXECUTED:
                s = _("Registration process not performed.")
            elif result.outcome == WriteOutcome.X_NOT_ACKNOWLEDGED:
                s = _("New user data creation failed.")
            elif result.outcome == WriteOutcome.X_NOT_SERIALIZABLE:
                s = _("The data cannot be passed into the server.")
            else:
                s = _(
                    "An unknown error occurred during the new user data registration. "
                    "Code: {} / Registration Code: {}.").format(
                        result.outcome.code,
                        result.idt_reg_result.outcome.code)

            if not result.outcome.is_success:
                MailSender.send_email_async(
                    f"Result: {result.serialize()}<br>"
                    f"Outcome: {result.outcome}<br>"
                    f"Exception: {result.exception}<br>"
                    f"Registration: {result.idt_reg_result.outcome}<br>"
                    f"Registration Exception: {result.idt_reg_result.exception}<br>",
                    subject="New user data registration failed")
        except IDIssuerIncorrect as ex1:
            s = str(ex1)
        except Exception as ex2:
            # EXNOTE: Insert `raise ex2` when any error occurred during login
            # raise ex2
            s += f" ({ex2})"

        if s != AccountLoginView.PASS_SIGNAL:
            s += s_contact

        response = simple_json_response(s)

        if token is not None:
            response.set_cookie(keys.Cookies.USER_TOKEN, token)

        if s == AccountLoginView.PASS_SIGNAL and token is None:
            return simple_json_response(
                _("User token is null however login succeed. {}").format(
                    s_contact))
        else:
            return response
Exemple #11
0
    def fn():
        marked_unavailable = 0

        dict_onplat_oids = RootUserManager.get_root_to_onplat_dict()
        dict_onplat_data = RootUserManager.get_onplat_data_dict()
        dict_channel = ChannelManager.get_channel_dict([p.channel_oid for p in list_prof_conn], accessbible_only=True)

        with ThreadPoolExecutor(max_workers=4, thread_name_prefix="ExstCheck") as executor:
            futures = [
                executor.submit(_check_on_prof_conn_, d, set_name_to_cache, dict_onplat_oids, dict_onplat_data,
                                dict_channel)
                for d in list_prof_conn
            ]

            # Non-lock call & Free resources when execution is done
            executor.shutdown(False)

            for completed in futures:
                ret = completed.result()
                if ret:
                    marked_unavailable += 1

        SYSTEM.logger.info(f"Marked {marked_unavailable} connections unavailable.")
Exemple #12
0
    def post(self, request, *args, **kwargs):
        update_result = RootUserManager.update_config(
            get_root_oid(request), **get_post_keys(request.POST))

        if update_result.success:
            return simple_str_response(
                request,
                f"success/{localtime(now_utc_aware()):%m-%d %H:%M:%S (%Z)} - "
                f"{_('Account settings updated.')}")
        else:
            return simple_str_response(
                request,
                f"danger/{localtime(now_utc_aware()):%m-%d %H:%M:%S (%Z)} - "
                f"{_('Account settings failed to update.')}")
Exemple #13
0
    def _ensure_user_idt_(platform: Platform, token: Union[int, str]) -> Optional[RootUserModel]:
        if token:
            result = RootUserManager.register_onplat(platform, token)
            if not result.success:
                MailSender.send_email_async(
                    f"Platform: {platform} / Token: {token}<hr>"
                    f"Outcome: {result.outcome}<hr>"
                    f"Conn Outcome: {result.conn_outcome}<hr>"
                    f"Identity Registration Result: {result.idt_reg_result.serialize()}",
                    subject="User Registration Failed")

            return result.model
        else:
            return None
Exemple #14
0
    def get(self, request, *args, **kwargs):
        u_data = RootUserManager.get_root_data_api_token(
            self.request.COOKIES[keys.Cookies.USER_TOKEN])
        excde_list = ExecodeManager.get_queued_execodes(u_data.model.id)

        return render_template(
            self.request, _("Account Home"), "account/main.html", {
                "root_data":
                u_data.model,
                "api_user_data":
                u_data.model_api,
                "execode_list":
                excde_list,
                "onplat_user_data_list":
                u_data.model_onplat_list,
                "reg_time_str":
                t_delta_str(now_utc_aware() - u_data.model.id.generation_time)
            })
Exemple #15
0
def handle_member_left(request, event, destination):
    for user in event.left.members:
        uid = user.user_id

        udata_result = RootUserManager.get_root_data_onplat(Platform.LINE, uid)
        cdata = ChannelManager.get_channel_token(
            Platform.LINE,
            LineApiUtils.get_channel_id(event),
            auto_register=True)

        if udata_result.success and cdata:
            ProfileManager.mark_unavailable_async(cdata.id,
                                                  udata_result.model.id)

    LINE.temp_apply_format(event_dest_fmt,
                           logging.INFO,
                           "LINE Left Group.",
                           extra={
                               ExtraKey.Event: event,
                               ExtraKey.Destination: destination
                           })
Exemple #16
0
    def get_name(self, channel_data=None) -> Optional[str]:
        # Checking `get_oid()` because the model might be constructed in the code (no ID) and
        # call `get_name()` afterward without storing it to the database
        if self.get_oid() is not None and self.id not in _user_name_cache_:
            n = None

            if self.platform == Platform.LINE:
                from extline import LineApiWrapper
                from models import ChannelCollectionModel

                if isinstance(channel_data, ChannelCollectionModel):
                    raise ValueError(
                        "Finding the user name with `ChannelCollectionModel` "
                        "currently not yet supported. Check issue #38.")

                if channel_data:
                    n = LineApiWrapper.get_user_name_safe(
                        self.token, channel_data)
                else:
                    n = LineApiWrapper.get_user_name_safe(self.token)
            elif self.platform == Platform.DISCORD:
                from extdiscord import DiscordClientWrapper

                n = DiscordClientWrapper.get_user_name_safe(self.token)

            if n:
                set_uname_cache(self.id, n)
            else:
                # Mark unavailable
                from mongodb.factory import ProfileManager, RootUserManager

                root_data_result = RootUserManager.get_root_data_onplat(
                    self.platform, self.token, auto_register=False)
                if root_data_result.success:
                    ProfileManager.mark_unavailable_async(
                        channel_data.id, root_data_result.model.id)

        return _user_name_cache_.get(self.id)