Это правильное представление на основе классов django? - PullRequest
1 голос
/ 22 марта 2020

В моем проекте у меня есть страница, которая отображает форму, где пользователь вводит не относящиеся к делу (на данный момент имя проекта) и хост / IP-адрес. Когда он нажимает кнопку сканирования, он отправляет запрос. В настоящий момент я получаю этот IP-адрес, и я пытаюсь «захватить баннер» запущенных сервисов на этом IP / хосте и отобразить результаты на странице. В приведенном ниже коде это работает, но поскольку я впервые использую django, я думаю, что мой подход действительно плох, потому что весь мой код (для захвата баннера et c) находится в функции POST в моем class-based-view. Итак, вопрос в том, могу ли я сделать это лучше? Возможно, напишите эту функцию bannerGrab () где-нибудь еще, и, если форма верна, просто вызовите функцию в методе POST ...

class NewProject(View):
    # Reusable across functions
    form_class = ProjectData
    template_name = 'projectRelated/create_project.html'
    ports = [20, 21, 22, 23, 80, 3306]

    def get(self, request):
        # redundant to use it like this
        # form = ProjectData()
        form = self.form_class
        context = {
            'form': form
            # this is a context variable that i can use in my html page. like this <h3> {{ context.var }} </h3>
            # context = {
            #     'context.var': 'This will render in the html'
            # }
        }
        print('Get method accessed!')
        return render(request, self.template_name, context)

    # TODO: Find a better way to show and store ports
    #       Store the results in JSON

    # TODO: Store to  JSON by choice. Not all code in POST method!!!
    def post(self, request):
        list_of_services = []
        form = self.form_class(request.POST)
        if form.is_valid():
            _target = form.cleaned_data['target']
            host_to_ip = ''
            # project_from_input = form.cleaned_data['project_name']
            print(_target)
            for port in self.ports:
                try:
                    error_message = 'Couldn\'t connect. Try another subnet!'
                    socket_obj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    # if connection is established result is 0.
                    # 0.5 seconds timeout. If subnet isn't reachable
                    socket_obj.settimeout(2)
                    if _target.isalpha():
                        # if user's input was alphanumeric convert to an ip address
                        host_to_ip = socket.gethostbyname(_target)
                        result = socket_obj.connect_ex((host_to_ip, port))
                    else:
                        # user's input was an IP address.
                        result = socket_obj.connect_ex((_target, port))
                    # If port is HTTP we need to make a request to get data!
                    if port == 80 and result == 0:
                        # in order to get an answer from the server we need to make a legitimate request to him.
                        bytes_to_send = str.encode("HEAD / HTTP/1.1\r\n\r\n")
                        # send our request FIRST.
                        socket_obj.send(bytes_to_send)
                        # grab the banner after server answers
                        banner = socket_obj.recv(1024).decode('utf-8')
                        for service in banner.split('\n'):
                            if 'Server:' in service:
                                list_of_services.append(service + ' running at port : ' + str(port))
                                socket_obj.close()
                    # an established connection returns 0 !
                    if result == 0:
                        banner = socket_obj.recv(1024).decode('utf-8')
                        banner_with_port = banner + ' running at port : ' + port
                        list_of_services.append(banner_with_port)
                        socket_obj.close()
                except Exception as ex:
                    print('Exception -> ' + str(ex))
                finally:
                    socket_obj.close()
                    # After button Run-Scan is pressed clear the form without reloading the page.
                    form = self.form_class
            context = {
                'form': form,
                'list_of_services': list_of_services,
                'error_message': error_message,
                'target_input': _target,
            }
            print('POST METHOD ACCESSED!')
            return render(request, self.template_name, context)```

1 Ответ

0 голосов
/ 22 марта 2020

Да, конечно, перемещение всех этих логик c в другой метод сделает код намного чище. Метод post обычно должен анализировать данные формы, проверять их и возвращать ответ.

Вы можете просто создать другой метод внутри класса NewProject. Или вы можете создать новый класс с именем BannerManager и переместить туда логи c. Но я не вижу смысла в создании нового класса, если у вас нет больше места, где вы работаете с сокетами, баннерами и т. Д. c.

...