示例#1
0
 def wrapper(cls, **kwargs):
     try:
         filename = kwargs['filename']
     except KeyError:
         filename = cls.filename
     res = func(cls, **kwargs)
     file_mode_checker(filename, mode=0o600)
     return res
示例#2
0
 def wrapper(cls, **kwargs):
     try:
         filename = kwargs['filename']
     except KeyError:
         filename = cls.filename
     res = func(cls, **kwargs)
     file_mode_checker(filename, mode=0o600)
     return res
示例#3
0
def save_botpasswords(botpasswords, _fncpass):
    """Write botpasswords to file."""
    if botpasswords:
        # Save user-password.py if necessary
        # user-config.py is already created at this point
        # therefore pywikibot.tools can be imported safely
        from pywikibot.tools import file_mode_checker
        try:
            # First create an empty file with good permissions, before writing
            # in it
            with codecs.open(_fncpass, 'w', 'utf-8') as f:
                f.write('')
                file_mode_checker(_fncpass, mode=0o600, quiet=True)
            with codecs.open(_fncpass, 'w', 'utf-8') as f:
                f.write(PASSFILE_CONFIG.format(botpasswords=botpasswords))
                file_mode_checker(_fncpass, mode=0o600)
                pywikibot.output("'{0}' written.".format(_fncpass))
        except EnvironmentError:
            os.remove(_fncpass)
            raise
示例#4
0
    def readPassword(self):
        """
        Read passwords from a file.

        DO NOT FORGET TO REMOVE READ ACCESS FOR OTHER USERS!!!
        Use chmod 600 password-file.

        All lines below should be valid Python tuples in the form
        (code, family, username, password),
        (family, username, password) or
        (username, password)
        to set a default password for an username. The last matching entry will
        be used, so default usernames should occur above specific usernames.

        For BotPasswords the password should be given as a BotPassword object.

        The file must be either encoded in ASCII or UTF-8.

        Example::

         ('my_username', 'my_default_password')
         ('my_sysop_user', 'my_sysop_password')
         ('wikipedia', 'my_wikipedia_user', 'my_wikipedia_pass')
         ('en', 'wikipedia', 'my_en_wikipedia_user', 'my_en_wikipedia_pass')
         ('my_username', BotPassword(
          'my_BotPassword_suffix', 'my_BotPassword_password'))
        """
        # Set path to password file relative to the user_config
        # but fall back on absolute path for backwards compatibility
        password_file = os.path.join(config.base_dir, config.password_file)
        if not os.path.isfile(password_file):
            password_file = config.password_file

        # We fix password file permission first.
        file_mode_checker(password_file, mode=config.private_files_permission)

        with codecs.open(password_file, encoding='utf-8') as f:
            lines = f.readlines()
        line_nr = len(lines) + 1
        for line in reversed(lines):
            line_nr -= 1
            if not line.strip() or line.startswith('#'):
                continue
            try:
                entry = eval(line)
            except SyntaxError:
                entry = None
            if type(entry) is not tuple:
                warn('Invalid tuple in line {0}'.format(line_nr),
                     _PasswordFileWarning)
                continue
            if not 2 <= len(entry) <= 4:
                warn(
                    'The length of tuple in line {0} should be 2 to 4 ({1} '
                    'given)'.format(line_nr, entry), _PasswordFileWarning)
                continue

            code, family, username, password = (
                self.site.code, self.site.family.name)[:4 - len(entry)] + entry
            if (normalize_username(username) == self.username
                    and family == self.site.family.name
                    and code == self.site.code):
                if isinstance(password, UnicodeType):
                    self.password = password
                    break
                elif isinstance(password, BotPassword):
                    self.password = password.password
                    self.login_name = password.login_name(self.username)
                    break
                else:
                    warn('Invalid password format', _PasswordFileWarning)
示例#5
0
 def test_auto_chmod_not_OK(self):
     """Chmod files that do not have mode private_files_permission."""
     self.stat.return_value.st_mode = 0o100644  # regular file
     tools.file_mode_checker(self.file, mode=0o600)
     self.stat.assert_called_with(self.file)
     self.chmod.assert_called_once_with(self.file, 0o600)
示例#6
0
 def test_auto_chmod_OK(self):
     """Do not chmod files that have mode private_files_permission."""
     self.stat.return_value.st_mode = 0o100600  # regular file
     tools.file_mode_checker(self.file, mode=0o600)
     self.stat.assert_called_with(self.file)
     self.assertFalse(self.chmod.called)
