def create_token(
    username, ttl=None, metadata=None, add_missing_user=True, service=False
):
    """
    :param username: Username of the user to create the token for. If the account for this user
                     doesn't exist yet it will be created.
    :type username: ``str``

    :param ttl: Token TTL (in seconds).
    :type ttl: ``int``

    :param metadata: Optional metadata to associate with the token.
    :type metadata: ``dict``

    :param add_missing_user: Add the user given by `username` if they don't exist
    :type  add_missing_user: ``bool``

    :param service: True if this is a service (non-user) token.
    :type service: ``bool``
    """

    if ttl:
        # Note: We allow arbitrary large TTLs for service tokens.
        if not service and ttl > cfg.CONF.auth.token_ttl:
            msg = "TTL specified %s is greater than max allowed %s." % (
                ttl,
                cfg.CONF.auth.token_ttl,
            )
            raise TTLTooLargeException(msg)
    else:
        ttl = cfg.CONF.auth.token_ttl

    if username:
        try:
            User.get_by_name(username)
        except:
            if add_missing_user:
                user_db = UserDB(name=username)
                User.add_or_update(user_db)

                extra = {"username": username, "user": user_db}
                LOG.audit('Registered new user "%s".' % (username), extra=extra)
            else:
                raise UserNotFoundError()

    token = uuid.uuid4().hex
    expiry = date_utils.get_datetime_utc_now() + datetime.timedelta(seconds=ttl)
    token = TokenDB(
        user=username, token=token, expiry=expiry, metadata=metadata, service=service
    )
    Token.add_or_update(token)

    username_string = username if username else "an anonymous user"
    token_expire_string = isotime.format(expiry, offset=False)
    extra = {"username": username, "token_expiration": token_expire_string}

    LOG.audit(
        'Access granted to "%s" with the token set to expire at "%s".'
        % (username_string, token_expire_string),
        extra=extra,
    )

    return token

    :param username: Username of the user to create the token for. If the account for this user
                     doesn't exist yet it will be created.
    :type username: ``str``

    :param ttl: Token TTL (in seconds).
    :type ttl: ``int``

    :param metadata: Optional metadata to associate with the token.
    :type metadata: ``dict``

    :param add_missing_user: Add the user given by `username` if they don't exist
    :type  add_missing_user: ``bool``

    :param service: True if this is a service (non-user) token.
    :type service: ``bool``
    
st2common/st2common/services/access.py