Ejemplo n.º 1
0
    def send_download_notification(self,
                                   workspace_id,
                                   user_id,
                                   share_id,
                                   inode_id,
                                   commit_id,
                                   pubws_email_id,
                                   login_type=KCD_KWS_LOGIN_TYPE_SECURE,
                                   minor=0,
                                   cmd=""):

        # Build ANP arguments list.
        am = kanp.ANP_msg()
        # Workspace bound arguments
        am.add_u64(workspace_id)
        am.add_u64(int(time.time()))
        am.add_u32(login_type)
        am.add_u32(user_id)
        am.add_u32(minor)
        am.add_bin(cmd)
        # Other arguments
        am.add_u32(share_id)
        am.add_u64(inode_id)
        am.add_u64(commit_id)
        am.add_u64(pubws_email_id)

        # Send notification to KCD database.
        ext_am, res_am = self.workspace_bound_request('notify_file_download',
                                                      am.get_payload())

        log.debug("Download notification posted for workspace %i." % \
            ( workspace_id ) )
Ejemplo n.º 2
0
 def phase_2_create_commit_submessage(self, hash):
     subm = PhaseTwoCommitSubMessage()
     subm.anpm = kanp.ANP_msg()
     subm.anpm.add_u32(3)
     subm.anpm.add_u32(kanp.KANP_KFS_SUBMESSAGE_COMMIT)
     subm.anpm.add_bin(hash)
     return subm
Ejemplo n.º 3
0
    def workspace_bound_request(self, stored_proc_name, args_payload):
        # Connect or reuse DB connection.
        self.db_connect()

        # Do the query.
        query = "SELECT %s('%s')" % (stored_proc_name,
                                     pgdb.escape_bytea(args_payload))
        cur = kpg.exec_pg_query_rb_on_except(self.db_conn, query)
        row = cur.fetchone()
        self.db_conn.commit()

        # Handle result.
        am = kanp.ANP_msg()
        am.parse(row[0].value)

        # Get generic error status.
        error_status = am.get_u32()

        if error_status == -1:
            # Generic error.
            err_msg = am.get_str()
            raise Exception("Error: '%s'." % (err_msg))

        else:
            # No generic error... continue parsing.

            # Get result type.
            res_type = am.get_u32()
            res_buf = am.get_bin()
            res_error = am.get_u32()

            if res_type == kanp.KANP_RES_OK:
                # Success
                ext_buf_am = am
                res_buf_am = kanp.ANP_msg()
                res_buf_am.parse(res_buf)
                return ext_buf_am, res_buf_am

            else:
                # Specific error
                am = kanp.ANP_msg()
                am.parse(res_buf)
                err_code = am.get_u32()
                err_msg = am.get_str()
                raise Exception("Error: '%s' stored procedure failed: error: %i ('%s')" % \
                    ( stored_proc_name, err_code, err_msg ) )
Ejemplo n.º 4
0
 def phase_2_create_chunk_submessage(self, data):
     # Prepare anp message
     subm = PhaseTwoChunkSubMessage()
     subm.anpm = kanp.ANP_msg()
     subm.anpm.add_u32(3)
     subm.anpm.add_u32(kanp.KANP_KFS_SUBMESSAGE_CHUNK)
     subm.anpm.add_bin(data)
     return subm
