Exemple #1
0
def reencrpyt_server_passwords(user_id, old_key, new_key):
    """
    This function will decrypt the saved passwords in SQLite with old key
    and then encrypt with new key
    """
    from pgadmin.utils.driver import get_driver
    driver = get_driver(config.PG_DEFAULT_DRIVER)

    for server in Server.query.filter_by(user_id=user_id).all():
        manager = driver.connection_manager(server.id)

        _password_check(server, manager, old_key, new_key)

        if server.tunnel_password is not None:
            tunnel_password = decrypt(server.tunnel_password, old_key)
            if isinstance(tunnel_password, bytes):
                tunnel_password = tunnel_password.decode()

            tunnel_password = encrypt(tunnel_password, new_key)
            setattr(server, 'tunnel_password', tunnel_password)
            manager.tunnel_password = tunnel_password
        elif manager.tunnel_password is not None:
            tunnel_password = decrypt(manager.tunnel_password, old_key)

            if isinstance(tunnel_password, bytes):
                tunnel_password = tunnel_password.decode()

            tunnel_password = encrypt(tunnel_password, new_key)
            manager.tunnel_password = tunnel_password

        db.session.commit()
        manager.update_session()
def create_or_update_server(user, server_dict):
    group = server_dict.pop("group")
    name = server_dict.pop("name")
    password = server_dict.pop("password")
    group_id = get_or_create_group_id(group, user)

    base = {"user_id": user.id, "servergroup_id": group_id, "name": name}
    server = Server.query.filter_by(**base).first()
    if server is None:
        server = Server(**base)
        print(
            "Created server {!r} in group {!r} for user {!r}".format(
                name, group, user.email
            )
        )
        db.session.add(server)

    server.password = encrypt(password, user.password)
    server.discovery_id = DISCOVERY_ID

    for attr, value in server_dict.items():
        setattr(server, attr, value)

    commit(
        "Error updating server {} in group {}".format(name, group),
        "Successfully saved.",
    )
    return server
Exemple #3
0
def _password_check(server, manager, old_key, new_key):
    # Check if old password was stored in pgadmin4 sqlite database.
    # If yes then update that password.
    if server.password is not None:
        password = decrypt(server.password, old_key)

        if isinstance(password, bytes):
            password = password.decode()

        password = encrypt(password, new_key)
        setattr(server, 'password', password)
        manager.password = password
Exemple #4
0
def set_masterpass_check_text(password, clear=False):
    """
    Set the encrypted text which will be used later to validate entered key
    :param password: password/key
    :param clear: remove the encrypted text
    """
    try:
        masterpass_check = None
        if not clear:
            masterpass_check = encrypt(MASTERPASS_CHECK_TEXT, password)

        # set the encrypted sample text with the new
        # master pass
        db.session.query(User) \
            .filter(User.id == current_user.id) \
            .update({User.masterpass_check: masterpass_check})
        db.session.commit()

    except Exception as _:
        db.session.rollback()
        raise
