Initial commit

This commit is contained in:
aewens 2019-01-17 23:32:03 +01:00
parent 53467cd95d
commit 01e8b3bba0
3 changed files with 222 additions and 1 deletions

View File

@ -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.

95
share Executable file
View File

@ -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()

126
uscripts Executable file
View File

@ -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))