Esempio n. 1
0
class BurpExtender(IBurpExtender, IScannerListener, IContextMenuFactory,
                   ActionListener, ITab, IHttpService, IScanIssue,
                   IBurpExtenderCallbacks):
    def __init__(self):
        self.msgrel = False
        self.project = False
        self.projectId = None
        print("[+] Carregando GAT CORE Extension...")

    def registerExtenderCallbacks(self, callbacks):
        """
        registrar classes
        """
        self._callbacks = callbacks
        self._helpers = self._callbacks.getHelpers()
        self._callbacks.setExtensionName("GAT CORE Integration")

        self.gui_elements = self.build_gui()
        callbacks.customizeUiComponent(self.gui_elements)
        callbacks.addSuiteTab(self)

        self._callbacks.registerContextMenuFactory(self)
        self._callbacks.registerScannerListener(self)

        save_setting = self._callbacks.saveExtensionSetting
        save_setting('project_id', None)

        self.reload_config()
        print("[+] GAT CORE Extension carregado!")

    def newScanIssue(self, issue):
        print("[+] Issue encontrada (%s)" % issue.getIssueName())
        return

    def actionTarget(self, event):
        print("*" * 80)

        self.fileId = []
        requestResponses = self.invocation.getSelectedMessages()
        chosts, ihosts = self.countHostIssues(requestResponses)

        if self.project <= 1:
            panelinput = JPanel()
            panelinput.add(JLabel("Projeto ID: "))
            projectq = JTextField(20)
            panelinput.add(projectq)

            result = JOptionPane.showOptionDialog(
                None, panelinput, "Qual projeto enviar Issues?",
                JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, None,
                ["OK", "Sem projeto"], "OK")

            if result == -1:
                print("[-] Cancelado envio!")
                return

            if result == JOptionPane.OK_OPTION:
                self.project_id.setText(projectq.getText())
                self.projectId = str(projectq.getText())
                if not re.match('([0-9a-f]{24})', self.projectId):
                    self.projectId = None
                    mess = "Projeto Id formato inválido".decode("utf8")
                    JOptionPane.showMessageDialog(None, mess, "Error",
                                                  JOptionPane.ERROR_MESSAGE)

                    return

                mess = "Sessão atual".decode("utf8")
                ever = JOptionPane.showOptionDialog(
                    None, "Solicitar Id de Projeto novamente?", mess,
                    JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
                    None, ["Nunca", "Sim"], "Sim")

                # let user select parameters for new session
                if ever == JOptionPane.OK_OPTION:
                    self.project = 2
                else:
                    self.project = 1

        for reqResp in requestResponses:
            url = reqResp.getHttpService()
            requestIssues = self._callbacks.getScanIssues(str(url))
            listIssues = []

            if requestIssues:
                if len(requestIssues) > 0:
                    for i in requestIssues:
                        scanissue = i
                        if scanissue.getIssueName() not in ['']:
                            sep = "<br><hr><br>"
                            issue = {}
                            issue['Tool_Type'] = "BURP"
                            IssueType = scanissue.getIssueType()
                            IssueName = scanissue.getIssueName()
                            IssueCrit = scanissue.getSeverity()
                            IssueConf = scanissue.getConfidence()
                            protocol = scanissue.getHttpService().getProtocol()
                            host = scanissue.getHttpService().getHost()
                            IssuePath = i.getUrl().getPath()
                            IssueDesc = scanissue.getIssueDetail()
                            IssueDescBk = scanissue.getIssueBackground()
                            IssueRecom = scanissue.getRemediationDetail()
                            IssueRecomBk = scanissue.getRemediationBackground()

                            if IssueType:
                                issue['IssueType'] = scanissue.getIssueType()
                            else:
                                issue['IssueType'] = 0000

                            if IssueName:
                                issue['DetailsFinding_Title'] = IssueName
                                issue['Recomenation_Title'] = IssueName
                            else:
                                issue['DetailsFinding_Title'] = "No Issue name"
                                issue['Recomenation_Title'] = "No Issue name"

                            if "False positive" in IssueCrit:
                                sTag = "False positive"
                                IssueCrit = ""
                            elif "Information" in IssueCrit:
                                IssueCrit = "Informative"
                                sTag = ""
                            else:
                                sTag = ""

                            if IssueCrit:
                                issue['Severity'] = IssueCrit
                            else:
                                issue['Severity'] = "Informative"

                            issue['Web_Application_URI'] = "{}://{}".format(
                                protocol, host)

                            if IssuePath:
                                issue['Web_Application_Path'] = IssuePath
                            else:
                                issue['Web_Application_Path'] = "/"

                            if IssueConf:
                                issue['fTag'] = IssueConf
                            else:
                                issue['fTag'] = " "

                            issue['sTag'] = sTag

                            if IssueDescBk is not None:
                                issue['Description'] = IssueDescBk.replace(
                                    "\n", "")
                            else:
                                issue['Description'] = ""

                            if IssueDesc is not None:
                                issue['Description'] += "{}{}".format(
                                    sep, IssueDesc.replace("\n", ""))

                            if IssueRecomBk is not None:
                                issue['Recommendation'] = IssueRecomBk.replace(
                                    "\n", "")
                            else:
                                issue['Recommendation'] = IssueName

                            if IssueRecom is not None:
                                issue['Recommendation'] += "{}{}".format(
                                    sep, IssueRecom.replace("\n", ""))

                            listIssues.append(issue)

                    self.generateReportGat(listIssues)

        # iniciar threads
        print("[+] Thread(s) Iniciada(s)...")
        if self.project:
            print("[+] Enviando Issues para o Project Id: {}".format(
                self.projectId))
        print("[+] Enviando {} host(s), total de {} Issue(s),\n".format(
            chosts, ihosts))
        self.launchThread(self.sendIssues)

    def actionScanner(self):
        pass

    def createMenuItems(self, invocation):
        self.invocation = invocation
        context = invocation.getInvocationContext()
        if context in [invocation.CONTEXT_TARGET_SITE_MAP_TREE]:
            sendToGAT = JMenuItem("Enviar Issues para GAT CORE")

            # sendToGAT.setForeground(Color.ORANGE)
            FONT = sendToGAT.getFont()
            sendToGAT.setFont(
                Font(FONT.getFontName(), Font.BOLD, FONT.getSize()))

            sendToGAT.addActionListener(self.actionTarget)

            menuItems = ArrayList()
            menuItems.add(sendToGAT)
            return menuItems

        else:
            # TODO: add support for other tools
            pass

    def build_gui(self):
        """Construct GUI elements."""

        Mpanel = JPanel()
        # Mpanel.setLayout(GridLayout(0, 3))
        Mpanel.setLayout(BoxLayout(Mpanel, BoxLayout.X_AXIS))

        panel = JPanel()
        panel.setLayout(None)

        Mpanel.add(Box.createVerticalGlue())
        Mpanel.add(panel)
        Mpanel.add(Box.createVerticalGlue())

        img = os.path.abspath("gat_logo_sticky.png")

        logo = JLabel(ImageIcon(img))
        logo.setBounds(150, 40, 165, 49)

        save_btn = JButton('Salvar', actionPerformed=self.save_config)
        save_btn.setBounds(100, 240, 75, 30)
        save_btn.setPreferredSize(Dimension(75, 30))

        limpar_btn = JButton('Limpar ID Projeto',
                             actionPerformed=self.clsProjectId)
        limpar_btn.setBounds(250, 240, 150, 30)
        limpar_btn.setPreferredSize(Dimension(150, 30))

        label_h = JLabel('API Url:')
        label_h.setHorizontalAlignment(SwingConstants.RIGHT)
        label_h.setBounds(0, 120, 95, 30)
        label_h.setPreferredSize(Dimension(100, 30))

        self.host_api = JTextField(50)
        self.host_api.setBounds(100, 120, 300, 30)
        self.host_api.setPreferredSize(Dimension(250, 30))

        label_a = JLabel('API Token:')
        label_a.setHorizontalAlignment(SwingConstants.RIGHT)
        label_a.setBounds(0, 160, 95, 30)
        label_a.setPreferredSize(Dimension(100, 30))

        self.api_token = JTextField(50)
        self.api_token.setBounds(100, 160, 300, 30)
        self.api_token.setPreferredSize(Dimension(250, 30))

        label_p = JLabel('Project ID:')
        label_p.setHorizontalAlignment(SwingConstants.RIGHT)
        label_p.setBounds(0, 200, 95, 30)
        label_p.setPreferredSize(Dimension(100, 30))

        self.project_id = JTextField(50)
        self.project_id.setForeground(Color.orange)
        self.project_id.setBackground(Color.gray)
        self.project_id.setBounds(100, 200, 300, 30)
        self.project_id.setPreferredSize(Dimension(250, 30))
        self.project_id.editable = False

        panel.add(logo)
        panel.add(label_h)
        panel.add(self.host_api)
        panel.add(label_a)
        panel.add(self.api_token)
        panel.add(label_p)
        panel.add(self.project_id)
        panel.add(limpar_btn)
        panel.add(save_btn)

        return Mpanel

    def save_config(self, _):
        """Save settings."""
        url = self.host_api.getText()
        token = self.api_token.getText()

        if re.match('https?://', url):
            url = re.sub('https?://', '', url)

        if url[-1:] == "/":
            url = url[:-1]

        if re.match('^(?i)Bearer ', token):
            token = re.sub('^(?i)Bearer ', '', token)

        if not re.match(
                '([a-f\d]{8})-([a-f\d]{4})-([a-f\d]{4})-([a-f\d]{4})-([a-f\d]{12})',
                token):
            JOptionPane.showMessageDialog(None, "Formato de TOKEN invalido!",
                                          "Error", JOptionPane.ERROR_MESSAGE)
            return

        save_setting = self._callbacks.saveExtensionSetting
        save_setting('host_api', url)
        save_setting('api_token', token)
        self.msgrel = True
        self.reload_config()
        return

    def reload_config(self):
        """Reload settings."""
        load_setting = self._callbacks.loadExtensionSetting
        host_api_url = load_setting('host_api') or ''
        host_api_token = load_setting('api_token') or ''
        # project_id = ''

        self.host_api.setText(host_api_url)
        self.api_token.setText(host_api_token)
        # self.project_id.setText(project_id)

        if self.msgrel:
            if self.host_api and self.api_token:
                JOptionPane.showMessageDialog(
                    None, "API token, API url dados salvo\n ", "Informativo",
                    JOptionPane.INFORMATION_MESSAGE)

                print("[+] API token, API url dados salvo")
                print("[+] Recarregue: GAT CORE Extension")
                return

        try:
            vapi = self.checkAuth()

            if vapi.status_code == 200:
                data = json.loads(vapi.text)
                print("[ ] Conectado: {}, {}".format(data['name'],
                                                     data['email']))
                # if self.msgrel:
                JOptionPane.showMessageDialog(
                    None, "Conectado: {}, {}".format(data['name'],
                                                     data['email']),
                    "Informativo", JOptionPane.INFORMATION_MESSAGE)

            else:
                raise Exception("Status_Code({})".format(vapi.status_code))

        except Exception as e:
            print("[-] GAT CORE Settings, erro ao conectar na API.")
            print("[-] Exception: {}".format(e))

        return

    def getTabCaption(self):
        """Return the text to be displayed on the tab"""
        return "GAT CORE Settings"

    def getUiComponent(self):
        """Passes the UI to burp"""
        return self.gui_elements

    def generateReportGat(self, rows):
        quote = '"'
        Id = uuid.uuid4().hex
        self.fileId.append(Id)
        path = os.getcwd()
        folder = "\\exports\\"
        file_name = "{}{}{}.csv".format(path, folder, Id)

        with open(file_name, mode='w') as csv_file:
            fields = [
                'Tool_Type', 'IssueType', 'DetailsFinding_Title', 'Severity',
                'Web_Application_URI', 'Web_Application_Path', 'fTag', 'sTag',
                'Description', 'Recomenation_Title', 'Recommendation'
            ]
            writer = csv.DictWriter(csv_file,
                                    fieldnames=fields,
                                    quotechar=quote,
                                    quoting=csv.QUOTE_NONNUMERIC,
                                    lineterminator='\n')
            writer.writeheader()
            writer.writerows(rows)
        csv_file.close()

        return Id

    def sendIssues(self):
        for Id in self.fileId:
            print("[+] Processando ID: {}".format(Id))
            path = os.getcwd()
            folder = "\\exports\\"
            file_name = "{}{}{}.csv".format(path, folder, Id)
            self.launchThread(self.requestAPI, arguments=file_name)

    def launchThread(self, targetFunction, arguments=None, retur=False):
        """Launches a thread against a specified target function"""
        if arguments:

            t = Thread(name='args', target=targetFunction, args=(arguments, ))
        else:
            t = Thread(name='no-args', target=targetFunction)

        t.setDaemon(True)
        t.start()

        if retur:
            r = t.join()
            return r

    def countHostIssues(self, requestResponses):
        count = 0
        icount = 0
        for reqResp in requestResponses:
            url = reqResp.getHttpService()
            requestIssues = self._callbacks.getScanIssues(str(url))
            if requestIssues:
                if len(requestIssues) > 0:
                    count += 1
                    for issue in requestIssues:
                        icount += 1

        return count, icount

    def requestAPI(self, filename):
        load_setting = self._callbacks.loadExtensionSetting
        api_uri = load_setting('host_api') or ''
        api_token = load_setting('api_token') or ''
        projectid = self.projectId

        name_csv = os.path.basename(filename)
        if projectid:
            resource = "/app/vulnerability/upload/api/Burp/{}".format(
                projectid)

        else:
            resource = "/app/vulnerability/upload/api/Burp"

        # print(resource)
        protocol = "http" if api_uri == "localhost" else "https"
        gatPoint = "{}://{}{}".format(protocol, api_uri, resource)

        try:
            dataList = []
            api_url = URL(gatPoint)
            boundary = name_csv.replace(".csv", "")

            headers = ArrayList()
            headers.add('POST %s HTTP/1.1' % resource)
            headers.add('Host: %s' % api_uri)
            headers.add('Authorization: Bearer %s' % api_token)
            headers.add('Accept: application/json')
            headers.add(
                'Content-type: multipart/form-data; boundary={}'.format(
                    boundary))

            dataList.append('--' + boundary)
            dataList.append(
                'Content-Disposition: form-data; name=file; filename={}'.
                format(name_csv))

            dataList.append('Content-Type: text/csv')
            dataList.append('')
            with open(filename) as f:
                dataList.append(f.read())

            dataList.append('--' + boundary + '--')
            dataList.append('')
            body = '\r\n'.join(dataList)

            newBody = self._helpers.bytesToString(body)

            newRequest = self._helpers.buildHttpMessage(headers, newBody)

            requestInfo = self._helpers.analyzeRequest(newRequest)
            headers = requestInfo.getHeaders()

            response = self._callbacks.makeHttpRequest(api_url.getHost(), 443,
                                                       True, newRequest)

            response_info = self._helpers.analyzeResponse(response)

            response_value = self._helpers.bytesToString(
                response)[response_info.getBodyOffset():].encode("utf-8")

        except Exception as e:
            print("[-] Falha arquivo/envio de Issues ID:{} - Error: {}".format(
                name_csv, e))

        if response_info.getStatusCode() == 200:
            self.removeCSV(filename)
            print("[+] Success ID: {}".format(name_csv.replace(".csv", "")))

        else:
            print("[-] Falhou o envio do ID: {} - code :{}".format(
                name_csv.replace(".csv", ""), response_info.getStatusCode()))

            if response_value:
                print("Error: {}".format(response_value))

            JOptionPane.showMessageDialog(None, "Falhou o envio das Issues",
                                          "Error", JOptionPane.ERROR_MESSAGE)
            self.removeCSV(filename)

    def checkAuth(self):
        """
        Validar api + token GAT
        """
        load_setting = self._callbacks.loadExtensionSetting
        api_uri = load_setting('host_api') or ''
        api_token = load_setting('api_token') or ''

        resource = "/api/v1/me"

        protocol = "http" if api_uri == "localhost" else "https"
        gatPoint = "{}://{}{}".format(protocol, api_uri, resource)

        api_url = URL(gatPoint)

        headers = ArrayList()
        headers.add('GET %s HTTP/1.1' % resource)
        headers.add('Host: %s' % api_uri)
        headers.add('Authorization: Bearer %s' % api_token)
        headers.add('Content-Type: application/json')

        newRequest = self._helpers.buildHttpMessage(headers, None)

        requestInfo = self._helpers.analyzeRequest(newRequest)
        headers = requestInfo.getHeaders()

        response = self._callbacks.makeHttpRequest(api_url.getHost(), 443,
                                                   True, newRequest)

        response_info = self._helpers.analyzeResponse(response)
        response_value = self._helpers.bytesToString(
            response)[response_info.getBodyOffset():].encode("utf-8")

        response = {}
        response['status_code'] = response_info.getStatusCode()
        response['text'] = response_value
        r = DotDict(response)
        return r

    def removeCSV(self, path):
        """ param <path> could either be relative or absolute. """
        if os.path.isfile(path) or os.path.islink(path):
            os.remove(path)
        else:
            raise ValueError("file {} is not a file".format(path))

    def clsProjectId(self, _):
        self.project_id.setText(None)
        self.project = False
        self.projectId = None
        JOptionPane.showMessageDialog(
            None, "Redefinido envio de Issues sem Projeto.", "Informativo",
            JOptionPane.INFORMATION_MESSAGE)