Exemple #5
0
    def change_password(self, gid, sid):
        """
        This function is used to change the password of the
        Database Server.

        Args:
            gid: Group id
            sid: Server id
        """
        try:
            data = json.loads(request.form['data'])
            if data and ('password' not in data or
                                 data['password'] == '' or
                                 'newPassword' not in data or
                                 data['newPassword'] == '' or
                                 'confirmPassword' not in data or
                                 data['confirmPassword'] == ''):
                return make_json_response(
                    status=400,
                    success=0,
                    errormsg=gettext(
                        "Couldn't find the required parameter(s)."
                    )
                )

            if data['newPassword'] != data['confirmPassword']:
                return make_json_response(
                    status=200,
                    success=0,
                    errormsg=gettext(
                        "Passwords do not match."
                    )
                )

            # Fetch Server Details
            server = Server.query.filter_by(id=sid).first()
            if server is None:
                return bad_request(gettext("Server not found."))

            # Fetch User Details.
            user = User.query.filter_by(id=current_user.id).first()
            if user is None:
                return unauthorized(gettext("Unauthorized request."))

            from pgadmin.utils.driver import get_driver
            manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
            conn = manager.connection()

            decrypted_password = decrypt(manager.password, user.password)

            if isinstance(decrypted_password, bytes):
                decrypted_password = decrypted_password.decode()

            password = data['password']

            # Validate old password before setting new.
            if password != decrypted_password:
                return unauthorized(gettext("Incorrect password."))

            # Hash new password before saving it.
            password = pqencryptpassword(data['newPassword'], manager.user)

            SQL = render_template("/".join([
                'servers/sql',
                '9.2_plus' if manager.version >= 90200 else '9.1_plus',
                'change_password.sql'
            ]),
                conn=conn, _=gettext,
                user=manager.user, encrypted_password=password)

            status, res = conn.execute_scalar(SQL)

            if not status:
                return internal_server_error(errormsg=res)

            password = encrypt(data['newPassword'], user.password)
            # Check if old password was stored in pgadmin4 sqlite database.
            # If yes then update that password.
            if server.password is not None:
                setattr(server, 'password', password)
                db.session.commit()
            # Also update password in connection manager.
            manager.password = password
            manager.update_session()

            return make_json_response(
                status=200,
                success=1,
                info=gettext(
                    "Password changed successfully."
                )
            )

        except Exception as e:
            return internal_server_error(errormsg=str(e))
Exemple #6
0
    def connect(self, gid, sid):
        """
        Connect the Server and return the connection object.
        Verification Process before Connection:
            Verify requested server.

            Check the server password is already been stored in the
            database or not.
            If Yes, connect the server and return connection.
            If No, Raise HTTP error and ask for the password.

            In case of 'Save Password' request from user, excrypted Pasword
            will be stored in the respected server database and
            establish the connection OR just connect the server and do not
            store the password.
        """
        current_app.logger.info(
            'Connection Request for server#{0}'.format(sid)
        )

        # Fetch Server Details
        server = Server.query.filter_by(id=sid).first()
        if server is None:
            return bad_request(gettext("Server not found."))

        # Fetch User Details.
        user = User.query.filter_by(id=current_user.id).first()
        if user is None:
            return unauthorized(gettext("Unauthorized request."))

        data = request.form if request.form else json.loads(request.data) if \
            request.data else {}

        password = None
        save_password = False

        if 'password' not in data:
            if server.password is None:
                # Return the password template in case password is not
                # provided, or password has not been saved earlier.
                return make_json_response(
                    success=0,
                    status=428,
                    result=render_template(
                        'servers/password.html',
                        server_label=server.name,
                        username=server.username,
                        _=gettext
                    )
                )
        else:
            password = data['password'] if 'password' in data else None
            save_password = \
                data['save_password'] if password and \
                                         'save_password' in data else False

        # Encrypt the password before saving with user's login password key.
        try:
            password = encrypt(password, user.password) \
                if password is not None else server.password
        except Exception as e:
            current_app.logger.exception(e)
            return internal_server_error(errormsg=e.message)

        # Connect the Server
        from pgadmin.utils.driver import get_driver
        manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
        conn = manager.connection()

        try:
            status, errmsg = conn.connect(
                password=password,
                server_types=ServerType.types()
            )
        except Exception as e:
            current_app.logger.exception(e)
            # TODO::
            # Ask the password again (if existing password couldn't be
            # descrypted)
            if e.message:
                return internal_server_error(errormsg=e.message)
            else:
                return internal_server_error(errormsg=str(e))

        if not status:
            current_app.logger.error(
                "Could not connected to server(#{0}) - '{1}'.\nError: {2}".format(
                    server.id, server.name, errmsg
                )
            )

            return make_json_response(
                success=0,
                status=401,
                result=render_template(
                    'servers/password.html',
                    server_label=server.name,
                    username=server.username,
                    errmsg=errmsg,
                    _=gettext
                )
            )
        else:
            if save_password:
                try:
                    # Save the encrypted password using the user's login
                    # password key.
                    setattr(server, 'password', password)
                    db.session.commit()
                except Exception as e:
                    # Release Connection
                    current_app.logger.exception(e)
                    manager.release(database=server.maintenance_db)
                    conn = None

                    return internal_server_error(errormsg=e.message)

            current_app.logger.info('Connection Established for server: \
                %s - %s' % (server.id, server.name))
            # Update the recovery and wal pause option for the server if connected successfully
            status, result = conn.execute_dict("""
                    SELECT CASE WHEN usesuper
                           THEN pg_is_in_recovery()
                           ELSE FALSE
                           END as inrecovery,
                           CASE WHEN usesuper AND pg_is_in_recovery()
                           THEN pg_is_xlog_replay_paused()
                           ELSE FALSE
                           END as isreplaypaused
                    FROM pg_user WHERE usename=current_user""")
            if status:
                in_recovery = result['rows'][0]['inrecovery'];
                wal_paused = result['rows'][0]['isreplaypaused']
            else:
                in_recovery = None
                wal_paused = None

            return make_json_response(
                success=1,
                info=gettext("Server connected."),
                data={
                    'icon': 'icon-{0}'.format(
                        manager.server_type
                    ),
                    'connected': True,
                    'type': manager.server_type,
                    'version': manager.version,
                    'db': manager.db,
                    'user': manager.user_info,
                    'in_recovery': in_recovery,
                    'wal_pause': wal_paused
                }
            )
