Updated to remove useless functionality. Will now output as shell variables

This commit is contained in:
Anon 2024-03-09 18:02:54 -08:00
parent ab258c30dd
commit 2819c01a9c
4 changed files with 158 additions and 222 deletions

154
create_app.py Executable file
View File

@ -0,0 +1,154 @@
#! /usr/bin/env python3
# CreatePleromaApp, a python script to generate OAuth tokens for fedi
# Copyright (C) 2024 Anon <@Anon@yandere.cc>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import getpass
import os
import re
import sys
import argparse
from mastodon import Mastodon, MastodonIllegalArgumentError, MastodonAPIError, MastodonIOError
class CreateAppError(Exception):
pass
# Modify this section to suit your default preferances
def default(key):
defaults={
"app": "app",
"domain": "https://yandere.cc",
"scopes": "write",
}
return defaults[key]
def printerr(s, end=None):
print(s, file=sys.stderr, end=end if end != None else os.linesep)
def inputerr(q):
sys.stdout.flush()
sys.stderr.flush()
printerr(q, end="")
return input()
# Function to format user input consistently with lables
def _input(lable, ans=""):
if ans:
q = "{} (Default: {}): ".format(
lable, ans)
return inputerr(q) or ans
else:
q = "{}: ".format(lable)
return inputerr(q)
def get_client_id_and_secret(app, permissions, domain):
try:
return Mastodon.create_app(app, scopes=permissions, api_base_url=domain)
except MastodonIOError:
raise CreateAppError("An error occurred. Make sure the domain name is correct.")
def get_api(client_id, client_secret, domain):
api = Mastodon(
client_id,
client_secret,
api_base_url=domain,
feature_set="pleroma"
)
return api
def get_token(api, email, password, permissions):
try:
token = api.log_in(email, password, scopes=permissions)
return token
except MastodonIllegalArgumentError:
raise CreateAppError("Username or Password is incorrect.")
except MastodonAPIError:
raise CreateAppError("Could not grant scopes:", ", ".join(permissions))
def main():
# Parser
parser = argparse.ArgumentParser(
description="A script to generate OAuth tokens for fedi",
epilog="",
add_help=True)
_ = parser.parse_args()
try:
# Settings Dictionary
settings = {}
# Create App
printerr("Generate and register Mastodon App")
printerr("You can just hit enter to accept the default for prompts that have them")
printerr("Ctrl+C to Quit\n")
# Get instance information
app_name = _input("Enter your app name", default("app"))
settings["API_BASE_URL"] = _input("URL of Instance", default("domain"))
email = _input("Enter your email")
password = getpass.getpass("Enter password: ")
printerr("Scopes: read, write, follow, push")
printerr("Separate each scope with a comma (example above).")
printerr("!!! Accept the default unless you intend to modify Yandere Lewd Bot !!!")
ans = _input("Scopes", default("scopes"))
ans = re.sub(r"\s+", "", ans, flags=re.UNICODE)
permissions = ans.split(",")
printerr("Granting: {}".format(str(permissions)))
# Begin logging in
settings["CLIENT_ID"], settings["CLIENT_SECRET"] =\
get_client_id_and_secret(
app_name,
permissions,
settings["API_BASE_URL"]
)
api = get_api(
settings["CLIENT_ID"],
settings["CLIENT_SECRET"],
settings["API_BASE_URL"]
)
settings["ACCESS_TOKEN"] = get_token(api, email, password, permissions)
# Output the user's new credentials
for k, v in settings.items():
v = settings[k]
print("{}={}".format(k, v))
printerr("Success :)")
return 0
except (KeyboardInterrupt, EOFError):
printerr("\nUser Quit :|")
return 1
except CreateAppError as e:
printerr(e)
printerr("Error :(")
return 2
except Exception as e:
printerr(e)
printerr("Unhandled Exception ¯\\_(ツ)_/¯")
return 3
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,2 +0,0 @@
Mastodon.py
cryptography

8
run.sh
View File

@ -1,7 +1,7 @@
#! /usr/bin/env bash #! /usr/bin/env bash
# Create Pleroma App, automate the creation of pleroma apps # CreatePleromaApp, a python script to generate OAuth tokens for fedi
# Copyright (C) 2022 Anon <@Anon@yandere.cc> # Copyright (C) 2024 Anon <@Anon@yandere.cc>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -21,8 +21,8 @@ ABS_PATH="$(readlink -f "$0")"
RUN_DIR="$(dirname "$ABS_PATH")" RUN_DIR="$(dirname "$ABS_PATH")"
# Relative paths to the virtual environment and main.py # Relative paths to the virtual environment and main.py
VENV='./venv/bin/activate' VENV='${RUN_DIR}/venv/bin/activate'
ENTRY='./src/create_app.py' ENTRY='${RUN_DIR}/create_app.py'
# cd into the bot's root path, set up the virtual environment, and run # cd into the bot's root path, set up the virtual environment, and run
cd "$RUN_DIR" cd "$RUN_DIR"

View File