Esempio n. 2
0
class BurpExtender(IBurpExtender, IContextMenuFactory, IHttpListener,
                   ISessionHandlingAction, ITab):
    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        callbacks.setExtensionName("JC-AntiToken")
        callbacks.registerContextMenuFactory(self)
        # callbacks.registerHttpListener(self)
        callbacks.registerSessionHandlingAction(self)
        self.drawUI()

    def printcn(self, msg):
        print(msg.decode('utf-8').encode(sys_encoding))

    def drawUI(self):
        # 最外层:垂直盒子,内放一个水平盒子+一个胶水
        out_vBox_main = Box.createVerticalBox()
        # 次外层:水平盒子,使用说明
        usage = u'''
                             JC-AntiToken(简单防重放绕过)
        适用场景:防重放的方式为,提前向一个页面发送请求取得token,替换到下一个页面中。
        适用说明:
            1. 请求头中Headers和Data的值必须是JSON字符串,如:{"var":"value"}
            2. 左边tokenRegex的格式为:
                a. .*开头,.*结尾,用()括住要取出的token
                b. 如:.*,"token":"(.*?)".*
            3. 右边tokenRegex的格式为:
                a. 需要三个(),第二个()括住要替换的token
                b. 如:(.*,"token":")(.*?)(".*)
        详见:https://github.com/chroblert/JC-AntiToken
        '''
        hBox_usage = Box.createHorizontalBox()
        jpanel_test = JPanel()
        jTextarea_usage = JTextArea()
        jTextarea_usage.setText(usage)
        jTextarea_usage.setRows(13)
        jTextarea_usage.setEditable(False)
        # jpanel_test.add(jTextarea_usage)
        hBox_usage.add(JScrollPane(jTextarea_usage))

        # 次外层:水平盒子,内放两个垂直盒子
        hBox_main = Box.createHorizontalBox()
        # 左垂直盒子
        vBox_left = Box.createVerticalBox()
        # 右垂直盒子
        vBox_right = Box.createVerticalBox()

        # 左垂直盒子内部:发送请求包拿token
        # URL标签
        jlabel_url = JLabel("       URL: ")
        self.jtext_url = JTextField(generWidth)
        self.jtext_url.setMaximumSize(self.jtext_url.getPreferredSize())
        hbox_url = Box.createHorizontalBox()
        hbox_url.add(jlabel_url)
        hbox_url.add(self.jtext_url)
        hglue_url = Box.createHorizontalGlue()
        hbox_url.add(hglue_url)
        # 请求方法标签
        jlabel_reqMeth = JLabel("ReqMeth: ")
        self.jcombobox_reqMeth = JComboBox()
        self.jcombobox_reqMeth.addItem("GET")
        self.jcombobox_reqMeth.addItem("POST")
        hbox_reqMeth = Box.createHorizontalBox()
        hbox_reqMeth.add(jlabel_reqMeth)
        hbox_reqMeth.add(self.jcombobox_reqMeth)
        self.jcombobox_reqMeth.setMaximumSize(
            self.jcombobox_reqMeth.getPreferredSize())
        hglue_reqMeth = Box.createHorizontalGlue()
        hbox_reqMeth.add(hglue_reqMeth)
        # ContentType标签
        jlabel_contentType = JLabel("ConType: ")
        self.jcombobox_contentType = JComboBox()
        self.jcombobox_contentType.addItem("application/json")
        self.jcombobox_contentType.addItem("application/x-www-form-urlencoded")
        hbox_contentType = Box.createHorizontalBox()
        hbox_contentType.add(jlabel_contentType)
        hbox_contentType.add(self.jcombobox_contentType)
        self.jcombobox_contentType.setMaximumSize(
            self.jcombobox_contentType.getPreferredSize())
        hglue_contentType = Box.createHorizontalGlue()
        hbox_contentType.add(hglue_contentType)
        # Charset标签
        jlabel_charset = JLabel("CharSet: ")
        self.jcombobox_charset = JComboBox()
        self.jcombobox_charset.addItem("UTF-8")
        self.jcombobox_charset.addItem("GBK")
        hbox_charset = Box.createHorizontalBox()
        hbox_charset.add(jlabel_charset)
        hbox_charset.add(self.jcombobox_charset)
        self.jcombobox_charset.setMaximumSize(
            self.jcombobox_charset.getPreferredSize())
        hglue_charset = Box.createHorizontalGlue()
        hbox_charset.add(hglue_charset)
        # 请求头标签
        jlabel_headers = JLabel("Headers: ")
        self.jtext_headers = JTextField(generWidth)
        self.jtext_headers.setMaximumSize(
            self.jtext_headers.getPreferredSize())
        hbox_headers = Box.createHorizontalBox()
        hbox_headers.add(jlabel_headers)
        hbox_headers.add(self.jtext_headers)
        hglue_headers = Box.createHorizontalGlue()
        hbox_headers.add(hglue_headers)
        # 请求参数标签
        jlabel_data = JLabel("     Data: ")
        self.jtext_data = JTextField(generWidth)
        self.jtext_data.setPreferredSize(Dimension(20, 40))
        self.jtext_data.setMaximumSize(self.jtext_data.getPreferredSize())
        hbox_data = Box.createHorizontalBox()
        hbox_data.add(jlabel_data)
        hbox_data.add(self.jtext_data)
        hglue_data = Box.createHorizontalGlue()
        hbox_data.add(hglue_data)
        # token标志位置标签
        hbox_radiobtn = Box.createHorizontalBox()
        jlabel_tokenPosition = JLabel("Token Position: ")
        self.radioBtn01 = JRadioButton("Header")
        self.radioBtn02 = JRadioButton("Body")
        btnGroup = ButtonGroup()
        btnGroup.add(self.radioBtn01)
        btnGroup.add(self.radioBtn02)
        self.radioBtn01.setSelected(True)
        hbox_radiobtn.add(jlabel_tokenPosition)
        hbox_radiobtn.add(self.radioBtn01)
        hbox_radiobtn.add(self.radioBtn02)
        # token正则表达式标签
        hbox_token = Box.createHorizontalBox()
        hbox_token_header = Box.createHorizontalBox()
        hbox_token_body = Box.createHorizontalBox()
        # token正则表达式标签:header中
        jlabel_tokenName = JLabel("tokenName: ")
        self.jtext_tokenName = JTextField(tokenWidth)
        self.jtext_tokenName.setMaximumSize(
            self.jtext_tokenName.getPreferredSize())
        hbox_token_header.add(jlabel_tokenName)
        hbox_token_header.add(self.jtext_tokenName)
        hglue_token_header = Box.createHorizontalGlue()
        hbox_token_header.add(hglue_token_header)
        # token正则表达式标签:body中
        jlabel_tokenRegex = JLabel("tokenRegex: ")
        self.jtext_tokenRegex = JTextField(tokenWidth)
        self.jtext_tokenRegex.setMaximumSize(
            self.jtext_tokenRegex.getPreferredSize())
        hbox_token_body.add(jlabel_tokenRegex)
        hbox_token_body.add(self.jtext_tokenRegex)
        hglue_token_body = Box.createHorizontalGlue()
        hbox_token_body.add(hglue_token_body)
        # token正则表达式标签
        hbox_token.add(hbox_token_header)
        hbox_token.add(hbox_token_body)
        # test测试按钮
        hbox_test = Box.createHorizontalBox()
        jbtn_test = JButton("TEST", actionPerformed=self.btnTest)
        self.jlabel_test = JLabel("Result: ")
        hbox_test.add(jbtn_test)
        hbox_test.add(self.jlabel_test)
        # 水平胶水填充
        hGlue_test = Box.createHorizontalGlue()
        hbox_test.add(hGlue_test)
        hbox_test.setBorder(BorderFactory.createLineBorder(Color.green, 2))
        # 响应数据输出
        hbox_resp = Box.createHorizontalBox()
        self.jtextarea_resp = JTextArea()
        jsp = JScrollPane(self.jtextarea_resp)
        hbox_resp.add(self.jtextarea_resp)
        # 左垂直盒子:添加各种水平盒子
        vBox_left.add(hbox_url)
        vBox_left.add(hbox_reqMeth)
        vBox_left.add(hbox_contentType)
        vBox_left.add(hbox_charset)
        vBox_left.add(hbox_headers)
        vBox_left.add(hbox_data)
        vBox_left.add(hbox_radiobtn)
        vBox_left.add(hbox_token)
        vBox_left.add(hbox_test)
        vBox_left.add(hbox_resp)
        # 左垂直盒子:垂直胶水填充
        vGlue_test = Box.createGlue()
        vBox_left.add(vGlue_test)

        # 右垂直盒子内部:指定token在请求包中的位置
        # token标志位置单选按钮
        hbox_radiobtn_r = Box.createHorizontalBox()
        jlabel_tokenPosition_r = JLabel("Token Position: ")
        self.radioBtn01_r = JRadioButton("Header")
        self.radioBtn02_r = JRadioButton("Body")
        btnGroup_r = ButtonGroup()
        btnGroup_r.add(self.radioBtn01_r)
        btnGroup_r.add(self.radioBtn02_r)
        self.radioBtn01_r.setSelected(True)
        hbox_radiobtn_r.add(jlabel_tokenPosition_r)
        hbox_radiobtn_r.add(self.radioBtn01_r)
        hbox_radiobtn_r.add(self.radioBtn02_r)

        # token正则表达式
        hbox_token_r = Box.createHorizontalBox()
        hbox_token_header_r = Box.createHorizontalBox()
        hbox_token_body_r = Box.createHorizontalBox()
        # token正则表达式:在header中
        jlabel_tokenName_r = JLabel("tokenName: ")
        self.jtext_tokenName_r = JTextField(tokenWidth)
        self.jtext_tokenName_r.setMaximumSize(
            self.jtext_tokenName_r.getPreferredSize())
        hbox_token_header_r.add(jlabel_tokenName_r)
        hbox_token_header_r.add(self.jtext_tokenName_r)
        hglue_token_header_r = Box.createHorizontalGlue()
        hbox_token_header_r.add(hglue_token_header_r)
        # token正则表达式:在Body中
        jlabel_tokenRegex_r = JLabel("tokenRegex: ")
        self.jtext_tokenRegex_r = JTextField(tokenWidth)
        self.jtext_tokenRegex_r.setMaximumSize(
            self.jtext_tokenRegex_r.getPreferredSize())
        hbox_token_body_r.add(jlabel_tokenRegex_r)
        hbox_token_body_r.add(self.jtext_tokenRegex_r)
        hglue_token_body_r = Box.createHorizontalGlue()
        hbox_token_body_r.add(hglue_token_body_r)
        # token正则表达式
        hbox_token_r.add(hbox_token_header_r)
        hbox_token_r.add(hbox_token_body_r)
        # 测试按钮
        hbox_test_r = Box.createHorizontalBox()
        jbtn_test_r = JButton("SET", actionPerformed=self.btnTest_r)
        self.jlabel_test_r = JLabel("Result: ")
        hbox_test_r.add(jbtn_test_r)
        hbox_test_r.add(self.jlabel_test_r)
        # 水平胶水填充
        hGlue02 = Box.createHorizontalGlue()
        hbox_test_r.add(hGlue02)
        hbox_test_r.setBorder(BorderFactory.createLineBorder(Color.green, 2))

        # 右垂直盒子:添加各种水平盒子
        vBox_right.add(hbox_radiobtn_r)
        vBox_right.add(hbox_token_r)
        vBox_right.add(hbox_test_r)
        vGlue = Box.createVerticalGlue()
        vBox_right.add(vGlue)

        vBox_left.setBorder(BorderFactory.createLineBorder(Color.black, 3))
        vBox_right.setBorder(BorderFactory.createLineBorder(Color.black, 3))

        # 次外层水平盒子:添加左右两个垂直盒子
        hBox_main.add(vBox_left)
        hBox_main.add(vBox_right)
        # 最外层垂直盒子:添加次外层水平盒子,垂直胶水
        out_vBox_main.add(hBox_usage)
        out_vBox_main.add(hBox_main)

        self.mainPanel = out_vBox_main
        self._callbacks.customizeUiComponent(self.mainPanel)
        self._callbacks.addSuiteTab(self)

    def getTabCaption(self):
        return "JC-AntiToken"

    def getUiComponent(self):
        return self.mainPanel

    def testBtn_onClick(self, event):
        print("click button")

    def createMenuItems(self, invocation):
        menu = []
        if invocation.getToolFlag() == IBurpExtenderCallbacks.TOOL_REPEATER:
            menu.append(
                JMenuItem("Test menu", None, actionPerformed=self.testmenu))
        return menu

    def testmenu(self, event):
        print(event)
        print("JCTest test menu")

    def processHttpMessage(self, toolflag, messageIsRequest, messageInfo):
        service = messageInfo.getHttpService()
        if messageIsRequest:
            pass
            print("Host: " + str(service.getHost()))
            print("Port: " + str(service.getPort()))
            print("Protocol: " + str(service.getProtocol()))
            print("-----------------------------------")

    def getActionName(self):
        return "JC-AntiToken"

    def performAction(self, currentRequest, macroItems):
        # url
        url = self._helpers.analyzeRequest(currentRequest).getUrl()
        print(url)
        reqInfo = self._helpers.analyzeRequest(currentRequest)
        # request headers
        headers = reqInfo.getHeaders()
        print("ReqHeaders: " + headers)
        # get cookie from request header
        cookie = self.getCookieFromReq(headers)
        print(cookie)
        print(type(cookie))
        # offset to req body
        reqBodyOffset = reqInfo.getBodyOffset()
        reqBody = str(bytearray(currentRequest.getRequest()[reqBodyOffset:]))
        print("ReqBody: " + reqBody)
        # modify Request Body
        newToken = self.getNewToken(cookie)
        if newToken != None:
            # tokenInReqHeader
            res = False
            if self.tokenInHeader_r:
                # pass
                # 普通header中
                for header in headers:
                    if ":" in header:
                        if header.split(":")[0] == self.tokenName_r:
                            headers = [
                                self.tokenName_r + ": " + newToken
                                if i.split(":")[0] == self.tokenName_r else i
                                for i in headers
                            ]
                            res = True
                            break
                # cookie中
                if not res and cookie != None and self.tokenName_r + "=" in cookie:
                    # pass
                    for i in range(len(headers)):
                        if headers[i].startwith("Cookie:"):
                            cookies2 = headers[i]
                            cookies3 = cookies2.split(":")[1]
                            if ";" not in cookies3:
                                headers[
                                    i] = "Cookie: " + self.tokenName_r + "=" + newToken
                                res = True
                                break
                            else:
                                cookies4 = cookies3.split(";")
                                for cookie_idx in range(len(cookies4)):
                                    if self.tokenName_r + "+" in cookies4[
                                            cookie_idx]:
                                        cookies4[
                                            cookie_idx] = self.tokenName_r + "=" + newToken
                                        res = True
                                        break
                                headers[i] = "Cookie: " + ";".join(cookies4)
                                break
                # query string中
                if not res:
                    meth = headers[0].split(" ")[0]
                    url = headers[0].split(" ")[1]
                    ver = headers[0].split(" ")[2]
                    if self.tokenName_r + "=" not in url:
                        pass
                    else:
                        if "&" not in url:
                            url = url.split("?")[
                                0] + "?" + self.tokenName_r + "=" + newToken
                            headers[0] = meth + " " + url + " " + ver
                        else:
                            params = url.split("?")[1].split("&")
                            for i in range(len(params)):
                                if self.tokenName_r + "=" in params[i]:
                                    params[
                                        i] = self.tokenName_r + "=" + newToken
                                    break
                            url = url.split("?")[0] + "?" + "&".join(params)
                            headers[0] = meth + " " + url + " " + ver
            # tokenInReqBody
            else:
                if re.match(self.tokenRegex_r, reqBody):
                    try:
                        reqBody = re.sub(self.tokenRegex_r,
                                         r'\g<1>' + newToken + r'\g<3>',
                                         reqBody, 0, re.M | re.I)
                    except Exception as e:
                        print(e)
                        # print(reqBody)
                        # reqBody = re.sub(self.tokenRegex_r,r'\g<1>'+newToken+r'\g<3>',reqBody,0,re.M|re.I)

            # if re.match(r'(.*?"_tokenName":")([a-zA-Z0-9]{6,})(")',reqBody):
            #     reqBody = re.sub(r'(.*?"_tokenName":")([a-zA-Z0-9]{6,})(")',r'\1'+newToken+r'\3',reqBody,0,re.M|re.I)
        # rebuild request
        reqMessage = self._helpers.buildHttpMessage(headers, bytes(reqBody))
        # forward
        currentRequest.setRequest(reqMessage)
        print("++++++++++++++++++++++++")

    def getCookieFromReq(self, headers):
        for header in headers:
            if re.match(r'^Cookie:', header, re.I):
                return re.match(r'^Cookie: (.*)', header, re.I).group(1)

    # get new token
    def getNewToken(self, cookie):
        print(cookie)
        print("getNewToken")
        # url = "http://myip.ipip.net"
        headers_cookie = {
            'Cookie': cookie,
        }
        if cookie != '':
            self.headers.update(**headers_cookie)
        if self.reqMeth == "GET":
            resp = self.sendGetHttp(self.url, self.headers, self.data,
                                    self.contentType)
        else:
            resp = self.sendPostHttp(self.url, self.headers, self.data,
                                     self.contentType)
        respBody = resp.read()
        respInfo = resp.info()
        if self.tokenInHeader:
            if respInfo.getheader(self.tokenName) != None:
                newToken = respInfo.getheader(self.tokenName)
                print(newToken)
                return newToken
            else:
                regexPattern = '.*' + self.tokenName + '=(.*?);'
                if respInfo.getheader("set-cookie") != None:
                    cookies = respInfo.getheader("set-cookie")
                    if re.match(regexPattern, cookies, re.M | re.I):
                        newToken = re.match(regexPattern, cookies,
                                            re.M | re.I).group(1)
                        print("newToken: ", newToken)
                        return newToken
                    else:
                        return None
                else:
                    return None
        else:
            regexPattern = self.tokenRegex
            if re.match(regexPattern, respBody, re.M | re.I):
                newToken = re.match(regexPattern, respBody,
                                    re.M | re.I).group(1)
                print("newToken: ", newToken)
                return newToken
            else:
                return None

    def sendGetHttp(self, url, headers, data, contentType):
        context = ssl._create_unverified_context()
        headers_contentType = {'Content-Type': contentType}
        if not headers.has_key("Content-Type"):
            headers.update(**headers_contentType)
        headers_userAgent = {
            'User-Agent':
            'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25'
        }
        if not headers.has_key("User-Agent"):
            headers.update(**headers_userAgent)
        try:
            if data != None:
                # if "urlencode" in contentType:
                data = urllib.urlencode(data)
                url = url + "?" + data
                req = urllib2.Request(url, headers=headers)
            else:
                req = urllib2.Request(url, headers=headers)
            resp = urllib2.urlopen(req, context=context)
            return resp
        except urllib2.HTTPError as error:
            print("ERROR: ", error)
            return None

    def sendPostHttp(self, url, headers, data, contentType):
        context = ssl._create_unverified_context()
        headers_contentType = {'Content-Type': contentType}
        if not headers.has_key("Content-Type"):
            headers.update(**headers_contentType)
        headers_userAgent = {
            'User-Agent':
            'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25'
        }
        if not headers.has_key("User-Agent"):
            headers.update(**headers_userAgent)
        print(headers)
        resp = ""
        print("data: ", data)
        if data != None:
            if "urlencode" in contentType:
                data = urllib.urlencode(data)
                req = urllib2.Request(url, headers=headers, data=data)
            else:
                data = json.dumps(data)
                req = urllib2.Request(url, headers=headers, data=data)
        else:
            if "urlencode" in contentType:
                req = urllib2.Request(url, headers=headers)
            else:
                data = json.dumps(data)
                req = urllib2.Request(url, headers=headers)
        try:
            resp = urllib2.urlopen(req, context=context)
            return resp
        except urllib2.HTTPError as error:
            print("ERROR: ", error)
            return None

    def btnTest(self, e):
        self.printcn("中文测试")
        self.url = self.jtext_url.getText()
        if self.url == "":
            self.jlabel_test.setText("please input url")
            return
        self.reqMeth = self.jcombobox_reqMeth.getSelectedItem()
        # 用户设置content-type
        self.contentType = self.jcombobox_contentType.getSelectedItem(
        ) + ";charset=" + self.jcombobox_charset.getSelectedItem()
        # 用户有没有自定义请求头
        if self.jtext_headers.getText() != "":
            self.headers = json.loads(self.jtext_headers.getText())
        else:
            self.headers = {}
        # 用户有没有自定义请求体
        if self.jtext_data.getText() != "":
            self.data = json.loads(self.jtext_data.getText())
        else:
            self.data = None
        self.tokenName = self.jtext_tokenName.getText()
        self.tokenRegex = self.jtext_tokenRegex.getText()
        resp = ''
        if self.reqMeth == "GET":
            resp = self.sendGetHttp(self.url, self.headers, self.data,
                                    self.contentType)
        else:
            resp = self.sendPostHttp(self.url, self.headers, self.data,
                                     self.contentType)
        if resp == None:
            self.jlabel_test.setText("error,detail in extender output")
            return
        respHeader = resp.info().headers
        print("resp-headers: ", respHeader)
        # print(resp.info().getheader("content-type"))
        self.printcn(resp.info().getheader("set-cookie"))
        # print(resp.info().getheader("xxx"))
        respBody = resp.read()
        print("respBody: ", respBody)
        self.jtextarea_resp.setText("".join(respHeader) + "\n" +
                                    "".join(respBody))
        if (self.radioBtn01.isSelected()):
            self.tokenInHeader = True
            if self.tokenName == "":
                self.jlabel_test.setText("please input tokenName")
                return
        else:
            self.tokenInHeader = False
            if self.tokenRegex == "":
                self.jlabel_test.setText("please input tokenRegex")
                return
        print(self.reqMeth)
        newToken = self.getNewToken("")
        if newToken != None:
            self.jlabel_test.setText("Result: " + str(newToken))
            self.jlabel_test.setBackground(Color.cyan)
        else:
            self.jlabel_test.setText("Result: None")

    def btnTest_r(self, e):
        self.tokenName_r = self.jtext_tokenName_r.getText()
        self.tokenRegex_r = self.jtext_tokenRegex_r.getText()
        if (self.radioBtn01_r.isSelected()):
            self.tokenInHeader_r = True
            if self.tokenName_r == "":
                self.jlabel_test_r.setText("please input tokenName")
                return
        else:
            self.tokenInHeader_r = False
            if self.tokenRegex_r == "":
                self.jlabel_test_r.setText("please input tokenRegex")
                return
        self.jlabel_test_r.setText("SUCCESS")