Exemple #7
0
    def create(self, gid):
        """Add a server node to the settings database"""
        required_args = [
            u'name',
            u'host',
            u'port',
            u'db',
            u'username',
            u'sslmode',
            u'role'
        ]

        data = request.form if request.form else json.loads(request.data.decode())

        for arg in required_args:
            if arg not in data:
                return make_json_response(
                    status=410,
                    success=0,
                    errormsg=gettext(
                        "Could not find the required parameter (%s)." % arg
                    )
                )

        try:
            server = Server(
                user_id=current_user.id,
                servergroup_id=data[u'gid'] if u'gid' in data else gid,
                name=data[u'name'],
                host=data[u'host'],
                port=data[u'port'],
                maintenance_db=data[u'db'],
                username=data[u'username'],
                ssl_mode=data[u'sslmode'],
                comment=data[u'comment'] if u'comment' in data else None,
                role=data[u'role'] if u'role' in data else None
            )
            db.session.add(server)
            db.session.commit()

            connected = False
            icon = "icon-server-not-connected"
            user = None

            if 'connect_now' in data and data['connect_now']:
                from pgadmin.utils.driver import get_driver
                manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(server.id)
                manager.update(server)
                conn = manager.connection()

                if 'password' in data and data["password"] != '':
                    # login with password
                    password = data['password']
                    password = encrypt(password, current_user.password)
                else:
                    # Attempt password less login
                    password = None

                status, errmsg = conn.connect(
                    password=password,
                    server_types=ServerType.types()
                )

                if not status:
                    db.session.delete(server)
                    db.session.commit()
                    return make_json_response(
                        status=401,
                        success=0,
                        errormsg=gettext("Unable to connect to server:\n\n%s" % errmsg)
                    )
                else:
                    user = manager.user_info
                    connected = True
                    icon = "icon-pg"

            return jsonify(
                node=self.blueprint.generate_browser_node(
                    "%d" % server.id, server.servergroup_id,
                    server.name,
                    icon,
                    True,
                    self.node_type,
                    user=user,
                    connected=connected,
                    server_type='pg'  # Default server type
                )
            )

        except Exception as e:
            if server:
                db.session.delete(server)
                db.session.commit()

            current_app.logger.exception(e)
            return make_json_response(
                status=410,
                success=0,
                errormsg=str(e)
            )
