Skip to content

Add password expiration method to the security plugin #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added security/__init__.py
Empty file.
79 changes: 79 additions & 0 deletions security/expire.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
def show_password_expire(show_expired=True, session=None):
import mysqlsh
shell = mysqlsh.globals.shell

if session is None:
session = shell.get_session()
if session is None:
print("No session specified. Either pass a session object to this "
"function or connect the shell to a database")
return
stmt = "select @@default_password_lifetime, @@disconnect_on_expired_password"
result = session.run_sql(stmt)
rows = result.fetch_all()
if rows[0][0] == 0:
print "Default password doesn't expire"
else:
print "Default password expires in %d days" % rows[0][0]
if rows[0][1] == 1:
print "On expired password disconnect"
if show_expired:
stmt = """select concat(sys.quote_identifier(user),'@',sys.quote_identifier(host))
AS user,
password_last_changed, IF((cast(
IFNULL(password_lifetime, @@default_password_lifetime) as signed)
+ cast(datediff(password_last_changed, now()) as signed) > 0),
concat(
cast(
IFNULL(password_lifetime, @@default_password_lifetime) as signed)
+ cast(datediff(password_last_changed, now()) as signed), ' days'),
IF(@@default_password_lifetime > 0, 'expired', 'do not expire')) expires_in
from mysql.user
where
user not like 'mysql.%' order by user"""
else:
stmt = """select concat(sys.quote_identifier(user),'@',sys.quote_identifier(host))
AS user,
password_last_changed,
concat(
cast(
IFNULL(password_lifetime, @@default_password_lifetime) as signed)
+ cast(datediff(password_last_changed, now()) as signed), ' days') expires_in
from mysql.user
where
cast(
IFNULL(password_lifetime, @@default_password_lifetime) as signed)
+ cast(datediff(password_last_changed, now()) as signed) > 0
and user not like 'mysql.%' order by user;"""

result = session.run_sql(stmt)
shell.dump_rows(result)


def show_password_expire_soon(expire_in_days=30, session=None):
import mysqlsh
shell = mysqlsh.globals.shell

if session is None:
session = shell.get_session()
if session is None:
print("No session specified. Either pass a session object to this "
"function or connect the shell to a database")
return
stmt = """select concat(sys.quote_identifier(user),'@',sys.quote_identifier(host))
AS user,
password_last_changed,
concat(
cast(
IFNULL(password_lifetime, @@default_password_lifetime) as signed)
+ cast(datediff(password_last_changed, now()) as signed), ' days') expires_in
from mysql.user
where
cast(
IFNULL(password_lifetime, @@default_password_lifetime) as signed)
+ cast(datediff(password_last_changed, now()) as signed) BETWEEN 1 and {limit}
and user not like 'mysql.%' order by user;""".format(limit=expire_in_days)

result = session.run_sql(stmt)
shell.dump_rows(result)

85 changes: 84 additions & 1 deletion security/init.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,85 @@
# init.py
# security/init.py
# --------------
# Initializes the security plugins.

# Contents
# --------
# This plugin will define the following functions

# Example
# -------

# MySQL 8.0.16 > > localhost:33060+ > > 2019-06-26 18:48:48 >
# JS> ext.security.showPasswordExpire()
# +-------------------------------------------------------------------+-----------------------+------------+
# | concat(sys.quote_identifier(user),'@',sys.quote_identifier(host)) | password_last_changed | expires_in |
# +-------------------------------------------------------------------+-----------------------+------------+
# | `demo`@`%` | 2019-05-21 12:25:58 | expired |
# | `fred`@`%` | 2019-02-07 11:09:01 | expired |
# | `root`@`localhost` | 2019-02-07 11:07:29 | expired |
# +-------------------------------------------------------------------+-----------------------+------------+
# MySQL 8.0.16 > > localhost:33060+ > > 2019-06-26 18:48:50 >
# JS> ext.security.showPasswordExpire(true)
# +-------------------------------------------------------------------+-----------------------+------------+
# | concat(sys.quote_identifier(user),'@',sys.quote_identifier(host)) | password_last_changed | expires_in |
# +-------------------------------------------------------------------+-----------------------+------------+
# | `demo`@`%` | 2019-05-21 12:25:58 | expired |
# | `fred`@`%` | 2019-02-07 11:09:01 | expired |
# | `root`@`localhost` | 2019-02-07 11:07:29 | expired |
# +-------------------------------------------------------------------+-----------------------+------------+
# MySQL 8.0.16 > > localhost:33060+ > > 2019-06-26 18:48:58 >
# JS> ext.security.showPasswordExpire(false)


from ext.mysqlsh_plugins_common import register_plugin
from ext.security import expire as security_expire

register_plugin("showPasswordExpire", security_expire.show_password_expire,
{
"brief": "Lists all accounts and their expiration date",
"parameters": [
{
"name": "show_expire",
"brief": "List expired passwords too",
"type": "bool",
"required": False
},
{
"name": "session",
"brief": "The session to be used on the operation.",
"type": "object",
"classes": ["Session", "ClassicSession"],
"required": False
}
]
},
"security",
{
"brief": "Security management and utilities.",
"details": [
"A collection of security management tools and related "
"utilities"
]
})

register_plugin("showPasswordExpireSoon", security_expire.show_password_expire_soon,
{
"brief": "Lists all accounts that will expire in specific days",
"parameters": [
{
"name": "expire_in_days",
"brief": "List accounts that will expire in that range upper limit, if none provided, the default is 30",
"type": "bool",
"required": False
},
{
"name": "session",
"brief": "The session to be used on the operation.",
"type": "object",
"classes": ["Session", "ClassicSession"],
"required": False
}
]
},
"security"
)