Example #1
0
 def test_get_crontab_many_jobs(self):
     num_of_jobs = MANY
     # Create a crontab with many jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     api.set_crontab(crontab, user1)
     test_crontab = api.get_crontab(user1)
     self.assertEqual(crontab, test_crontab)
Example #2
0
 def test_get_crontab_many_jobs(self):
     num_of_jobs = MANY
     # Create a crontab with many jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     api.set_crontab(crontab, user1)
     test_crontab = api.get_crontab(user1)
     self.assertEqual(crontab, test_crontab)
Example #3
0
 def test_set_crontab_one_job(self):
     num_of_jobs = ONE
     # Create a crontab with one jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     test_crontab = api.get_crontab(user1)
     self.assertEquals(test_crontab, False)
     api.set_crontab(crontab, user1)
     test_crontab = api.get_crontab(user1)
     self.assertEqual(crontab, test_crontab)
Example #4
0
 def test_set_crontab_one_job(self):
     num_of_jobs = ONE
     # Create a crontab with one jobs
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     test_crontab = api.get_crontab(user1)
     self.assertEquals(test_crontab, False)
     api.set_crontab(crontab, user1)
     test_crontab = api.get_crontab(user1)
     self.assertEqual(crontab, test_crontab)
Example #5
0
def process_edits(uid, tb_file, using_local_file, old_tab):
    crontab = []
    jobs = []
    old_jobs = api.get_jobs_for_user(uid)
    with open(tb_file, "r") as tab:
        for line in tab:
            line = line.strip()
            crontab.append(line)
            # Ignore newlines and full line comments
            if line and (line[0] != "#"):
                split = line.split()
                interval = " ".join(split[:5])
                cmd = " ".join(split[5:])
                try:
                    # Ensure the crontab line is valid
                    croniter(interval)
                    if not cmd:
                        raise ValueError
                except (KeyError, ValueError):
                    # Otherwise prompt user to edit crontab
                    e_str = "The crontab you entered has invalid entries, " "would you like to edit it again? (y/n) "
                    while True:
                        cnt = _input(e_str)
                        if (cnt == "n") or (cnt == "N"):
                            if using_local_file is False:
                                os.unlink(tb_file)
                            sys.exit(1)
                        elif (cnt == "y") or (cnt == "Y"):
                            return False
                        e_str = "Please enter y or n: "

                # Check if job was already there
                job = None
                if line in old_tab:
                    for old_job in old_jobs:
                        if old_job.interval == interval and old_job.command == cmd:
                            job = old_job
                            old_jobs.remove(old_job)
                            break
                if not job:
                    old_tab.discard(line)
                    job = api.Job(interval, cmd, uid, datetime.now())
                jobs.append(job)

    if using_local_file is False:
        os.unlink(tb_file)

    api.set_crontab("\n".join(crontab), uid)
    api.set_jobs(jobs, uid)
    return True
Example #6
0
 def test_get_crontab_different_users_many_jobs(self):
     num_of_jobs = MANY
     # Create a crontab with many jobs for another user from crontab owner
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     api.set_crontab(crontab, user2)
     test_crontab = api.get_crontab(user2)
     self.assertEqual(crontab, test_crontab)
     # Append crontab for another user
     test_jobs = create_test_tab(num_of_jobs, user3)
     api.set_jobs(test_jobs, user3)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     api.set_crontab(crontab, user3)
     test_crontab = api.get_crontab(user3)
     self.assertEqual(crontab, test_crontab)
Example #7
0
 def test_get_crontab_different_users_many_jobs(self):
     num_of_jobs = MANY
     # Create a crontab with many jobs for another user from crontab owner
     test_jobs = create_test_tab(num_of_jobs, user1)
     api.set_jobs(test_jobs, user1)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     api.set_crontab(crontab, user2)
     test_crontab = api.get_crontab(user2)
     self.assertEqual(crontab, test_crontab)
     # Append crontab for another user
     test_jobs = create_test_tab(num_of_jobs, user3)
     api.set_jobs(test_jobs, user3)
     with open(TAB_FILE, 'r') as tabfile:
         crontab = tabfile.read()
     api.set_crontab(crontab, user3)
     test_crontab = api.get_crontab(user3)
     self.assertEqual(crontab, test_crontab)