Exemple #8
0
    def connect(self, gid, sid):
        """
        Connect the Server and return the connection object.
        Verification Process before Connection:
            Verify requested server.

            Check the server password is already been stored in the
            database or not.
            If Yes, connect the server and return connection.
            If No, Raise HTTP error and ask for the password.

            In case of 'Save Password' request from user, excrypted Pasword
            will be stored in the respected server database and
            establish the connection OR just connect the server and do not
            store the password.
        """
        current_app.logger.info(
            'Connection Request for server#{0}'.format(sid))

        # Fetch Server Details
        server = Server.query.filter_by(id=sid).first()
        if server is None:
            return bad_request(gettext("Server not found."))

        # Fetch User Details.
        user = User.query.filter_by(id=current_user.id).first()
        if user is None:
            return unauthorized(gettext("Unauthorized request."))

        data = request.form if request.form else json.loads(
            request.data, encoding='utf-8') if request.data else {}

        password = None
        passfile = None
        save_password = False

        # Connect the Server
        manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
        conn = manager.connection()

        if 'password' not in data:
            conn_passwd = getattr(conn, 'password', None)
            if conn_passwd is None and server.password is None and \
                    server.passfile is None:
                # Return the password template in case password is not
                # provided, or password has not been saved earlier.
                return make_json_response(success=0,
                                          status=428,
                                          result=render_template(
                                              'servers/password.html',
                                              server_label=server.name,
                                              username=server.username,
                                              _=gettext))
            elif server.passfile and server.passfile != '':
                passfile = server.passfile
            else:
                password = conn_passwd or server.password
        else:
            password = data['password'] if 'password' in data else None
            save_password = \
                data['save_password'] if password and \
                                         'save_password' in data else False

            # Encrypt the password before saving with user's login password key.
            try:
                password = encrypt(password, user.password) \
                    if password is not None else server.password
            except Exception as e:
                current_app.logger.exception(e)
                return internal_server_error(errormsg=e.message)

        status = True
        try:
            status, errmsg = conn.connect(password=password,
                                          passfile=passfile,
                                          server_types=ServerType.types())
        except Exception as e:
            current_app.logger.exception(e)

            return make_json_response(success=0,
                                      status=401,
                                      result=render_template(
                                          'servers/password.html',
                                          server_label=server.name,
                                          username=server.username,
                                          errmsg=getattr(e, 'message', str(e)),
                                          _=gettext))

        if not status:
            if hasattr(str, 'decode'):
                errmsg = errmsg.decode('utf-8')

            current_app.logger.error(
                "Could not connected to server(#{0}) - '{1}'.\nError: {2}".
                format(server.id, server.name, errmsg))

            return make_json_response(success=0,
                                      status=401,
                                      result=render_template(
                                          'servers/password.html',
                                          server_label=server.name,
                                          username=server.username,
                                          errmsg=errmsg,
                                          _=gettext))
        else:
            if save_password and config.ALLOW_SAVE_PASSWORD:
                try:
                    # Save the encrypted password using the user's login
                    # password key.
                    setattr(server, 'password', password)
                    db.session.commit()
                except Exception as e:
                    # Release Connection
                    current_app.logger.exception(e)
                    manager.release(database=server.maintenance_db)
                    conn = None

                    return internal_server_error(errormsg=e.message)

            current_app.logger.info('Connection Established for server: \
                %s - %s' % (server.id, server.name))
            # Update the recovery and wal pause option for the server if connected successfully
            in_recovery, wal_paused = recovery_state(conn, manager.version)

            return make_json_response(success=1,
                                      info=gettext("Server connected."),
                                      data={
                                          'icon':
                                          'icon-{0}'.format(
                                              manager.server_type),
                                          'connected':
                                          True,
                                          'server_type':
                                          manager.server_type,
                                          'type':
                                          manager.server_type,
                                          'version':
                                          manager.version,
                                          'db':
                                          manager.db,
                                          'user':
                                          manager.user_info,
                                          'in_recovery':
                                          in_recovery,
                                          'wal_pause':
                                          wal_paused
                                      })