class JBrukerSubmit:

    colHeads = ('block/sample #', 'Holder', 'Name', 'Experiment', 'Solvent',
                'Group', 'Member', 'Sample Name')

    if platform.node() == 'DM-CHEM-200':
        basedir = r"W:\downloads\Eric\jython"
    elif platform.node() == 'ERIC-PC':
        basedir = r"C:\Users\ERIC\Dropbox\projects\programming\2020\python\autoNMRinput"
    else:
        # running from Bruker spectrometers
        basedir = "/data/downloads/Eric"

    def listSubmit(self, event):
        """Submit highlighted to csv file to automation folder of spectrometer
        """

        # Ask for starting carousel position and submit experimets to topspin
        # obtain file name of CSV file
        selected = self.list.selectedIndex
        csvName = self.data[selected]

        # if no selected file and table is empty just return
        if self.label.text == "Selected File":
            return

        # Create check dialog before submitting data to automation
        self.dataTableModel.dataVector
        #        submitString = "submit " + csvName + " starting at carousel position " + self.carouselStartingPosition.text
        submitString = "submit " + csvName + " starting at carousel position " + str(
            (self.dataTableModel.dataVector)[0][1])
        result = JOptionPane.showConfirmDialog(self.frame, submitString)

        # if submission confirmed
        if result == 0:
            # submit csv file to automation
            ret = readcsv243A.submitNMRexpts([
                self.dataTableModel.dataVector, csvName,
                self.carouselStartingPosition.text
            ])
            # if successful or not update status string
            if ret == 0:
                self.statusLabel.text = "File " + csvName + " Submitted to TOPSPIN  Starting at Carousel Position " + str(
                    (self.dataTableModel.dataVector)[0][1])
                self.panelStatusLabel.setBackground(Color.GREEN)
            elif ret == 1:
                self.statusLabel.text = "Carousel Position not a number"
                self.panelStatusLabel.setBackground(Color.RED)
            elif ret == 2:
                self.statusLabel.text = "Incompatible experiment chosen for spectrometer"
                self.panelStatusLabel.setBackground(Color.RED)
            elif ret == 3:
                self.statusLabel.text = "A holder starting position is not between 1 and 60 inclusive"
                self.panelStatusLabel.setBackground(Color.RED)
            elif ret == 4:
                self.statusLabel.text = "Too many samples for starting position chosen"
                self.panelStatusLabel.setBackground(Color.RED)

            # if an error occured display error message also in a warning dialog too.
            if ret in [1, 2, 3, 4]:
                JOptionPane.showMessageDialog(self.frame,
                                              self.statusLabel.text)

    def listSelect(self, event):
        """When a new csv file is selected from the list
        read in the file and display its contents in the table.
        Unordered csv files will be ordered based on the block/sample number.
        A holder column will be added to the CSV data based on the carousel 
        starting position.
        """

        # Process the events from the list box and update the label
        # get the index from the list and then the filename
        selected = self.list.selectedIndex
        if selected >= 0:

            # update file label and set background colour to normal
            csvName = self.data[selected]
            self.label.text = csvName
            self.panelLabel.setBackground(self.standardBackgroundColor)

            # reset status label
            self.statusLabel.text = "Status"
            self.panelStatusLabel.setBackground(self.standardBackgroundColor)
            #
            # update table by reading in csv file
            # read in csv file and store as a list of dictionaries
            # one dictionary for each line
            fn = csvName
            self.expt_list = []
            f = open(os.path.join(JBrukerSubmit.basedir, fn), 'r')
            reader = csv.DictReader(f)
            for row in reader:
                self.expt_list.append(row)
            f.close()

            # get carousel starting position, if the value cannot be converted
            # to an integer reset it to 1 and reset the GUI to 1
            try:
                self.cnumber = int(self.carouselStartingPosition.text)
            except:
                self.cnumber = 1
                self.self.carouselStartingPosition.text = "1"

            # get the csv data into a list of lists form ready for displaying
            self.tableData = returnJTableData(self.expt_list, self.cnumber)

            # display csv table in table view
            colNames = JBrukerSubmit.colHeads
            # transfer the data over to the table model
            self.dataTableModel.setDataVector(self.tableData, colNames)
            # display the table in the GUI
            self.scrollPaneTable.getViewport().setView((self.table))

            # check to see if experiments will run on the spectometer
            ok, pulseSequence = checkExperimentsWillRun(self.expt_list)

            if not ok:
                # display warning dialog
                warningText = pulseSequence + " cannot be run on this spectrometer"
                JOptionPane.showMessageDialog(self.frame, warningText)

    def returnCSVlist(self, hiddenFiles):
        """ read in csv files ommitting any that are created after 
        auto submission and return as list of strings.
        Miss out any that have been hidden"""
        csvlist = [
            f for f in os.listdir(JBrukerSubmit.basedir)
            if (f.endswith(".csv")) and (f[-6] not in ['A', 'B', 'N'])
        ]
        csvlist = [f for f in csvlist if f not in self.hiddenFiles]
        return csvlist

    def listUpdate(self, event):
        """ when update button clicked renew csv list """
        self.data = self.returnCSVlist(self.hiddenFiles)
        self.list.setListData(self.data)

    def checkCarouselNumber(self, event):
        """ check that carousel field is an integer change background to white
        if okay, red if not."""

        self.cnumber = self.carouselStartingPosition.text
        try:
            self.cnumber = int(self.cnumber)
            self.carouselStartingPosition.background = Color.WHITE
            self.listSelect(event)
        except:
            self.carouselStartingPosition.background = Color.RED

    def tableMouseClicked(self, event):
        """Prior to editing the user will click the holder number cell
        more often than not. This function saves the cell row and column and
        the value in the cell prior to editing."""

        tble = event.getSource()
        self.rw = tble.getSelectedRow()
        self.cl = tble.getSelectedColumn()
        self.oldHolderValue = tble.getValueAt(self.rw, self.cl)