Ejemplo n.º 5
0
    def connect_workspace(self,
                          workspace_id,
                          last_evt_id=0,
                          last_evt_timestamp=0,
                          user_id=0,
                          real_name='',
                          email_address='',
                          email_id='',
                          ticket='',
                          password='',
                          delete_on_login=0):

        # Create ANP command.
        m = kanp.ANP_msg()
        m.add_u64(workspace_id)
        m.add_u32(delete_on_login)
        m.add_u64(last_evt_id)
        m.add_u64(last_evt_timestamp)
        m.add_u32(user_id)
        m.add_str(real_name)
        m.add_str(email_address)
        m.add_str(email_id)
        m.add_bin(ticket)
        m.add_str(password)

        # Send the command to KCD.
        payload = m.get_payload()
        self.send_command_header(kanp.KANP_CMD_KWS_CONNECT_KWS, len(payload))
        log.debug("Sent anp command to connect to workspace %i." %
                  (workspace_id))
        self.write(payload)
        # Get command result.
        h, m = kanp.get_anpt_all(self)
        if h.type != kanp.KANP_RES_KWS_CONNECT_KWS:
            assert h.type == kanp.KANP_RES_FAIL
            raise kanp.KANPFailure(m.get_u32(), m.get_str())

        # Decode result.
        result = m.get_u32()
        error = m.get_str()
        user_id = m.get_u32()
        email_id = m.get_str()
        last_evt_id = m.get_u64()
        secure = m.get_u32()
        password_assigned = m.get_u32()
        kwmo_server = m.get_str()
        if result != kanp.KANP_KWS_LOGIN_OK:
            raise kanp.KANPFailure(result, error)

        log.debug("Connected to workspace %i." % (workspace_id))
Ejemplo n.º 6
0
    def set_freemium_user(self, email, license):
        # Connect to database if needed.
        self.db_connect()

        # Build ANP arguments list.
        m = kanp.ANP_msg()
        m.add_str(email)
        m.add_str(license)

        # Do the query.
        query = "SELECT set_freemium_user('%s')" % ( pgdb.escape_bytea(m.get_payload()) )
        cur = kpg.exec_pg_query_rb_on_except(self.db_conn, query)
        row = cur.fetchone()
        self.db_conn.commit()

        return 0
Ejemplo n.º 7
0
    def select_role(self, role):
        log.debug("select_role() called")

        # send request
        m = kanp.ANP_msg()
        m.add_u32(role)
        payload = m.get_payload()
        self.send_command_header(kanp.KANP_CMD_MGT_SELECT_ROLE, len(payload))
        self.write(payload)

        # get response
        h, m = kanp.get_anpt_all(self)
        if h.type != kanp.KANP_RES_OK:
            assert h.type == kanp.KANP_RES_FAIL
            raise kanp.KANPFailure(m.get_u32(), m.get_str())
        assert h.type == kanp.KANP_RES_OK
        log.debug("Role %i selected." % (role))
Ejemplo n.º 8
0
    def save_notification_policy(self, workspace_id, user_id,
                                 notification_policy):
        # Connect to database if needed.
        self.db_connect()

        # Build ANP arguments list.
        am = kanp.ANP_msg()
        am.add_u64(int(workspace_id))
        am.add_u32(int(user_id))
        am.add_u32(notification_policy)

        # Do the query.
        query = "SELECT do_notif_mgt(E'%s')" % (pgdb.escape_bytea(
            am.get_payload()))
        cur = kpg.exec_pg_query_rb_on_except(self.db_conn, query)
        row = cur.fetchone()
        self.db_conn.commit()

        return 0
Ejemplo n.º 9
0
    def get_kcd_upload_ticket(self,
                              workspace_id,
                              share_id,
                              user_id,
                              email_id='kwmo'):
        # Connect to KCD.
        self.connect()

        # Select workspace role.
        self.select_role(kanp.KANP_KCD_ROLE_WORKSPACE)

        # Connect to workspace.
        self.connect_workspace(workspace_id=int(workspace_id),
                               user_id=user_id,
                               email_id=email_id,
                               password=self.conf.kcd_passwd)

        # Send the command to KCD.
        am = kanp.ANP_msg()
        am.add_u64(workspace_id)
        am.add_u32(share_id)
        payload = am.get_payload()
        self.send_command_header(kanp.KANP_CMD_KFS_UPLOAD_REQ, len(payload))
        self.write(payload)
        log.debug("Sent upload request to KCD for workspace %i, share %i." %
                  (workspace_id, share_id))

        # Get command result.
        h, m = kanp.get_anpt_all(self)

        # Close KCD connection.
        self.close()

        # Handle result.
        if h.type != kanp.KANP_RES_KFS_UPLOAD_REQ:
            log.debug("Got result type '%s'." %
                      (kanp.get_kanp_constant(h.type, 'KANP_')))
            assert h.type == kanp.KANP_RES_FAIL
            raise kanp.KANPFailure(m.get_u32(), m.get_str())
        ticket = m.get_bin()

        return ticket