Exemple #9
0
    def create(self, gid):
        """Add a server node to the settings database"""
        required_args = [
            u'name', u'host', u'port', u'db', u'username', u'sslmode', u'role'
        ]

        data = request.form if request.form else json.loads(request.data,
                                                            encoding='utf-8')

        for arg in required_args:
            if arg not in data:
                return make_json_response(
                    status=410,
                    success=0,
                    errormsg=gettext(
                        "Could not find the required parameter (%s)." % arg))

        if 'hostaddr' in data and data['hostaddr'] != '':
            if not self.pat4.match(data['hostaddr']):
                if not self.pat6.match(data['hostaddr']):
                    return make_json_response(
                        success=0,
                        status=400,
                        errormsg=gettext('Host address not valid'))

        # To check ssl configuration
        is_ssl, data = self.check_ssl_fields(data)

        server = None

        try:
            server = Server(
                user_id=current_user.id,
                servergroup_id=data[u'gid'] if u'gid' in data else gid,
                name=data[u'name'],
                host=data[u'host'],
                hostaddr=data[u'hostaddr'] if u'hostaddr' in data else None,
                port=data[u'port'],
                maintenance_db=data[u'db'],
                username=data[u'username'],
                ssl_mode=data[u'sslmode'],
                comment=data[u'comment'] if u'comment' in data else None,
                role=data[u'role'] if u'role' in data else None,
                db_res=','.join(data[u'db_res'])
                if u'db_res' in data else None,
                sslcert=data['sslcert'] if is_ssl else None,
                sslkey=data['sslkey'] if is_ssl else None,
                sslrootcert=data['sslrootcert'] if is_ssl else None,
                sslcrl=data['sslcrl'] if is_ssl else None,
                sslcompression=1 if is_ssl and data['sslcompression'] else 0)
            db.session.add(server)
            db.session.commit()

            connected = False
            user = None
            manager = None

            if 'connect_now' in data and data['connect_now']:
                manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
                    server.id)
                manager.update(server)
                conn = manager.connection()

                have_password = False
                if 'password' in data and data["password"] != '':
                    # login with password
                    have_password = True
                    passfile = None
                    password = data['password']
                    password = encrypt(password, current_user.password)
                elif 'passfile' in data and data["passfile"] != '':
                    passfile = data['passfile']
                    setattr(server, 'passfile', passfile)
                    db.session.commit()
                else:
                    # Attempt password less login
                    password = None
                    passfile = None

                status, errmsg = conn.connect(password=password,
                                              passfile=passfile,
                                              server_types=ServerType.types())
                if hasattr(str, 'decode') and errmsg is not None:
                    errmsg = errmsg.decode('utf-8')
                if not status:
                    db.session.delete(server)
                    db.session.commit()
                    return make_json_response(
                        status=401,
                        success=0,
                        errormsg=gettext(
                            u"Unable to connect to server:\n\n%s" % errmsg))
                else:
                    if 'save_password' in data and data['save_password'] and \
                            have_password and config.ALLOW_SAVE_PASSWORD:
                        setattr(server, 'password', password)
                        db.session.commit()

                    user = manager.user_info
                    connected = True

            return jsonify(node=self.blueprint.generate_browser_node(
                "%d" % server.id,
                server.servergroup_id,
                server.name,
                'icon-{0}'.format(manager.server_type)
                if manager and manager.server_type else "icon-pg",
                True,
                self.node_type,
                user=user,
                connected=connected,
                server_type=manager.
                server_type if manager and manager.server_type else 'pg'))

        except Exception as e:
            if server:
                db.session.delete(server)
                db.session.commit()

            current_app.logger.exception(e)
            return make_json_response(status=410, success=0, errormsg=str(e))
Exemple #10
0
    def change_password(self, gid, sid):
        """
        This function is used to change the password of the
        Database Server.

        Args:
            gid: Group id
            sid: Server id
        """
        try:
            data = json.loads(request.form['data'], encoding='utf-8')
            if data and ('password' not in data or data['password'] == '' or
                         'newPassword' not in data or data['newPassword'] == ''
                         or 'confirmPassword' not in data
                         or data['confirmPassword'] == ''):
                return make_json_response(
                    status=400,
                    success=0,
                    errormsg=gettext(
                        "Could not find the required parameter(s)."))

            if data['newPassword'] != data['confirmPassword']:
                return make_json_response(
                    status=200,
                    success=0,
                    errormsg=gettext("Passwords do not match."))

            # Fetch Server Details
            server = Server.query.filter_by(id=sid).first()
            if server is None:
                return bad_request(gettext("Server not found."))

            # Fetch User Details.
            user = User.query.filter_by(id=current_user.id).first()
            if user is None:
                return unauthorized(gettext("Unauthorized request."))

            manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
            conn = manager.connection()

            decrypted_password = decrypt(manager.password, user.password)

            if isinstance(decrypted_password, bytes):
                decrypted_password = decrypted_password.decode()

            password = data['password']

            # Validate old password before setting new.
            if password != decrypted_password:
                return unauthorized(gettext("Incorrect password."))

            # Hash new password before saving it.
            password = pqencryptpassword(data['newPassword'], manager.user)

            SQL = render_template(
                "/servers/sql/#{0}#/change_password.sql".format(
                    manager.version),
                conn=conn,
                _=gettext,
                user=manager.user,
                encrypted_password=password)

            status, res = conn.execute_scalar(SQL)

            if not status:
                return internal_server_error(errormsg=res)

            password = encrypt(data['newPassword'], user.password)
            # Check if old password was stored in pgadmin4 sqlite database.
            # If yes then update that password.
            if server.password is not None and config.ALLOW_SAVE_PASSWORD:
                setattr(server, 'password', password)
                db.session.commit()
            # Also update password in connection manager.
            manager.password = password
            manager.update_session()

            return make_json_response(
                status=200,
                success=1,
                info=gettext("Password changed successfully."))

        except Exception as e:
            return internal_server_error(errormsg=str(e))