#        print "table mouse clicked", self.rw, self.cl

    def tableChangedCB(self, event):
        """Function is called when a cell is being edited. After the user 
        presses return the data is updated.
        Should only work if Holder column is being edited"""

        print "Table Changed"
        tble = event.getSource()
        if (event.keyChar == "\n") and (self.cl != 1):
            tble.setValueAt(self.oldHolderValue, self.rw, self.cl)

        elif (event.keyChar == "\n") and (self.cl == 1):
            print "RETURN"
            vlue = tble.getValueAt(self.rw, self.cl)
            print "row", self.rw, "col", self.cl, "value", vlue
            #
            # check to see if new holder number is used by another sample
            # get block number of sample changed
            blckNumber = tble.getValueAt(self.rw, 0)
            #
            # get values in table
            holderAlreadyOccupied = False
            tableValues = self.dataTableModel.dataVector
            for i, rw in enumerate(tableValues):
                print i
                if (int(rw[1])
                        == int(vlue)) and (int(blckNumber) != int(rw[0])):
                    tble.setValueAt(int(self.oldHolderValue), self.rw, 1)
                    holderAlreadyOccupied = True
                    warningText = "Holder " + str(
                        vlue) + " already used for sample " + str(rw[0])
                    JOptionPane.showMessageDialog(self.frame, warningText)

                    break
            #
            # check to see if any other rows with same sample number need to be updated
            if not holderAlreadyOccupied:
                for i, rw in enumerate(tableValues):
                    if int(blckNumber) == int(rw[0]):
                        tble.setValueAt(int(vlue), i, 1)

    # def tableKeyPressedCB(self, event):
    #     print "tableKeyPressedCB"
    #     tble = event.getSource()
    #     if event.keyChar == "\n":
    #         print "RETURN"
    #         vlue = tble.getValueAt(self.rw, self.cl)
    #         print "row", self.rw, "col", self.cl, "value", vlue

    #     elif (event.keyChar).isdigit():
    #         print "event.keyChar", event.keyChar

    #         self.rw = tble.getSelectedRow()
    #         self.cl = tble.getSelectedColumn()

    def listShowAllFiles(self, event):
        fp = open("hiddenFiles.txt", 'w')
        fp.write('zzz\n')
        fp.close()
        self.hiddenFiles = ['zzz']
        self.listUpdate(event)

    def listHideFile(self, event):

        # find highlighted csv file name
        selected = self.list.selectedIndex
        csvName = self.data[selected]
        # add csv file name to hidden csv files list
        self.hiddenFiles.append(csvName)
        # update label above table view
        self.label.text = "Selected File"
        self.panelLabel.setBackground(self.standardBackgroundColor)
        # display csv table in table view

        # set table to blanks
        self.tableData = []
        for i in range(18):
            self.tableData.append([
                "",
            ] * len(JBrukerSubmit.colHeads))

        self.dataTableModel.setDataVector(self.tableData,
                                          JBrukerSubmit.colHeads)
        self.listUpdate(event)

        # save hiddenFiles file
        fp = open("hiddenFiles.txt", 'w')
        for f in self.hiddenFiles:
            fp.write(f + '\n')
        fp.close()

    def __init__(self):

        self.rw = 0  # table row
        self.cl = 0  # table column

        # load hidden files list

        self.hiddenFiles = ["zzz"]

        if os.path.exists("hiddenFiles.txt"):
            fp = open("hiddenFiles.txt", "r")
            self.hiddenFiles = fp.readlines()
            fp.close()

        self.hiddenFiles = [f.strip() for f in self.hiddenFiles]
        print self.hiddenFiles

        # These lines setup the basic frame, size and layout
        # the setDefaultCloseOperation so that only the window closes and not TOPSPIN
        self.frame = JFrame("Submit NMR Experimets")
        self.frame.setSize(1200, 440)
        self.frame.setLayout(BorderLayout())
        self.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)

        # set up the list and the contents of the list
        # the python tuple get converted to a Java vector
        self.data = self.returnCSVlist(self.hiddenFiles)
        self.list = JList(self.data, valueChanged=self.listSelect)
        self.spane = JScrollPane()
        self.spane.setPreferredSize(Dimension(145, 150))
        self.spane.getViewport().setView((self.list))
        panel = JPanel()
        panel.add(self.spane)

        # define buttons
        bpanel = JPanel()
        btnS = JButton('Submit File', actionPerformed=self.listSubmit)
        btnU = JButton('Update List', actionPerformed=self.listUpdate)
        btnHideFile = JButton('Hide File', actionPerformed=self.listHideFile)
        btnShowAllFiles = JButton('Show All Files',
                                  actionPerformed=self.listShowAllFiles)

        # label displaying CSV file selected
        self.label = JLabel('Selected File', JLabel.CENTER)

        # label to display warnings and confirm expriments submitted
        self.statusLabel = JLabel('Status', JLabel.CENTER)

        # Create table to display csv file
        self.tableData = []

        for r in range(18):
            self.tableData.append([
                "",
            ] * len(JBrukerSubmit.colHeads))

        colNames = JBrukerSubmit.colHeads
        self.dataTableModel = DefaultTableModel(self.tableData, colNames)
        self.table = JTable(self.dataTableModel,
                            keyTyped=self.tableChangedCB,
                            mouseClicked=self.tableMouseClicked)

        # set all columns to uneditable except Holder column
        # print dir(self.table)
        # self.table.getColumn(0).setEditable(False)
        # self.table.getColumn(2).setEditable(False)
        # self.table.getColumn(3).setEditable(False)
        # self.table.getColumn(4).setEditable(False)
        # self.table.getColumn(5).setEditable(False)
        # self.table.getColumn(6).setEditable(False)

        # self.table = JTable(self.dataTableModel,
        #                     keyPressed=self.tableKeyPressedCB)

        self.scrollPaneTable = JScrollPane()
        self.scrollPaneTable.setPreferredSize(Dimension(900, 300))

        self.scrollPaneTable.getViewport().setView((self.table))

        panelTable = JPanel()
        panelTable.add(self.scrollPaneTable)

        # create text field to get carousel starting position
        self.carouselLabel = JLabel("Carousel Position", JLabel.CENTER)
        self.carouselStartingPosition = JTextField(
            '1', 13, keyPressed=self.checkCarouselNumber)

        # add widgets to do with manupulating csv list in FlowLayout Mode
        panelList = JPanel()
        panelList.setLayout(FlowLayout())
        panelList.setPreferredSize(Dimension(170, 200))

        # set preferred size of buttons
        btnU.setPreferredSize(Dimension(140, 20))
        btnS.setPreferredSize(Dimension(140, 20))
        btnHideFile.setPreferredSize(Dimension(140, 20))
        btnShowAllFiles.setPreferredSize(Dimension(140, 20))

        self.carouselLabel.setPreferredSize(Dimension(140, 20))
        self.carouselStartingPosition.setPreferredSize(Dimension(170, 20))

        panelList.add(btnU)
        panelList.add(panel)
        panelList.add(btnHideFile)
        panelList.add(btnShowAllFiles)
        panelList.add(JSeparator(JSeparator.HORIZONTAL),
                      BorderLayout.LINE_START)
        panelList.add(self.carouselLabel)
        panelList.add(self.carouselStartingPosition)
        panelList.add(btnS)

        self.panelLabel = JPanel()
        self.panelLabel.add(self.label)
        self.standardBackgroundColor = self.panelLabel.getBackground()

        # put status label in a panel so that background color can be changed
        self.panelStatusLabel = JPanel()
        self.panelStatusLabel.add(self.statusLabel)

        # add widgets to frame
        self.frame.add(self.panelLabel, BorderLayout.NORTH)
        self.frame.add(panelList, BorderLayout.WEST)
        self.frame.add(panelTable, BorderLayout.CENTER)
        self.frame.add(self.panelStatusLabel, BorderLayout.SOUTH)

        self.frame.setVisible(True)