Example #8
0
def main():
    tb_file = None
    valid_crontab = None
    usr_euid = os.geteuid()
    opts = parse_args()

    # Convert given username into (uid, username)
    if opts.usr:
        try:
            opts.usr = (pwd.getpwnam(opts.usr).pw_uid, opts.usr)
        except KeyError:
            sys.exit("User '%s' does not exist." % opts.usr)

        # Verify permissions for selected crontab
        if (usr_euid != 0) and (opts.usr[0] != usr_euid):
            sys.exit("Access denied. You do not have permission to edit %s's " "crontab." % opts.usr[1])
    # If no user is specified, set to current user (euid or uid?)
    else:
        opts.usr = (usr_euid, pwd.getpwuid(usr_euid).pw_name)

    # Perform rm operation
    if opts.rm:
        if opts.rm_prompt:
            rm = None
            e_str = "You are about to delete %s's crontab, continue? " "(y/n) " % opts.usr[1]
            while (rm != "Y") and (rm != "y"):
                rm = _input(e_str)
                if (rm == "N") or (rm == "n"):
                    sys.exit(0)
                e_str = "Please enter y or n: "

        api.set_jobs([], opts.usr[0])
        api.set_crontab(False, opts.usr[0])
        sys.exit(0)

    while not valid_crontab:
        tb_file, old_tab = get_crontab(opts, valid_crontab, tb_file)
        valid_crontab = process_edits(opts.usr[0], tb_file, opts.file, old_tab)
Example #9
0
def main():
    tb_file = None
    valid_crontab = None
    usr_euid = os.geteuid()
    opts = parse_args()

    # Convert given username into (uid, username)
    if opts.usr:
        try:
            opts.usr = (pwd.getpwnam(opts.usr).pw_uid, opts.usr)
        except KeyError:
            sys.exit("User `%s' does not exist." % opts.usr)
    # If no user is specified, set to current user (euid or uid?)
    else:
        opts.usr = (usr_euid, pwd.getpwuid(usr_euid).pw_name)

    check_permissions(opts.usr, usr_euid)

    # Perform rm operation
    if opts.rm:
        if opts.rm_prompt:
            rm = None
            e_str = ("You are about to delete %s's crontab, continue? "
                     "(y/n) " % opts.usr[1])
            while (rm != 'Y') and (rm != 'y'):
                rm = _input(e_str)
                if (rm == 'N') or (rm == 'n'):
                    sys.exit(0)
                e_str = "Please enter y or n: "

        api.set_jobs([], opts.usr[0])
        api.set_crontab(False, opts.usr[0])
        sys.exit(0)

    while not valid_crontab:
        tb_file, old_tab = get_crontab(opts, valid_crontab, tb_file)
        valid_crontab = process_edits(opts.usr[0], tb_file, opts.file, old_tab)
Example #10
0
def main():
    tb_file = None
    valid_crontab = None
    usr_euid = os.geteuid()
    opts = parse_args()

    # Convert given username into (uid, username)
    if opts.usr:
        try:
            opts.usr = (pwd.getpwnam(opts.usr).pw_uid, opts.usr)
        except KeyError:
            sys.exit("User `%s' does not exist." % opts.usr)
    # If no user is specified, set to current user (euid or uid?)
    else:
        opts.usr = (usr_euid, pwd.getpwuid(usr_euid).pw_name)

    check_permissions(opts.usr, usr_euid)

    # Perform rm operation
    if opts.rm:
        if opts.rm_prompt:
            rm = None
            e_str = ("You are about to delete %s's crontab, continue? "
                     "(y/n) " % opts.usr[1])
            while (rm != 'Y') and (rm != 'y'):
                rm = _input(e_str)
                if (rm == 'N') or (rm == 'n'):
                    sys.exit(0)
                e_str = "Please enter y or n: "

        api.set_jobs([], opts.usr[0])
        api.set_crontab(False, opts.usr[0])
        sys.exit(0)

    while not valid_crontab:
        tb_file, old_tab = get_crontab(opts, valid_crontab, tb_file)
        valid_crontab = process_edits(opts.usr[0], tb_file, opts.file, old_tab)