Exemple #11
0
import config
from pgadmin.utils.crypto import encrypt

from pgadmin.model import db, User, Server

app = create_app(config.APP_NAME)
with app.app_context():
    user = User.query.first()
    key = user.password
    i = 0
    while True:
        i = i + 1
        s = Server()
        sfx = str(i) if i > 1 else ''
        s.name = os.getenv('SETUP_SERVER' + sfx + '_NAME')
        s.host = os.getenv('SETUP_SERVER' + sfx + '_HOST')
        s.port = os.getenv('SETUP_SERVER' + sfx + '_PORT')
        s.username = os.getenv('SETUP_SERVER' + sfx + '_USER')
        if not s.name or not s.host or not s.port or not s.username:
            break
        pwd = os.getenv('SETUP_SERVER' + sfx + '_PASS')
        if pwd:
            s.password = encrypt(pwd, key)
            s.save_password = 1
        s.user_id = user.id
        s.servergroup_id = 1
        s.maintenance_db = 'postgres'
        s.ssl_mode = 'prefer'
        db.session.add(s)
    db.session.commit()
Exemple #12
0
    def create(self, gid):
        """Add a server node to the settings database"""
        required_args = [
            u'name', u'host', u'port', u'db', u'username', u'sslmode', u'role'
        ]

        data = request.form if request.form else json.loads(request.data,
                                                            encoding='utf-8')

        for arg in required_args:
            if arg not in data:
                return make_json_response(
                    status=410,
                    success=0,
                    errormsg=gettext(
                        "Could not find the required parameter (%s)." % arg))

        server = None

        try:
            server = Server(
                user_id=current_user.id,
                servergroup_id=data[u'gid'] if u'gid' in data else gid,
                name=data[u'name'],
                host=data[u'host'],
                port=data[u'port'],
                maintenance_db=data[u'db'],
                username=data[u'username'],
                ssl_mode=data[u'sslmode'],
                comment=data[u'comment'] if u'comment' in data else None,
                role=data[u'role'] if u'role' in data else None)
            db.session.add(server)
            db.session.commit()

            connected = False
            icon = "icon-server-not-connected"
            user = None
            manager = None

            if 'connect_now' in data and data['connect_now']:
                manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
                    server.id)
                manager.update(server)
                conn = manager.connection()

                have_password = False
                if 'password' in data and data["password"] != '':
                    # login with password
                    have_password = True
                    password = data['password']
                    password = encrypt(password, current_user.password)
                else:
                    # Attempt password less login
                    password = None

                status, errmsg = conn.connect(password=password,
                                              server_types=ServerType.types())
                if hasattr(str, 'decode') and errmsg is not None:
                    errmsg = errmsg.decode('utf-8')
                if not status:
                    db.session.delete(server)
                    db.session.commit()
                    return make_json_response(
                        status=401,
                        success=0,
                        errormsg=gettext(
                            u"Unable to connect to server:\n\n%s" % errmsg))
                else:
                    if 'save_password' in data and data[
                            'save_password'] and have_password:
                        setattr(server, 'password', password)
                        db.session.commit()

                    user = manager.user_info
                    connected = True

            return jsonify(node=self.blueprint.generate_browser_node(
                "%d" % server.id,
                server.servergroup_id,
                server.name,
                'icon-{0}'.format(manager.server_type)
                if manager and manager.server_type else "icon-pg",
                True,
                self.node_type,
                user=user,
                connected=connected,
                server_type=manager.
                server_type if manager and manager.server_type else 'pg'))

        except Exception as e:
            if server:
                db.session.delete(server)
                db.session.commit()

            current_app.logger.exception(e)
            return make_json_response(status=410, success=0, errormsg=str(e))