示例#7
0
文件: http.py 项目: luzpaz/pywikibot
        """Initialize the class."""
        super(PywikibotCookieJar, self).__init__(*args, **kwargs)

    @mode_check_decorator
    def load(self, **kwargs):
        """Load cookies from file."""
        super(PywikibotCookieJar, self).load()

    @mode_check_decorator
    def save(self, **kwargs):
        """Save cookies to file."""
        super(PywikibotCookieJar, self).save()


cookie_file_path = config.datafilepath('pywikibot.lwp')
file_mode_checker(cookie_file_path, create=True)
cookie_jar = cookielib.LWPCookieJar(cookie_file_path)
try:
    cookie_jar.load()
except cookielib.LoadError:
    debug('Loading cookies failed.', _logger)
else:
    debug('Loaded cookies from file.', _logger)

session = requests.Session()
session.cookies = cookie_jar


# Prepare flush on quit
def _flush():
    log('Closing network session.')
示例#8
0
        """Initialize the class."""
        super(PywikibotCookieJar, self).__init__(*args, **kwargs)

    @mode_check_decorator
    def load(self, **kwargs):
        """Load cookies from file."""
        super(PywikibotCookieJar, self).load()

    @mode_check_decorator
    def save(self, **kwargs):
        """Save cookies to file."""
        super(PywikibotCookieJar, self).save()


cookie_file_path = config.datafilepath('pywikibot.lwp')
file_mode_checker(cookie_file_path, create=True)
cookie_jar = cookielib.LWPCookieJar(cookie_file_path)
try:
    cookie_jar.load()
except cookielib.LoadError:
    debug('Loading cookies failed.', _logger)
else:
    debug('Loaded cookies from file.', _logger)

session = requests.Session()
session.cookies = cookie_jar


# Prepare flush on quit
def _flush():
    log('Closing network session.')
示例#9
0
def create_user_config(main_family, main_code, main_username, force=False):
    """
    Create a user-config.py in base_dir.

    Create a user-password.py if necessary.
    """
    _fnc = os.path.join(base_dir, USER_BASENAME)
    _fncpass = os.path.join(base_dir, PASS_BASENAME)

    useritem = namedtuple('useritem', 'family, code, name')
    userlist = []
    if force and not config.verbose_output:
        if main_username:
            userlist = [useritem(main_family, main_code, main_username)]
    else:
        while True:
            userlist += [
                useritem(*get_site_and_lang(
                    main_family, main_code, main_username, force=force))
            ]
            if not pywikibot.input_yn('Do you want to add any other projects?',
                                      force=force,
                                      default=False,
                                      automatic_quit=False):
                break

    # For each different username entered, ask if user wants to save a
    # BotPassword (username, BotPassword name, BotPassword pass)
    msg = fill('See {}/BotPasswords to know how to get codes.'
               'Please note that plain text in {} and anyone with read '
               'access to that directory will be able read the file.'.format(
                   __url__, _fncpass))
    botpasswords = []
    userset = {user.name for user in userlist}
    for username in userset:
        if pywikibot.input_yn(
                'Do you want to add a BotPassword for {}?'.format(username),
                force=force,
                default=False):
            if msg:
                pywikibot.output(msg)
            msg = None
            message = 'BotPassword\'s "bot name" for {}'.format(username)
            botpasswordname = pywikibot.input(message, force=force)
            message = 'BotPassword\'s "password" for "{}" ' \
                      '(no characters will be shown)' \
                      .format(botpasswordname)
            botpasswordpass = pywikibot.input(message,
                                              force=force,
                                              password=True)
            if botpasswordname and botpasswordpass:
                botpasswords.append(
                    (username, botpasswordname, botpasswordpass))

    if not userlist:  # Show a sample
        usernames = "# usernames['{}']['{}'] = u'MyUsername'".format(
            main_family, main_code)
    else:
        usernames = '\n'.join(
            "usernames['{user.family}']['{user.code}'] = u'{user.name}'".
            format(user=user) for user in userlist)
        # Arbitrarily use the first key as default settings
        main_family, main_code = userlist[0].family, userlist[0].code
    botpasswords = '\n'.join(
        "('{0}', BotPassword('{1}', '{2}'))".format(*botpassword)
        for botpassword in botpasswords)

    config_text = copy_sections()
    if config_text:
        config_content = EXTENDED_CONFIG
    else:
        pywikibot.output('Creating a small variant of user-config.py')
        config_content = SMALL_CONFIG

    try:
        # Finally save user-config.py
        with codecs.open(_fnc, 'w', 'utf-8') as f:
            f.write(
                config_content.format(main_family=main_family,
                                      main_code=main_code,
                                      usernames=usernames,
                                      config_text=config_text,
                                      botpasswords='password_file = ' +
                                      ('"{}"'.format(PASS_BASENAME)
                                       if botpasswords else 'None')))
        pywikibot.output("'%s' written." % _fnc)
    except BaseException:
        if os.path.exists(_fnc):
            os.remove(_fnc)
        raise

    if botpasswords:
        # Save user-password.py if necessary
        # user-config.py is already created at this point
        # therefore pywikibot.tools can be imported safely
        from pywikibot.tools import file_mode_checker
        try:
            # First create an empty file with good permissions, before writing
            # in it
            with codecs.open(_fncpass, 'w', 'utf-8') as f:
                f.write('')
                file_mode_checker(_fncpass, mode=0o600, quiet=True)
            with codecs.open(_fncpass, 'w', 'utf-8') as f:
                f.write(PASSFILE_CONFIG.format(botpasswords=botpasswords))
                file_mode_checker(_fncpass, mode=0o600)
                pywikibot.output("'{0}' written.".format(_fncpass))
        except EnvironmentError:
            os.remove(_fncpass)
            raise
 def test_auto_chmod_not_OK(self):
     """Chmod files that do not have mode private_files_permission."""
     self.stat.return_value.st_mode = 0o100644  # regular file
     tools.file_mode_checker(self.file, mode=0o600)
     self.stat.assert_called_with(self.file)
     self.chmod.assert_called_once_with(self.file, 0o600)
 def test_auto_chmod_OK(self):
     """Do not chmod files that have mode private_files_permission."""
     self.stat.return_value.st_mode = 0o100600  # regular file
     tools.file_mode_checker(self.file, mode=0o600)
     self.stat.assert_called_with(self.file)
     self.assertFalse(self.chmod.called)