@ -1,216 +0,0 @@
#! /usr/bin/env python3
# Create Pleroma App, a python script to generate OAuth tokens for fedi
# Copyright (C) 2022 Anon <@Anon@yandere.cc>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import getpass
import re
import sys
import datetime
import argparse
import contextlib
import os
from pprint import pformat
from mastodon import Mastodon, MastodonIllegalArgumentError, MastodonAPIError, MastodonIOError
from collections import OrderedDict
class CreateAppError(Exception):
pass
# Modify this section to suit your default preferances
def default(key):
defaults={
"app": "app",
"domain": "https://yandere.cc",
"scopes": "write",
"encrypt": "y",
"cfg": None,
"long_date_format": "%m/%d/%Y %I:%M%p"
}
return defaults[key]
# Function to format user input consistently with lables
def _input(lable, ans=None):
if ans:
q = "{} (Default: {}): ".format(
lable, ans)
return input(q) or ans
else:
q = "{}: ".format(lable)
return input(q)
def get_client_id_and_secret(app, permissions, domain):
try:
return Mastodon.create_app(app, scopes=permissions, api_base_url=domain)
except MastodonIOError:
raise CreateAppError("An error occurred. Make sure the domain name is correct.")
def get_api(client_id, client_secret, domain):
api = Mastodon(client_id, client_secret, api_base_url=domain)
return api
def get_token(api, email, password, permissions):
try:
token = api.log_in(email, password, scopes=permissions)
return token
except MastodonIllegalArgumentError:
raise CreateAppError("Username or Password is incorrect.")
except MastodonAPIError:
raise CreateAppError("Could not grant scopes:", ", ".join(permissions))
def get_cfg(cfg_name):
try:
import importlib
cfg = importlib.import_module(cfg_name)
return cfg
except ImportError:
raise CreateAppError("Cannot import module:", cfg_name, "Make sure you omitted the .py extension and try again")
def package_settings(app, domain, client_id, client_secret, token):
settings_server = OrderedDict([
("app_name", app),
("api_base_url", domain),
("client_id", client_id),
("client_secret", client_secret),
("access_token", token)
])
return settings_server
def get_setting_reminder(fmt):
dt_now = datetime.datetime.now()
dt_now = dt_now.replace(year=dt_now.year + 1)
settings_reminder = dt_now.strftime(fmt)
return settings_reminder
def credentials_py(label, setting):
return "{} = {}".format(label, pformat(setting))
def credentials_ini(label, setting):
r = "[{}]".format(label)
for k, v in setting.items():
r += "\n{}={}".format(k, v)
return r
def main():
# Default time localization
long_date_format = default("long_date_format")
# Parser
parser = argparse.ArgumentParser(
description="A script to generate OAuth tokens for fedi",
epilog="",
add_help=True)
parser.add_argument("-c", "--config", help="Use time localization settings from a pyhton config file (omit the .py extension)", default=None)
parser.add_argument("-k", "--keyfile", help="Keyfile used for decryption", default=None)
parser.add_argument("--plain", help="Output credentials in plain ini format", action="store_true")
parser.add_argument("--minimal", help="Only print OAuth credentials, ignoring encryption settings", action="store_true")
arguments = parser.parse_args()
try:
# Custom time localization
# This is mainly intended to be used with bots configured with python files
# This python file should contain the following dictionary with a key value pair of:
# settings_time = {"long_date_format": "%m/%d/%Y %I:%M%p"}
load_config = arguments.config or default("cfg")
if load_config:
cfg = get_cfg(load_config)
long_date_format = cfg.settings_time["long_date_format"]
# Create App
print("Generate and register Mastodon App")
print("You can just hit enter to accept the default for prompts that have them")
print("Ctrl+C to Quit\n")
# Get instance information
app = _input("Enter your app name", default("app"))
domain = _input("URL of Instance", default("domain"))
email = _input("Enter your email")
password = getpass.getpass("Enter password: ")
print("Scopes: read, write, follow, push")
print("Separate each scope with a comma (example above).")
print("!!! Accept the default unless you intend to modify Yandere Lewd Bot !!!")
ans = _input("Scopes", default("scopes"))
ans = re.sub(r"\s+", "", ans, flags=re.UNICODE)
permissions = ans.split(",")
print("Granting:", permissions)
# Begin logging in
client_id, client_secret = get_client_id_and_secret(app, permissions, domain)
api = get_api(client_id, client_secret, domain)
token = get_token(api, email, password, permissions)
# Credentials (unencrypted)
encrypt, salt = False, ""
settings_server = package_settings(app, domain, client_id, client_secret, token)
reminder = get_setting_reminder(long_date_format)
# Encrypt
if not arguments.minimal:
with contextlib.suppress(ImportError):
import FediBotEncryption
ans = _input("Do you want to encrypt your credentials? (y/n)", default("encrypt"))
if ans.upper() in ("Y", "YES"):
encrypt = True
salt, settings_server = FediBotEncryption.settings_server_encrypt(settings_server, arguments.keyfile)
settings_encrypt = OrderedDict([
("encrypt", encrypt),
("salt", salt),
("keyfile", arguments.keyfile)
])
settings_reminder = OrderedDict([
("settings_reminder", reminder)
])
# Credential formatting functions
formatted_credentials = credentials_ini if arguments.plain else credentials_py
# Output the user's new credentials
print("Copy to your config file!!!")
print(formatted_credentials("settings_server", settings_server))
if not arguments.minimal:
print("\n{}\n".format(formatted_credentials("settings_reminder", settings_reminder)))
print(formatted_credentials("settings_encrypt", settings_encrypt))
print("Success :)")
return 0
except (KeyboardInterrupt, EOFError):
print("User Quit :|")
return 1
except CreateAppError as e:
print(e)
print("Error :(")
return 2
except Exception as e:
print(e)
print("Unhandled Exception ¯\\_(ツ)_/¯")
return 3
if __name__ == "__main__":
sys.exit(main())