Exemplo n.º 1
0
 def register_preferences(self):
     """
     register_preferences
     Override it so that - it does not register the show_node preference for
     server type.
     """
     ServerType.register_preferences()
Exemplo n.º 2
0
 def register_preferences(self):
     """
     register_preferences
     Override it so that - it does not register the show_node preference for
     server type.
     """
     ServerType.register_preferences()
Exemplo n.º 3
0
    def _restore(self, data):
        """
        Helps restoring to reconnect the auto-connect connections smoothly on
        reload/restart of the app server..
        """
        # restore server version from flask session if flask server was
        # restarted. As we need server version to resolve sql template paths.
        from pgadmin.browser.server_groups.servers.types import ServerType

        self.ver = data.get('ver', None)
        self.sversion = data.get('sversion', None)

        if self.ver and not self.server_type:
            for st in ServerType.types():
                if st.instanceOf(self.ver):
                    self.server_type = st.stype
                    self.server_cls = st
                    break

        # Hmm.. we will not honour this request, when I already have
        # connections
        if len(self.connections) != 0:
            return

        # We need to know about the existing server variant supports during
        # first connection for identifications.
        self.pinged = datetime.datetime.now()
        try:
            if 'password' in data and data['password']:
                data['password'] = data['password'].encode('utf-8')
        except Exception as e:
            current_app.logger.exception(e)

        connections = data['connections']
        for conn_id in connections:
            conn_info = connections[conn_id]
            conn = self.connections[conn_info['conn_id']] = Connection(
                self, conn_info['conn_id'], conn_info['database'],
                conn_info['auto_reconnect'], conn_info['async'],
                use_binary_placeholder=conn_info['use_binary_placeholder'],
                array_to_string=conn_info['array_to_string']
            )

            # only try to reconnect if connection was connected previously and
            # auto_reconnect is true.
            if conn_info['wasConnected'] and conn_info['auto_reconnect']:
                try:
                    conn.connect(
                        password=data['password'],
                        server_types=ServerType.types()
                    )
                    # This will also update wasConnected flag in connection so
                    # no need to update the flag manually.
                except Exception as e:
                    current_app.logger.exception(e)
                    self.connections.pop(conn_info['conn_id'])
Exemplo n.º 4
0
    def _restore(self, data):
        """
        Helps restoring to reconnect the auto-connect connections smoothly on
        reload/restart of the app server..
        """
        # Hmm.. we will not honour this request, when I already have
        # connections
        if len(self.connections) != 0:
            return

        # We need to know about the existing server variant supports during
        # first connection for identifications.
        from pgadmin.browser.server_groups.servers.types import ServerType
        self.pinged = datetime.datetime.now()

        connections = data['connections']
        for conn_id in connections:
            conn_info = connections[conn_id]
            conn = self.connections[conn_info['conn_id']] = Connection(
                self, conn_info['conn_id'], conn_info['database'], True,
                conn_info['async'])

            try:
                conn.connect(password=data['password'],
                             server_types=ServerType.types())
            except Exception as e:
                current_app.logger.exception(e)
                self.connections.pop(conn_info['conn_id'])
Exemplo n.º 5
0
    def supported_servers(self, **kwargs):
        """
        This property defines (if javascript) exists for this node.
        Override this property for your own logic.
        """

        return make_response(
            render_template("servers/supported_servers.js",
                            server_types=ServerType.types()), 200,
            {'Content-Type': 'application/x-javascript'})
Exemplo n.º 6
0
    def _get_server_type(self):
        """
        Get server type and server cls.
        :return:
        """
        from pgadmin.browser.server_groups.servers.types import ServerType

        if self.ver and not self.server_type:
            for st in ServerType.types():
                if st.instance_of(self.ver):
                    self.server_type = st.stype
                    self.server_cls = st
                    break
Exemplo n.º 7
0
    def csssnippets(self):
        """
        Returns a snippet of css to include in the page
        """
        snippets = [render_template("css/servers.css")]

        for submodule in self.submodules:
            snippets.extend(submodule.csssnippets)

        for st in ServerType.types():
            snippets.extend(st.csssnippets)

        return snippets