示例#12
0
def create_user_config(main_family, main_code, main_username, force=False):
    """
    Create a user-config.py in base_dir.

    Create a user-password.py if necessary.
    """
    _fnc = os.path.join(base_dir, USER_BASENAME)
    _fncpass = os.path.join(base_dir, PASS_BASENAME)

    useritem = namedtuple('useritem', 'family, code, name')
    userlist = []
    if force and not config.verbose_output:
        if main_username:
            userlist = [useritem(main_family, main_code, main_username)]
    else:
        while True:
            userlist += [useritem(*get_site_and_lang(
                main_family, main_code, main_username, force=force))]
            if not pywikibot.input_yn('Do you want to add any other projects?',
                                      force=force,
                                      default=False, automatic_quit=False):
                break

    # For each different username entered, ask if user wants to save a
    # BotPassword (username, BotPassword name, BotPassword pass)
    msg = fill('See {}/BotPasswords to know how to get codes.'
               'Please note that plain text in {} and anyone with read '
               'access to that directory will be able read the file.'
               .format(__url__, _fncpass))
    botpasswords = []
    userset = {user.name for user in userlist}
    for username in userset:
        if pywikibot.input_yn('Do you want to add a BotPassword for {}?'
                              .format(username), force=force, default=False):
            if msg:
                pywikibot.output(msg)
            msg = None
            message = 'BotPassword\'s "bot name" for {}'.format(username)
            botpasswordname = pywikibot.input(message, force=force)
            message = 'BotPassword\'s "password" for "{}" ' \
                      '(no characters will be shown)' \
                      .format(botpasswordname)
            botpasswordpass = pywikibot.input(message, force=force,
                                              password=True)
            if botpasswordname and botpasswordpass:
                botpasswords.append((username, botpasswordname,
                                     botpasswordpass))

    if not userlist:  # Show a sample
        usernames = "# usernames['{}']['{}'] = u'MyUsername'".format(
            main_family, main_code)
    else:
        usernames = '\n'.join(
            "usernames['{user.family}']['{user.code}'] = u'{user.name}'"
            .format(user=user) for user in userlist)
        # Arbitrarily use the first key as default settings
        main_family, main_code = userlist[0].family, userlist[0].code
    botpasswords = '\n'.join(
        "('{0}', BotPassword('{1}', '{2}'))".format(*botpassword)
        for botpassword in botpasswords)

    config_text = copy_sections()
    if config_text:
        config_content = EXTENDED_CONFIG
    else:
        pywikibot.output('Creating a small variant of user-config.py')
        config_content = SMALL_CONFIG

    try:
        # Finally save user-config.py
        with codecs.open(_fnc, 'w', 'utf-8') as f:
            f.write(config_content.format(
                main_family=main_family,
                main_code=main_code,
                usernames=usernames,
                config_text=config_text,
                botpasswords='password_file = ' + ('"{}"'.format(PASS_BASENAME)
                                                   if botpasswords
                                                   else 'None')))
        pywikibot.output("'%s' written." % _fnc)
    except BaseException:
        if os.path.exists(_fnc):
            os.remove(_fnc)
        raise

    if botpasswords:
        # Save user-password.py if necessary
        # user-config.py is already created at this point
        # therefore pywikibot.tools can be imported safely
        from pywikibot.tools import file_mode_checker
        try:
            # First create an empty file with good permissions, before writing
            # in it
            with codecs.open(_fncpass, 'w', 'utf-8') as f:
                f.write('')
                file_mode_checker(_fncpass, mode=0o600, quiet=True)
            with codecs.open(_fncpass, 'w', 'utf-8') as f:
                f.write(PASSFILE_CONFIG.format(botpasswords=botpasswords))
                file_mode_checker(_fncpass, mode=0o600)
                pywikibot.output("'{0}' written.".format(_fncpass))
        except EnvironmentError:
            os.remove(_fncpass)
            raise