Ejemplo n.º 10
0
class FreemiumKcdClient:
    # Constructor
    # parameters:
    #  conf: configuration object, or None
    def __init__(self, conf, db_conn=None):
        # Get config object.
        self.conf = conf

        # Get db connection if provited.
        self.db_conn = db_conn

        # Command ID.
        self.command_id = 0

        # Initialize parent class, but do not connect.
        #tcp_client.TcpClient.__init__(self, self.conf.kcd_host, self.conf.kcd_port, use_openssl=True, allow_dh=True)

    # This method connects or reuse a DB connection to KCD.
    def db_connect(self):
        if not self.db_conn: self.db_conn = get_kcd_db_conn(self.conf)

    def set_freemium_user(self, email, license):
        # Connect to database if needed.
        try:
            self.db_connect()
        except Exception, e:
            raise KcdDbConnectException("Couldn't connect to kcd db: " + str(e))

        # Build ANP arguments list.
        m = kanp.ANP_msg()
        m.add_str(email)
        m.add_str(license)

        # Do the query.
        query = "SELECT set_freemium_user(E'%s')" % ( pgdb.escape_bytea(m.get_payload()) )
        cur = kpg.exec_pg_query_rb_on_except(self.db_conn, query)
        row = cur.fetchone()
        self.db_conn.commit()

        return 0
Ejemplo n.º 11
0
    def send_invitation(self, workspace_id, message, invitees):
        # Create command.
        m = kanp.ANP_msg()
        m.add_u64(workspace_id)
        m.add_str(message)
        m.add_u32(len(invitees))
        for invitee in invitees:
            m.add_str(invitee.real_name)
            m.add_str(invitee.email_address)
            m.add_u64(invitee.key_id)
            m.add_str(invitee.org_name)
            m.add_str(invitee.password)
            m.add_u32(int(invitee.send_mail))

        # Send the command to KCD.
        payload = m.get_payload()
        self.send_command_header(kanp.KANP_CMD_KWS_INVITE_KWS, len(payload))
        log.debug("Sent anp invite command for workspace %i." % (workspace_id))
        self.write(payload)

        # Get command result.
        h, m = kanp.get_anpt_all(self)
        if h.type != kanp.KANP_RES_KWS_INVITE_KWS:
            log.debug("Received type '%s'." % (str(h.type)))
            assert h.type == kanp.KANP_RES_FAIL
            raise kanp.KANPFailure(m.get_u32(), m.get_str())

        # Decode the result.
        ws_url = m.get_str()
        invitees_nb = m.get_u32()
        for i in range(0, invitees_nb):
            invitees[i].email_id = m.get_str()
            invitees[i].url = m.get_str()
            invitees[i].error = m.get_str()

        return ws_url, invitees
Ejemplo n.º 12
0
    def phase_2_send_message_with_one_submessage(self, subm):

        # Prepare ANP message.
        message = PhaseTwoMessage()
        message.anpm = kanp.ANP_msg()
        message.anpm.add_u32(1)  # Send only one sub-message

        # Calculate base messasge size.
        message.size = message.anpm.get_payload_size()
        #log.debug("Base message size: %i bytes." % ( message.size ))

        # Calculate total sub-message size.
        subm.size = subm.anpm.get_payload_size()
        log.debug("Chunk sub-message size: %i bytes." % (subm.size))

        total_size = message.size + subm.size

        # Sent ANP transport header
        #log.debug("Phase 2: sending ANPT header with data size %i." % ( total_size ))
        self.writer.send_command_header(kanp.KANP_CMD_KFS_PHASE_2, total_size)
        #log.debug("Phase 2: sent ANPT header, size %i." % ( total_size ))

        # Send base message.
        kanp.send_anpt_msg(self.writer, message.anpm)

        # Send sub-message.
        kanp.send_anpt_msg(self.writer, subm.anpm)

        # get response
        #log.debug("Phase 2: getting reply.")
        h, m = kanp.get_anpt_all(self.reader)
        #log.debug("ANP RESPONSE DUMP: %s" % (str(m.dump())))
        #log.debug("Phase 2: got reply.")
        if h.type == kanp.KANP_RES_FAIL:
            raise kanp.KANPFailure(m.get_u32(), m.get_str())
        assert h.type == kanp.KANP_RES_OK