Exemple #13
0
    def connect(self, gid, sid):
        """
        Connect the Server and return the connection object.
        Verification Process before Connection:
            Verify requested server.

            Check the server password is already been stored in the
            database or not.
            If Yes, connect the server and return connection.
            If No, Raise HTTP error and ask for the password.

            In case of 'Save Password' request from user, excrypted Pasword
            will be stored in the respected server database and
            establish the connection OR just connect the server and do not
            store the password.
        """
        current_app.logger.info(
            'Connection Request for server#{0}'.format(sid))

        # Fetch Server Details
        server = Server.query.filter_by(id=sid).first()
        if server is None:
            return bad_request(gettext("Server not found."))

        # Fetch User Details.
        user = User.query.filter_by(id=current_user.id).first()
        if user is None:
            return unauthorized(gettext("Unauthorized request."))

        data = request.form if request.form else json.loads(request.data) if \
            request.data else {}

        password = None
        save_password = False

        if 'password' not in data:
            if server.password is None:
                # Return the password template in case password is not
                # provided, or password has not been saved earlier.
                return make_json_response(success=0,
                                          status=428,
                                          result=render_template(
                                              'servers/password.html',
                                              server_label=server.name,
                                              username=server.username,
                                              _=gettext))
        else:
            password = data['password'] if 'password' in data else None
            save_password = \
                data['save_password'] if password and \
                                         'save_password' in data else False

        # Encrypt the password before saving with user's login password key.
        try:
            password = encrypt(password, user.password) \
                if password is not None else server.password
        except Exception as e:
            current_app.logger.exception(e)
            return internal_server_error(errormsg=e.message)

        # Connect the Server
        from pgadmin.utils.driver import get_driver
        manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
        conn = manager.connection()

        try:
            status, errmsg = conn.connect(password=password,
                                          server_types=ServerType.types())
        except Exception as e:
            current_app.logger.exception(e)
            # TODO::
            # Ask the password again (if existing password couldn't be
            # descrypted)
            if e.message:
                return internal_server_error(errormsg=e.message)
            else:
                return internal_server_error(errormsg=str(e))

        if not status:
            current_app.logger.error(
                "Could not connected to server(#{0}) - '{1}'.\nError: {2}".
                format(server.id, server.name, errmsg))

            return make_json_response(success=0,
                                      status=401,
                                      result=render_template(
                                          'servers/password.html',
                                          server_label=server.name,
                                          username=server.username,
                                          errmsg=errmsg,
                                          _=gettext))
        else:
            if save_password:
                try:
                    # Save the encrypted password using the user's login
                    # password key.
                    setattr(server, 'password', password)
                    db.session.commit()
                except Exception as e:
                    # Release Connection
                    current_app.logger.exception(e)
                    manager.release(database=server.maintenance_db)
                    conn = None

                    return internal_server_error(errormsg=e.message)

            current_app.logger.info('Connection Established for server: \
                %s - %s' % (server.id, server.name))
            # Update the recovery and wal pause option for the server if connected successfully
            status, result = conn.execute_dict("""
                    SELECT CASE WHEN usesuper
                           THEN pg_is_in_recovery()
                           ELSE FALSE
                           END as inrecovery,
                           CASE WHEN usesuper AND pg_is_in_recovery()
                           THEN pg_is_xlog_replay_paused()
                           ELSE FALSE
                           END as isreplaypaused
                    FROM pg_user WHERE usename=current_user""")
            if status:
                in_recovery = result['rows'][0]['inrecovery']
                wal_paused = result['rows'][0]['isreplaypaused']
            else:
                in_recovery = None
                wal_paused = None

            return make_json_response(success=1,
                                      info=gettext("Server connected."),
                                      data={
                                          'icon':
                                          'icon-{0}'.format(
                                              manager.server_type),
                                          'connected':
                                          True,
                                          'type':
                                          manager.server_type,
                                          'version':
                                          manager.version,
                                          'db':
                                          manager.db,
                                          'user':
                                          manager.user_info,
                                          'in_recovery':
                                          in_recovery,
                                          'wal_pause':
                                          wal_paused
                                      })