示例#13
0
    def readPassword(self):
        """
        Read passwords from a file.

        DO NOT FORGET TO REMOVE READ ACCESS FOR OTHER USERS!!!
        Use chmod 600 password-file.

        All lines below should be valid Python tuples in the form
        (code, family, username, password),
        (family, username, password) or
        (username, password)
        to set a default password for an username. The last matching entry will
        be used, so default usernames should occur above specific usernames.

        For BotPasswords the password should be given as a BotPassword object.

        The file must be either encoded in ASCII or UTF-8.

        Example::

         ('my_username', 'my_default_password')
         ('my_sysop_user', 'my_sysop_password')
         ('wikipedia', 'my_wikipedia_user', 'my_wikipedia_pass')
         ('en', 'wikipedia', 'my_en_wikipedia_user', 'my_en_wikipedia_pass')
         ('my_username', BotPassword(
          'my_BotPassword_suffix', 'my_BotPassword_password'))
        """
        # Set path to password file relative to the user_config
        # but fall back on absolute path for backwards compatibility
        password_file = os.path.join(config.base_dir, config.password_file)
        if not os.path.isfile(password_file):
            password_file = config.password_file

        # We fix password file permission first.
        file_mode_checker(password_file, mode=config.private_files_permission)

        with codecs.open(password_file, encoding='utf-8') as f:
            lines = f.readlines()
        line_nr = len(lines) + 1
        for line in reversed(lines):
            line_nr -= 1
            if not line.strip() or line.startswith('#'):
                continue
            try:
                entry = eval(line)
            except SyntaxError:
                entry = None
            if type(entry) is not tuple:
                warn('Invalid tuple in line {0}'.format(line_nr),
                     _PasswordFileWarning)
                continue
            if not 2 <= len(entry) <= 4:
                warn('The length of tuple in line {0} should be 2 to 4 ({1} '
                     'given)'.format(line_nr, entry), _PasswordFileWarning)
                continue

            code, family, username, password = (
                self.site.code, self.site.family.name)[:4 - len(entry)] + entry
            if (normalize_username(username) == self.username
                    and family == self.site.family.name
                    and code == self.site.code):
                if isinstance(password, UnicodeType):
                    self.password = password
                    break
                elif isinstance(password, BotPassword):
                    self.password = password.password
                    self.login_name = password.login_name(self.username)
                    break
                else:
                    warn('Invalid password format', _PasswordFileWarning)
    def readPassword(self):
        """
        Read passwords from a file.

        DO NOT FORGET TO REMOVE READ ACCESS FOR OTHER USERS!!!
        Use chmod 600 password-file.

        All lines below should be valid Python tuples in the form
        (code, family, username, password),
        (family, username, password) or
        (username, password)
        to set a default password for an username. The last matching entry will
        be used, so default usernames should occur above specific usernames.

        For BotPasswords the password should be given as a BotPassword object.

        The file must be either encoded in ASCII or UTF-8.

        Example:

        (u"my_username", u"my_default_password")
        (u"my_sysop_user", u"my_sysop_password")
        (u"wikipedia", u"my_wikipedia_user", u"my_wikipedia_pass")
        (u"en", u"wikipedia", u"my_en_wikipedia_user", u"my_en_wikipedia_pass")
        (u"my_username", BotPassword(u"my_BotPassword_suffix", u"my_BotPassword_password"))
        """
        # Set path to password file relative to the user_config
        # but fall back on absolute path for backwards compatibility
        password_file = os.path.join(config.base_dir, config.password_file)
        if not os.path.isfile(password_file):
            password_file = config.password_file

        # We fix password file permission first.
        file_mode_checker(password_file, mode=config.private_files_permission)

        password_f = codecs.open(password_file, encoding='utf-8')
        for line_nr, line in enumerate(password_f):
            if not line.strip():
                continue
            try:
                entry = eval(line)
            except SyntaxError:
                entry = None
            if type(entry) is not tuple:
                warn('Invalid tuple in line {0}'.format(line_nr),
                     _PasswordFileWarning)
                continue
            if not 2 <= len(entry) <= 4:
                warn(
                    'The length of tuple in line {0} should be 2 to 4 ({1} '
                    'given)'.format(line_nr, entry), _PasswordFileWarning)
                continue

            # When the tuple is inverted the default family and code can be
            # easily appended which makes the next condition easier as it does
            # not need to know if it's using the default value or not.
            entry = list(entry[::-1]) + [
                self.site.family.name, self.site.code
            ][len(entry) - 2:]

            if (normalize_username(entry[1]) == self.username
                    and entry[2] == self.site.family.name
                    and entry[3] == self.site.code):
                if isinstance(entry[0], basestring):
                    self.password = entry[0]
                elif isinstance(entry[0], BotPassword):
                    self.password = entry[0].password
                    self.login_name = entry[0].login_name(self.username)
                else:
                    warn('Invalid password format', _PasswordFileWarning)
        password_f.close()