Ejemplo n.º 13
0
    def prepare_phase_two(self):
        message = None
        files_iter = iter(self.kfs_entries)
        switch_file = True
        switch_message = True
        commit_file = False
        switch_chunk = True
        exit = False

        while 1:

            if exit or switch_message:
                switch_message = False

                if message and len(message.sub_messages) > 0:
                    # Finish ANPT message preparation.
                    message.anpm = kanp.ANP_msg()
                    message.anpm.add_u32(len(message.sub_messages))
                    message.size += message.anpm.get_payload_size()

                    # Append ANPT message to list.
                    self.phase_two_messages.append(message)

                # Init new ANPT message.
                message = PhaseTwoMessage()

            if exit:
                break

            if commit_file:
                commit_file = False

                # Prepare a file commit sub-message.
                log.debug("Committing file.")

                # Prepare a partial anp message (missing an ANP bin field for the MD5 signature of the file).
                subm = PhaseTwoCommitSubMessage()
                subm.anpm = kanp.ANP_msg()
                subm.anpm.add_u32(3)
                subm.anpm.add_u32(kanp.KANP_KFS_SUBMESSAGE_COMMIT)
                #hash = kfs_compute_hash(kfs_entry.fd)
                #subm.anpm.add_bin(kfs_entry.hash)

                # Calculate total sub-message size.
                subm.size = subm.anpm.get_payload_size(
                ) + 5 + 16  # partial anp mesg + anp bin header + md5 sign.
                log.debug("Commit sub-message has %i bytes in total." %
                          (subm.size))

                # Append sub-message to current ANPT message.
                log.debug("Appending commit sub-message to ANPT message.")
                message.sub_messages.append(subm)
                message.size += subm.size

                # Switch to next file.
                switch_file = True
                continue

            if not message:
                # Init new message.
                log.debug("Initiating a new message.")
                message = PhaseTwoMessage()

            if switch_file:
                switch_file = False

                try:
                    # Get next file.
                    kfs_entry = files_iter.next()
                    log.debug("Got new file: '%s'." % (kfs_entry.name))

                    # Start again with file chunk.
                    chunks_iter = iter(kfs_entry.chunks)
                    switch_chunk = True
                    continue

                except StopIteration:
                    # No more file in list.
                    log.debug("No more file.")

                    exit = True
                    continue

            if kfs_entry.kfs_op != kanp.KANP_KFS_OP_CREATE_FILE and kfs_entry.kfs_op != kanp.KANP_KFS_OP_UPDATE_FILE:
                # That operation does not need any phase 2 messsage.
                log.debug("No phase two needed for that operation.")
                switch_file = True
                continue

            if kfs_entry.kfs_error:
                # This file cannot be uploaded. Pass to next file.
                log.debug("Skipping file '%s' because it had an error in phase 1: '%s'." % \
                    (kfs_entry.name, kfs_entry.kfs_error ))
                switch_file = True
                continue

            if switch_chunk:
                switch_chunk = False

                try:
                    # Get next KFS file chunk.
                    chunk = chunks_iter.next()
                    log.debug("Got a new chunk of %i bytes." % (chunk.size))

                except StopIteration:
                    # No more chunks. Commit file.
                    commit_file = True
                    continue

            # Add chunk to current ANPT message.

            # Prepare a partial anp message (missing an ANP bin field for the chunk data).
            subm = PhaseTwoChunkSubMessage()
            subm.anpm = kanp.ANP_msg()
            subm.anpm.add_u32(3)
            subm.anpm.add_u32(kanp.KANP_KFS_SUBMESSAGE_CHUNK)
            #subm.anpm.add_bin(chunk.read())

            # Set sub-message chunk.
            subm.chunk = chunk

            # Calculate total sub-message size.
            subm.size = subm.anpm.get_payload_size(
            ) + 5 + chunk.size  # partial anp mesg + anp bin header + chunk data
            log.debug("Chunk sub-message has %i bytes in total." % (subm.size))

            if (message.size + subm.size + 100000) > kanp.ANPT_MSG_MAX_SIZE:
                # Current ANPT message cannot accept chunk.

                # Switch ANPT message.
                switch_message = True
                # Do not switch chunk (implicit).
                #switch_chunk = False
                continue

            # Append sub-message to this message.
            log.debug("Appending chunk sub-message to ANPT message.")
            message.sub_messages.append(subm)
            message.size += subm.size

            switch_chunk = True