Exemple #14
0
    def post(self):
        json_dict = {}
        if not current_user:
            json_dict['state'] = "error"
            json_dict['msg'] = "Access denied."
            return jsonify(json_dict)
        else:
            args= request.json.get('params')
            sid = args.get('sid')
            gid = args.get('gid')
            pwd = args.get('pwd')
            save = args.get('save')
            update = args.get('update')
            try:
                pg_server = Server.query.filter_by(
                    id=sid,
                    servergroup_id=gid,
                    user_id=current_user.id
                ).first()
                if not pg_server:
                    json_dict['state'] = "error"
                    json_dict['msg'] = "Server not available in metadata."
                    return jsonify(json_dict)
                else:
                    json_dict['discovery_id'] = pg_server.discovery_id

                manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(int(sid))
                if update:
                    manager.update(pg_server)
                conn = manager.connection()
                if conn.connected():
                    try:
                        cur = conn.conn.cursor()
                        cur.execute(version_query)
                        x = cur.fetchone()[0]
                        cur.close()
                        ver_platform = x.split(",")[0]
                        json_dict['version'] = ver_platform
                        version_info = ver_platform.split()
                        json_dict['pg_version'] = version_info[1]
                        json_dict['state'] = "success"
                        json_dict['msg'] = "Already Connected."
                        return jsonify(json_dict)
                    except Exception as e:
                        pass

                password = ""
                if pwd:
                    password = pwd
                    try:
                        password = encrypt(password, current_user.password)
                    except Exception as e:
                        errmsg = "ERROR: " + str(e)
                        json_dict['state'] = "error"
                        json_dict['msg'] = errmsg
                        return jsonify(json_dict)
                else:
                    if pg_server.password:
                        password=pg_server.password
                    else:
                        json_dict['state'] = "error"
                        json_dict['need_pwd'] = True
                        json_dict['msg'] = "Password required."
                        return jsonify(json_dict)
                status = True
                try:
                    status, errmsg = conn.connect(
                        password=password,
                        server_types=ServerType.types()
                    )
                except Exception as e:
                    errmsg = "ERROR: " + str(e)
                    json_dict['state'] = "error"
                    json_dict['msg'] = errmsg
                    return jsonify(json_dict)
                if not status:
                    emsg = errmsg.split("\n")
                    if len(emsg)>1:
                        if emsg[0] == emsg[1]:
                            errmsg = emsg[0]
                    if hasattr(str, 'decode'):
                        errmsg = errmsg.decode('utf-8')
                    if errmsg.find("timeout expired") >= 0:
                        errmsg = "Connection timed out."
                    json_dict['state'] = "error"
                    json_dict['msg'] = errmsg
                    if errmsg.find("password authentication failed")>=0:
                        json_dict['need_pwd'] = True
                    return jsonify(json_dict)
                else:
                    manager.update_session()
                    cur = conn.conn.cursor()
                    cur.execute(version_query)
                    x = cur.fetchone()[0]
                    cur.close()
                    ver_platform = x.split(",")[0]
                    json_dict['version'] = ver_platform
                    version_info = ver_platform.split()
                    json_dict['pg_version'] = version_info[1]
                    json_dict['msg'] = "connected sucessfully"
                    if save and pwd:
                        pg_server.password = password
                        db.session.commit()

            except Exception as e:
                errmsg = "ERROR: " + str(e)
                json_dict['state'] = "error"
                json_dict['msg'] = errmsg
            return jsonify(json_dict)