Exemplo n.º 8
0
    def csssnippets(self):
        """
        Returns a snippet of css to include in the page
        """
        snippets = [render_template("css/servers.css")]

        for submodule in self.submodules:
            snippets.extend(submodule.csssnippets)

        for st in ServerType.types():
            snippets.extend(st.csssnippets)

        return snippets
Exemplo n.º 9
0
    def module_js(self, **kwargs):
        """
        This property defines (if javascript) exists for this node.
        Override this property for your own logic.
        """
        username = '******'
        if config.SERVER_MODE is True:
            username = current_user.email.split('@')[0]

        return make_response(
            render_template(
                "servers/servers.js",
                server_types=ServerType.types(),
                _=gettext,
                username=username,
            ), 200, {'Content-Type': 'application/x-javascript'})
Exemplo n.º 10
0
    def module_js(self, **kwargs):
        """
        This property defines (if javascript) exists for this node.
        Override this property for your own logic.
        """
        username = '******'
        if config.SERVER_MODE is True:
            username = current_user.email.split('@')[0]

        return make_response(
            render_template(
                "servers/servers.js",
                server_types=ServerType.types(),
                _=gettext,
                username=username,
            ),
            200, {'Content-Type': 'application/x-javascript'}
        )
Exemplo n.º 11
0
    def _check_and_reconnect_server(self, conn, conn_info, data):
        """
        Check and try to reconnect the server if server previously connected
        and auto_reconnect is true.
        :param conn:
        :type conn:
        :param conn_info:
        :type conn_info:
        :param data:
        :type data:
        :return:
        :rtype:
        """
        from pgadmin.browser.server_groups.servers.types import ServerType
        if conn_info['wasConnected'] and conn_info['auto_reconnect']:
            try:
                # Check SSH Tunnel needs to be created
                if self.use_ssh_tunnel == 1 and \
                        not self.tunnel_created:
                    status, error = self.create_ssh_tunnel(
                        data['tunnel_password'])

                    # Check SSH Tunnel is alive or not.
                    self.check_ssh_tunnel_alive()

                conn.connect(
                    password=data['password'],
                    server_types=ServerType.types()
                )
                # This will also update wasConnected flag in
                # connection so no need to update the flag manually.
            except CryptKeyMissing:
                # maintain the status as this will help to restore once
                # the key is available
                conn.wasConnected = conn_info['wasConnected']
                conn.auto_reconnect = conn_info['auto_reconnect']
            except Exception as e:
                current_app.logger.exception(e)
                self.connections.pop(conn_info['conn_id'])
                raise
Exemplo n.º 12
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
                }
            )
Exemplo n.º 13
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)
            )
Exemplo n.º 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)
Exemplo n.º 15
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
                                      })
Exemplo n.º 16
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
                                      })
Exemplo n.º 17
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))
Exemplo n.º 18
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))
Exemplo n.º 19
0
    def _restore(self, data):
        """
        Helps restoring to reconnect the auto-connect connections smoothly on
        reload/restart of the app server..
        """
        # restore server version from flask session if flask server was
        # restarted. As we need server version to resolve sql template paths.
        from pgadmin.browser.server_groups.servers.types import ServerType

        self.ver = data.get('ver', None)
        self.sversion = data.get('sversion', None)

        if self.ver and not self.server_type:
            for st in ServerType.types():
                if st.instanceOf(self.ver):
                    self.server_type = st.stype
                    self.server_cls = st
                    break

        # Hmm.. we will not honour this request, when I already have
        # connections
        if len(self.connections) != 0:
            return

        # We need to know about the existing server variant supports during
        # first connection for identifications.
        self.pinged = datetime.datetime.now()
        try:
            if 'password' in data and data['password']:
                data['password'] = data['password'].encode('utf-8')
            if 'tunnel_password' in data and data['tunnel_password']:
                data['tunnel_password'] = \
                    data['tunnel_password'].encode('utf-8')
        except Exception as e:
            current_app.logger.exception(e)

        connections = data['connections']
        for conn_id in connections:
            conn_info = connections[conn_id]
            conn = self.connections[conn_info['conn_id']] = Connection(
                self, conn_info['conn_id'], conn_info['database'],
                conn_info['auto_reconnect'], conn_info['async_'],
                use_binary_placeholder=conn_info['use_binary_placeholder'],
                array_to_string=conn_info['array_to_string']
            )

            # only try to reconnect if connection was connected previously and
            # auto_reconnect is true.
            if conn_info['wasConnected'] and conn_info['auto_reconnect']:
                try:
                    # Check SSH Tunnel needs to be created
                    if self.use_ssh_tunnel == 1 and not self.tunnel_created:
                        status, error = self.create_ssh_tunnel(
                            data['tunnel_password'])

                        # Check SSH Tunnel is alive or not.
                        self.check_ssh_tunnel_alive()

                    conn.connect(
                        password=data['password'],
                        server_types=ServerType.types()
                    )
                    # This will also update wasConnected flag in connection so
                    # no need to update the flag manually.
                except Exception as e:
                    current_app.logger.exception(e)
                    self.connections.pop(conn_info['conn_id'])