Ejemplo n.º 14
0
    def phase_one(self, email_id, ticket):

        # Prepare phase one ANP message.
        m = kanp.ANP_msg()
        m.add_bin(ticket)
        m.add_u64(email_id)
        m.add_u32(len(self.kfs_entries))
        for kfs_entry in self.kfs_entries:
            if kfs_entry.kfs_op == kanp.KANP_KFS_OP_CREATE_FILE:
                m.add_u32(5)  # nb of elements
                m.add_u32(kfs_entry.kfs_op)
                m.add_u64(kfs_entry.parent_inode_id)
                m.add_u64(kfs_entry.parent_commit_id)
                m.add_str(kfs_entry.name)

            elif kfs_entry.kfs_op == kanp.KANP_KFS_OP_UPDATE_FILE:
                m.add_u32(4)  # nb of elements
                m.add_u32(kfs_entry.kfs_op)
                m.add_u64(kfs_entry.inode)
                m.add_u64(kfs_entry.commit_id)

            elif kfs_entry.kfs_op == kanp.KANP_KFS_OP_CREATE_DIR:
                m.add_u32(5)  # nb of elements
                m.add_u32(kfs_entry.kfs_op)
                m.add_u64(kfs_entry.parent_inode_id)
                m.add_u64(kfs_entry.parent_commit_id)
                m.add_str(kfs_entry.name)

            elif kfs_entry.kfs_op == kanp.KANP_KFS_OP_DELETE_DIR:
                m.add_u32(4)  # nb of elements
                m.add_u32(kfs_entry.kfs_op)
                m.add_u64(kfs_entry.inode_id)
                m.add_u64(kfs_entry.commit_id)

            elif kfs_entry.kfs_op == kanp.KANP_KFS_OP_DELETE_FILE:
                m.add_u32(4)  # nb of elements
                m.add_u32(kfs_entry.kfs_op)
                m.add_u64(kfs_entry.inode_id)
                m.add_u64(kfs_entry.commit_id)

            else:
                raise Exception("Unexpected KFS operation: '%s'." %
                                (str(kfs_entry.kfs_op)))

        # Send phase one ANP message to KCD.
        payload = m.get_payload()
        self.writer.send_command_header(kanp.KANP_CMD_KFS_PHASE_1,
                                        len(payload))
        self.writer.write(payload)
        log.debug("Phase 1 data sent.")

        # Get phase one result.
        h, m = kanp.get_anpt_all(self.reader)
        if h.type != kanp.KANP_RES_KFS_PHASE_1:
            assert h.type == kanp.KANP_RES_FAIL
            raise kanp.KANPFailure(m.get_u32(), m.get_str())
        log.debug("Got phase 1 reply.")

        # Handle phase one reply.
        phase_two_needed = False
        commit_id = m.get_u64()
        nb_op = m.get_u32()
        assert nb_op == len(self.kfs_entries)
        for i in range(0, nb_op):
            errno = m.get_u32()
            error = m.get_str()
            if error:
                log.debug(
                    "Phase 1: KFS operation %i error: errno=%i, error='%s'" % \
                    ( i, errno, error ))
                self.kfs_entries[i].kfs_error = error