示例#15
0
    def readPassword(self):
        """
        Read passwords from a file.

        DO NOT FORGET TO REMOVE READ ACCESS FOR OTHER USERS!!!
        Use chmod 600 password-file.

        All lines below should be valid Python tuples in the form
        (code, family, username, password),
        (family, username, password) or
        (username, password)
        to set a default password for an username. The last matching entry will
        be used, so default usernames should occur above specific usernames.

        For BotPasswords the password should be given as a BotPassword object.

        The file must be either encoded in ASCII or UTF-8.

        Example:

        (u"my_username", u"my_default_password")
        (u"my_sysop_user", u"my_sysop_password")
        (u"wikipedia", u"my_wikipedia_user", u"my_wikipedia_pass")
        (u"en", u"wikipedia", u"my_en_wikipedia_user", u"my_en_wikipedia_pass")
        (u"my_username", BotPassword(u"my_BotPassword_suffix", u"my_BotPassword_password"))
        """
        # Set path to password file relative to the user_config
        # but fall back on absolute path for backwards compatibility
        password_file = os.path.join(config.base_dir, config.password_file)
        if not os.path.isfile(password_file):
            password_file = config.password_file

        # We fix password file permission first.
        file_mode_checker(password_file, mode=config.private_files_permission)

        password_f = codecs.open(password_file, encoding='utf-8')
        for line_nr, line in enumerate(password_f):
            if not line.strip():
                continue
            try:
                entry = eval(line)
            except SyntaxError:
                entry = None
            if type(entry) is not tuple:
                warn('Invalid tuple in line {0}'.format(line_nr),
                     _PasswordFileWarning)
                continue
            if not 2 <= len(entry) <= 4:
                warn('The length of tuple in line {0} should be 2 to 4 ({1} '
                     'given)'.format(line_nr, entry), _PasswordFileWarning)
                continue

            # When the tuple is inverted the default family and code can be
            # easily appended which makes the next condition easier as it does
            # not need to know if it's using the default value or not.
            entry = list(entry[::-1]) + [self.site.family.name,
                                         self.site.code][len(entry) - 2:]

            if (normalize_username(entry[1]) == self.username and
                    entry[2] == self.site.family.name and
                    entry[3] == self.site.code):
                if isinstance(entry[0], basestring):
                    self.password = entry[0]
                elif isinstance(entry[0], BotPassword):
                    self.password = entry[0].password
                    self.login_name = entry[0].login_name(self.username)
                else:
                    warn('Invalid password format', _PasswordFileWarning)
        password_f.close()