Created
August 7, 2021 20:03
-
-
Save mk270/e7f805f326d017cfe469023528b200aa to your computer and use it in GitHub Desktop.
A tool for adding Ghost CMS users from the command line
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# ghost-add-user, (c) Martin Keegan 2021 | |
# Copyright licence: Apache Software Licence 2.0 | |
# A tool for adding new users to Ghost CMS from the command line | |
# please excuse this pre-alpha code. I was in a massive hurry. | |
import logging | |
import argparse | |
import MySQLdb | |
import random | |
import datetime | |
import bcrypt | |
LOCATION = "Cambridge, UK" | |
PROFILE_IMG = "https://static.ghost.org/v4.0.0/images/ghost-user.png" | |
DBARGS = { | |
"db": "ghost_production" | |
} | |
def make_random_id(): | |
"""Return a random hex-encoded string, e.g., '60e7252b8c40d317d8dd08af'.""" | |
s = "" | |
for x in range(0, 24): | |
s += random.choice(['0','1','2','3','4','5','6','7','8','9', | |
'a','b','c','d','e','f']) | |
return s | |
def make_time(): | |
"""Return the current time in a string format acceptable to MySQL.""" | |
return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
def hash_pw(password): | |
"""Take bytes and return a password hash using bcrypt. Example output: | |
$2b$12$4HdDp3Zb/P4si9yLLf1yXOPp7zC6NagX22Ub8c2xFZeWtVCibFl4u | |
""" | |
return bcrypt.hashpw(password, bcrypt.gensalt()) | |
def main(args): | |
logging.info("running") | |
db = MySQLdb.connect(**DBARGS) | |
c = db.cursor() | |
default_role = 'Editor' | |
c.execute("select id from roles where name = %s", (default_role,)) | |
(role_id,) = c.fetchone() | |
user_id = make_random_id() | |
password = hash_pw(args.password.encode('UTF-8')) | |
insertion = { | |
"id": user_id, | |
"name": args.name, | |
"slug": args.username, | |
"password": password, | |
"email": args.email, | |
"profile_image": PROFILE_IMAGE, | |
"cover_image": None, | |
"bio": None, | |
"website": None, | |
"location": args.location, | |
"facebook": None, | |
"twitter": None, | |
"accessibility": None, | |
"status": "active", | |
"locale": None, | |
"visibility": "public", | |
"meta_title": None, | |
"meta_description": None, | |
"tour": None, | |
"last_seen": make_time(), | |
"created_at": make_time(), | |
"created_by": "1", | |
"updated_at": make_time(), | |
"updated_by": "1" | |
} | |
print(insertion) | |
columns = insertion.keys() | |
cols_sepd = ", ".join(columns) | |
binds_sepd = ', '.join(['%(' + item + ')s' for item in columns]) | |
c.execute(f"insert into users ({cols_sepd}) values ({binds_sepd})", | |
insertion) | |
insertion = { | |
"id": make_random_id(), | |
"role_id": role_id, | |
"user_id": user_id | |
} | |
columns = insertion.keys() | |
cols_sepd = ", ".join(columns) | |
binds_sepd = ', '.join(['%(' + item + ')s' for item in columns]) | |
c.execute(f"insert into roles_users ({cols_sepd}) values ({binds_sepd})", | |
insertion) | |
db.commit() | |
def run(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--debug', action='store_true', required=False, | |
help='set logging level to INFO') | |
parser.add_argument('--name', required=True, | |
help="Slug to be used as user identifier") | |
parser.add_argument('--username', required=True) | |
parser.add_argument('--password', required=True) | |
parser.add_argument('--location', required=False, | |
default=LOCATION) | |
parser.add_argument('--email', required=True, | |
help="Email address to be used as login name") | |
args = parser.parse_args() | |
if args.debug: | |
logging.getLogger().setLevel(20) | |
main(args) | |
if __name__ == '__main__': | |
run() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment