Initial commit
This commit is contained in:
parent
53467cd95d
commit
01e8b3bba0
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) <year> <owner> . All rights reserved.
|
||||
Copyright (c) 2019 Austin Ewens. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from os import (stat, utime, fdopen, supports_fd, O_CREAT, O_APPEND,
|
||||
open as osopen)
|
||||
from os.path import exists, isfile
|
||||
from argparse import ArgumentParser
|
||||
from sys import exit, stderr
|
||||
from email.mime.text import MIMEText
|
||||
from subprocess import Popen, PIPE
|
||||
from getpass import getuser
|
||||
from pwd import getpwuid
|
||||
from socket import gethostname
|
||||
from shlex import split as shell_split
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=stderr, **kwargs)
|
||||
|
||||
def touch(fname, mode=0o666, dir_fd=None, **kwargs):
|
||||
flags = O_CREAT | O_APPEND
|
||||
with fdopen(osopen(fname, flags=flags, mode=mode, dir_fd=dir_fd)) as f:
|
||||
utime(f.fileno() if utime in supports_fd else fname,
|
||||
dir_fd=None if supports_fd else dir_fd, **kwargs)
|
||||
|
||||
def ownership(filename):
|
||||
return getpwuid(stat(filename).st_uid).pw_name
|
||||
|
||||
def mail(user, subject, body):
|
||||
domain = gethostname()
|
||||
message = MIMEText(body)
|
||||
message["From"] = "{}@{}".format(user, domain)
|
||||
message["To"] = "root@{}".format(domain)
|
||||
message["Subject"] = subject
|
||||
command = shell_split("/usr/sbin/sendmail -t -oi")
|
||||
proc = Popen(command, stdin=PIPE, universal_newlines=True)
|
||||
proc.communicate(message.as_string())
|
||||
|
||||
def share_list(config_file, splitter):
|
||||
scripts = None
|
||||
with open(config_file, "r") as cfgfile:
|
||||
scripts = cfgfile.read().split("\n")
|
||||
if len(scripts) == 1 and len(scripts[0]) == 0:
|
||||
print("There are currently no shared user scripts")
|
||||
exit(0)
|
||||
for script in scripts:
|
||||
name, path, desc, author = script.split(splitter)
|
||||
print("{}\t{} (made by {})".format(name, desc, author).expandtabs())
|
||||
|
||||
def share_submit(queue_file, splitter):
|
||||
script_path = input("Absolute path to script: ")
|
||||
if not isfile(script_path):
|
||||
eprint("ERROR: That script does not exist")
|
||||
exit(1)
|
||||
user = getuser()
|
||||
owner = ownership(script_path)
|
||||
if user != owner:
|
||||
eprint("ERROR: You do not own this script")
|
||||
exit(1)
|
||||
script_name = script_path.split("/")[-1]
|
||||
script_desc = input("Description of script: ")
|
||||
with open(queue_file, "a") as queue:
|
||||
queue.write("{0}{4}{1}{4}{2}{4}{3}".format(script_name, script_path,
|
||||
script_desc, user, splitter))
|
||||
subject = "Submission of '{}' script".format(script_name)
|
||||
body = "\n".join([
|
||||
"Path to script: {}".format(script_path),
|
||||
"Description: {}".format(script_desc),
|
||||
"Author: {}".format(user)
|
||||
])
|
||||
mail(user, subject, body)
|
||||
print("SUCCESS: Your script has been submitted for approval")
|
||||
|
||||
config_file = "/center/etc/shared"
|
||||
splitter = "%%"
|
||||
if not exists(config_file):
|
||||
touch(config_file)
|
||||
|
||||
queue_file = "{}.queue".format(config_file)
|
||||
if not exists(queue_file):
|
||||
touch(queue_file)
|
||||
|
||||
description = "Allows users to share their scripts with the server"
|
||||
parser = ArgumentParser(prog="share", description=description)
|
||||
subparsers = parser.add_subparsers(title="commands", dest="commands")
|
||||
subparsers.required = False
|
||||
list_parser = subparsers.add_parser("list", help="list all shared scripts")
|
||||
submit_parser = subparsers.add_parser("submit",
|
||||
help="starts interactive prompt to share your script")
|
||||
arguments = parser.parse_args()
|
||||
|
||||
if arguments.commands == "list":
|
||||
share_list(config_file, splitter)
|
||||
elif arguments.commands == "submit":
|
||||
share_submit(queue_file, splitter)
|
||||
else:
|
||||
parser.print_help()
|
|
@ -0,0 +1,126 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from os import symlink
|
||||
from os.path import exists
|
||||
from argparse import ArgumentParser
|
||||
from sys import exit, stderr
|
||||
from argparse import ArgumentParser
|
||||
from getpass import getuser
|
||||
from email.mime.text import MIMEText
|
||||
from subprocess import Popen, PIPE
|
||||
from socket import gethostname
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=stderr, **kwargs)
|
||||
|
||||
def mail(sender, user, subject, body):
|
||||
domain = gethostname()
|
||||
message = MIMEText(body)
|
||||
message["From"] = "{}@{}".format(sender, domain)
|
||||
message["To"] = "{}@{}".format(user, domain)
|
||||
message["Subject"] = subject
|
||||
command = shell_split("/usr/sbin/sendmail -t -oi")
|
||||
proc = Popen(command, stdin=PIPE, universal_newlines=True)
|
||||
proc.communicate(message.as_string())
|
||||
|
||||
def remove_script_from_queue(queue_file, splitter, scripts, index):
|
||||
script_name = sorted(list(scripts.keys()))[index]
|
||||
del scripts[script_name]
|
||||
lines = list()
|
||||
for name, attrs in scripts:
|
||||
path = attrs.get("path", "")
|
||||
desc = attrs.get("desc", "")
|
||||
user = attrs.get("user", "")
|
||||
lines.append(splitter.join([name, path, desc, user]))
|
||||
with open(queue_file, "w") as qfile:
|
||||
qfile.write("\n".join(lines))
|
||||
|
||||
description = "Administrative tool for handling shared user script submissions"
|
||||
parser = ArgumentParser(prog="uscript", description=description)
|
||||
parser.add_argument("-l", "--list", dest="list", action="store_true",
|
||||
help="list all submitted scripts")
|
||||
parser.add_argument("-a", "--approve", dest="approve", nargs="?",
|
||||
help="approval of script index based on position from --list")
|
||||
parser.add_argument("-R", "--reject", dest="reject", nargs="?",
|
||||
help="rejection of script index based on position from --list")
|
||||
arguments = parser.parse_args()
|
||||
|
||||
config_file = "/center/etc/shared"
|
||||
queue_file = "{}.queue".format("/center/etc/shared")
|
||||
splitter = "%%"
|
||||
queued = None
|
||||
|
||||
if not exists(queue_file):
|
||||
print("No scripts are queued")
|
||||
exit(0)
|
||||
|
||||
with open(queue_file, "r") as qfile:
|
||||
queued = qfile.read().split("\n")
|
||||
|
||||
if len(queued) == 1 and len(queued[0]) == 0:
|
||||
print("No scripts are queued")
|
||||
exit(0)
|
||||
|
||||
scripts = dict()
|
||||
names = list()
|
||||
for queue in queued:
|
||||
name, path, desc, user = queue.split(splitter)
|
||||
scripts[name] = {
|
||||
"path": path,
|
||||
"desc": desc,
|
||||
"user": user
|
||||
}
|
||||
names.append(name)
|
||||
names = sorted(names)
|
||||
|
||||
if arguments.list:
|
||||
header = "Index\tScript\tAuthor".expandtabs()
|
||||
print(header)
|
||||
print("-" * len(header))
|
||||
for n, name in enumerate(names):
|
||||
author = scripts[name]["user"]
|
||||
print("{}\t{}\t{}".format(n, name, author).expandtabs())
|
||||
|
||||
approved = arguments.approve
|
||||
rejected = arguments.reject
|
||||
if approved is not None:
|
||||
approved = int(approved)
|
||||
if 0 > approved >= len(names):
|
||||
eprint("ERROR: That index does not exist, see --list")
|
||||
exit(1)
|
||||
script_name = names[approved]
|
||||
script = scripts[script_name]
|
||||
script_path = script["path"]
|
||||
user = script["user"]
|
||||
sender = getuser()
|
||||
user_bin = "/center/bin"
|
||||
symlink(script_path, "{}/{}".format(user_bin, script_name))
|
||||
remove_script_from_queue(queue_file, splitter, scripts, approved)
|
||||
subject = "{} has been approved".format(script_name)
|
||||
body = "".join([
|
||||
"Congratulations! Your script '{}' has been ".format(script_name),
|
||||
"approved by {} and has been added to the server's ".format(sender),
|
||||
"user script repository found at /center/bin."
|
||||
])
|
||||
mail(sender, user, subject, body)
|
||||
print("'{}' has been approved, email has been sent".format(script_name))
|
||||
|
||||
if rejected is not None:
|
||||
rejected = int(rejected)
|
||||
if 0 > rejected >= len(names):
|
||||
eprint("ERROR: That index does not exist, see --list")
|
||||
exit(1)
|
||||
script_name = names[rejected]
|
||||
script = scripts[script_name]
|
||||
user = script["user"]
|
||||
sender = getuser()
|
||||
remove_script_from_queue(queue_file, splitter, scripts, rejected)
|
||||
print("'{}' has been rejected".format(script_name))
|
||||
reason = input("Provide reason for user ({}): ".format(author))
|
||||
subject = "{} has been rejected".format(script_name)
|
||||
body = "".join([
|
||||
"Unfortunately, your script '{}' has been ".format(script_name),
|
||||
"rejected by {} for the following reason(s):\n{}".format(sender)
|
||||
])
|
||||
mail(sender, user, subject, body)
|
||||
print("'{}' has been rejected, email has been sent".format(script_name))
|
Loading…
Reference in New Issue