Exemplo n.º 20
0
    def _restore(self, data):
        """
        Helps restoring to reconnect the auto-connect connections smoothly on
        reload/restart of the app server..
        """
        # restore server version from flask session if flask server was
        # restarted. As we need server version to resolve sql template paths.
        masterpass_processed = process_masterpass_disabled()

        # The data variable is a copy so is not automatically synced
        # update here
        if masterpass_processed and 'password' in data:
            data['password'] = None
        if masterpass_processed and 'tunnel_password' in data:
            data['tunnel_password'] = None

        from pgadmin.browser.server_groups.servers.types import ServerType

        self.ver = data.get('ver', None)
        self.sversion = data.get('sversion', None)

        if self.ver and not self.server_type:
            for st in ServerType.types():
                if st.instanceOf(self.ver):
                    self.server_type = st.stype
                    self.server_cls = st
                    break

        # We need to know about the existing server variant supports during
        # first connection for identifications.
        self.pinged = datetime.datetime.now()
        try:
            if 'password' in data and data['password']:
                if hasattr(data['password'], 'encode'):
                    data['password'] = data['password'].encode('utf-8')
            if 'tunnel_password' in data and data['tunnel_password']:
                data['tunnel_password'] = \
                    data['tunnel_password'].encode('utf-8')
        except Exception as e:
            current_app.logger.exception(e)

        connections = data['connections']

        with connection_restore_lock:
            for conn_id in connections:
                conn_info = connections[conn_id]
                if conn_info['conn_id'] in self.connections:
                    conn = self.connections[conn_info['conn_id']]
                else:
                    conn = self.connections[conn_info['conn_id']] = Connection(
                        self,
                        conn_info['conn_id'],
                        conn_info['database'],
                        conn_info['auto_reconnect'],
                        conn_info['async_'],
                        use_binary_placeholder=conn_info[
                            'use_binary_placeholder'],
                        array_to_string=conn_info['array_to_string'])

                # only try to reconnect if connection was connected previously
                # and auto_reconnect is true.
                if conn_info['wasConnected'] and conn_info['auto_reconnect']:
                    try:
                        # Check SSH Tunnel needs to be created
                        if self.use_ssh_tunnel == 1 and \
                           not self.tunnel_created:
                            status, error = self.create_ssh_tunnel(
                                data['tunnel_password'])

                            # Check SSH Tunnel is alive or not.
                            self.check_ssh_tunnel_alive()

                        conn.connect(password=data['password'],
                                     server_types=ServerType.types())
                        # This will also update wasConnected flag in
                        # connection so no need to update the flag manually.
                    except CryptKeyMissing:
                        # maintain the status as this will help to restore once
                        # the key is available
                        conn.wasConnected = conn_info['wasConnected']
                        conn.auto_reconnect = conn_info['auto_reconnect']
                    except Exception as e:
                        current_app.logger.exception(e)
                        self.connections.pop(conn_info['conn_id'])
                        raise