Skip to content

Instantly share code, notes, and snippets.

@mk270
Created August 7, 2021 20:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mk270/e7f805f326d017cfe469023528b200aa to your computer and use it in GitHub Desktop.
Save mk270/e7f805f326d017cfe469023528b200aa to your computer and use it in GitHub Desktop.
A tool for adding Ghost CMS users from the command line
#!/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