Example #11
0
def process_edits(uid, tb_file, using_local_file, old_tab):
    e_str = ""
    jobs = []
    crontab = []
    old_jobs = api.get_jobs_for_user(uid)
    with open(tb_file, 'r') as tab:
        for i, line in enumerate(tab):
            line = line.strip()
            crontab.append(line)
            # Ignore newlines and comments
            if line and (line[0] != '#'):
                split = line.split()
                # Check for special interval syntax
                if split[0][0] == '@':
                    try:
                        interval = _special_intervals[split[0]]
                    except KeyError:
                        e_str += ("Error in line %i: Bad special interval "
                                  "syntax, %s\n" % (i + 1, split[0]))
                        continue
                    cmd = ' '.join(split[1:])

                # Check if setting variable
                elif '=' in ''.join(split[:5]):
                    name, _, value = line.partition('=')

                    # Check if var name is zero or multiple words
                    name = name.strip()
                    num_names = len(name.split())
                    if num_names != 1:
                        if num_names:
                            e_str += ("Error in line %i: Bad variable "
                                      "assignment syntax; multiple variable "
                                      "names given\n" % (i + 1))
                        else:
                            e_str += ("Error in line %i: Bad variable "
                                      "assignment syntax; no variable name "
                                      "given\n" % (i + 1))
                    else:
                        value = value.strip()
                        if (((value[0] == "'") or (value[0] == '"'))
                                and (value[-1] == value[0])):
                            # If properly wrapped in quotes, check if escaped
                            for i, char in enumerate(reversed(value[:-1])):
                                if char != '\\':
                                    i += 1
                                    break
                            if i % 2 != 0:
                                value = value[1:-1]
                        os.environ[name] = value
                    continue

                else:
                    # Check if five or six time/date fields
                    if (len(split) > 5 and not any(c.isalpha()
                                                   for c in split[5])
                            and ('*' in split[5] or any(c.isdigit()
                                                        for c in split[5]))
                            and split[5][0] != '/'):
                        # Could print warning that using 6 time fields
                        interval = ' '.join(split[:6])
                        cmd = ' '.join(split[6:])
                    else:
                        interval = ' '.join(split[:5])
                        cmd = ' '.join(split[5:])

                # Check for un-escaped %s in command
                job_input = None
                index = cmd.find('%')
                while (index != -1) and (cmd[index - 1] == '\\'):
                    index = cmd.find('%', index + 1)
                if index != -1:
                    job_input = _escaped_pct.sub(
                        '%', _unescaped_pct.sub(r"\1\n", cmd[index + 1:]))
                    cmd = cmd[:index]
                cmd = _escaped_pct.sub('%', cmd)

                # Ensure the crontab line is valid
                try:
                    croniter(interval)
                    if not cmd:
                        raise ValueError("Missing command")
                except (KeyError, ValueError) as e:
                    if isinstance(e, KeyError):
                        e = "Bad time interval syntax, %s " % e
                    # Replace croniter's typo-riddled error msg
                    elif str(e) == ("Exactly 5 or 6 columns has to be "
                                    "specified for iteratorexpression."):
                        e = ("Less than 5 fields separated by whitespace in "
                             "the time interval (requires 5 or 6)")
                    e_str += "Error in line %i: %s\n" % (i + 1, e)
                else:
                    if not e_str:
                        job = None
                        # Check if job was in the old crontab
                        if line in old_tab:
                            for old_job in old_jobs:
                                if (old_job.interval == interval
                                        and old_job.command == cmd
                                        and old_job.job_input == job_input
                                        and old_job.environment == os.environ):
                                    job = old_job
                                    old_jobs.remove(old_job)
                                    break
                        if not job:
                            old_tab.discard(line)
                            job = api.Job(interval, cmd, uid,
                                          os.environ.copy(), job_input,
                                          datetime.now())
                        jobs.append(job)
    # Prompt user to edit crontab on error
    if e_str:
        e_str += ("The crontab you entered has invalid entries, "
                  "would you like to edit it again? (y/n) ")
        while True:
            cnt = _input(e_str)
            if (cnt == 'n') or (cnt == 'N'):
                if using_local_file is False:
                    os.unlink(tb_file)
                sys.exit(1)
            elif (cnt == 'y') or (cnt == 'Y'):
                return False
            e_str = "Please enter y or n: "

    if using_local_file is False:
        os.unlink(tb_file)

    api.set_crontab('\n'.join(crontab), uid)
    api.set_jobs(jobs, uid)
    return True
Example #12
0
def process_edits(uid, tb_file, using_local_file, old_tab):
    e_str = ""
    jobs = []
    crontab = []
    old_jobs = api.get_jobs_for_user(uid)
    with open(tb_file, 'r') as tab:
        for i, line in enumerate(tab):
            line = line.strip()
            crontab.append(line)
            # Ignore newlines and comments
            if line and (line[0] != '#'):
                split = line.split()
                # Check for special interval syntax
                if split[0][0] == '@':
                    try:
                        interval = _special_intervals[split[0]]
                    except KeyError:
                        e_str += ("Error in line %i: Bad special interval "
                                  "syntax, %s\n" % (i + 1, split[0]))
                        continue
                    cmd = ' '.join(split[1:])

                # Check if setting variable
                elif '=' in ''.join(split[:5]):
                    name, _, value = line.partition('=')

                    # Check if var name is zero or multiple words
                    name = name.strip()
                    num_names = len(name.split())
                    if num_names != 1:
                        if num_names:
                            e_str += ("Error in line %i: Bad variable "
                                      "assignment syntax; multiple variable "
                                      "names given\n" % (i + 1))
                        else:
                            e_str += ("Error in line %i: Bad variable "
                                      "assignment syntax; no variable name "
                                      "given\n" % (i + 1))
                    else:
                        value = value.strip()
                        if (((value[0] == "'") or (value[0] == '"')) and
                           (value[-1] == value[0])):
                            # If properly wrapped in quotes, check if escaped
                            for i, char in enumerate(reversed(value[:-1])):
                                if char != '\\':
                                    i += 1
                                    break
                            if i % 2 != 0:
                                value = value[1:-1]
                        os.environ[name] = value
                    continue

                else:
                    # Check if five or six time/date fields
                    if (len(split) > 5 and
                            not any(c.isalpha() for c in split[5]) and
                            ('*' in split[5] or
                             any(c.isdigit() for c in split[5])) and
                            split[5][0] != '/'):
                        # Could print warning that using 6 time fields
                        interval = ' '.join(split[:6])
                        cmd = ' '.join(split[6:])
                    else:
                        interval = ' '.join(split[:5])
                        cmd = ' '.join(split[5:])

                # Check for un-escaped %s in command
                job_input = None
                index = cmd.find('%')
                while (index != -1) and (cmd[index-1] == '\\'):
                    index = cmd.find('%', index + 1)
                if index != -1:
                    job_input = _escaped_pct.sub('%', _unescaped_pct.sub(
                                                 r"\1\n", cmd[index+1:]))
                    cmd = cmd[:index]
                cmd = _escaped_pct.sub('%', cmd)

                # Ensure the crontab line is valid
                try:
                    croniter(interval)
                    if not cmd:
                        raise ValueError("Missing command")
                except (KeyError, ValueError) as e:
                    if isinstance(e, KeyError):
                        e = "Bad time interval syntax, %s " % e
                    # Replace croniter's typo-riddled error msg
                    elif str(e) == ("Exactly 5 or 6 columns has to be "
                                    "specified for iteratorexpression."):
                        e = ("Less than 5 fields separated by whitespace in "
                             "the time interval (requires 5 or 6)")
                    e_str += "Error in line %i: %s\n" % (i + 1, e)
                else:
                    if not e_str:
                        job = None
                        # Check if job was in the old crontab
                        if line in old_tab:
                            for old_job in old_jobs:
                                if (old_job.interval == interval and
                                        old_job.command == cmd and
                                        old_job.job_input == job_input and
                                        old_job.environment == os.environ):
                                    job = old_job
                                    old_jobs.remove(old_job)
                                    break
                        if not job:
                            old_tab.discard(line)
                            job = api.Job(interval, cmd, uid,
                                          os.environ.copy(), job_input,
                                          datetime.now())
                        jobs.append(job)
    # Prompt user to edit crontab on error
    if e_str:
        e_str += ("The crontab you entered has invalid entries, "
                  "would you like to edit it again? (y/n) ")
        while True:
            cnt = _input(e_str)
            if (cnt == 'n') or (cnt == 'N'):
                if using_local_file is False:
                    os.unlink(tb_file)
                sys.exit(1)
            elif (cnt == 'y') or (cnt == 'Y'):
                return False
            e_str = "Please enter y or n: "

    if using_local_file is False:
        os.unlink(tb_file)

    api.set_crontab('\n'.join(crontab), uid)
    api.set_jobs(jobs, uid)
    return True