Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display and Manage Trademarks on company page #2624

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions company/templates/company/edit_domain.html
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,38 @@ <h2 class="text-base font-semibold leading-7 text-gray-900">Domain Managers</h2>
{% endfor %}
</div>
</div>
<div class="border-b border-gray-900/10 pb-12 mt-5">
<h2 class="text-base font-semibold leading-7 text-gray-900">Trademarks</h2>
<div>
<label for="trademarkInput"
class="block text-sm font-medium leading-6 text-gray-900">Trademark Name</label>
<input name="trademarkInput"
type="text"
id="trademarkInput"
autocomplete="trademarkInput"
class="w-[90%] block rounded-md border-0 py-1.5 pl-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-red-600 sm:text-sm sm:leading-6"
placeholder="Enter trademark name">
<button name="addtrademark_button"
onclick="addTrademark()"
type="button"
class="w-[120px] h-[40px] bg-red-500 text-sm text-white font-bold rounded-md mt-2 hover:bg-red-600 transition-all">
Add Trademarks
</button>
</div>
<input type="hidden" name="removedTrademarks" id="removedTrademarks">
<div id="trademarkList" class="mt-4">
{% for trademark in trademarks %}
<div value="{{ trademark.id }}"
name="remove-button"
id="remove-button"
class="flex items-center justify-between bg-gray-100 p-2 rounded-md mb-2">
<span>{{ trademark.name }}</span>
<br>
<button type="button" onclick="removeTrademark(this)" class="text-red-600">Remove</button>
</div>
{% endfor %}
</div>
</div>
<div class="border-b border-gray-900/10 pb-12 mt-5">
<h2 class="text-base font-semibold leading-7 text-gray-900">Notifications</h2>
<p class="mt-1 text-sm leading-6 text-gray-600">
Expand Down Expand Up @@ -265,6 +297,36 @@ <h2 class="text-base font-semibold leading-7 text-gray-900">Notifications</h2>
updateUserSelections();
}

function addTrademark() {
const trademarkInput = document.getElementById('trademarkInput');
const trademarkList = document.getElementById('trademarkList');
const trademark = trademarkInput.value;
if (trademarkInput.value.trim() !== "") {
const trademarkItem = document.createElement('div');
trademarkItem.className = "flex items-center justify-between bg-gray-100 p-2 rounded-md mb-2";
trademarkItem.innerHTML = `
<span>${trademark}</span>
<button value="$trademark" type="button" onclick="removeTrademark(this)" class="text-red-600">Remove</button>
`;
trademarkList.appendChild(trademarkItem);
}
}
function removeTrademark(button) {
const trademarkItem = button.parentElement;
const trademarkId = trademarkItem.getAttribute('value');
const removedTrademarksField = document.getElementById('removedTrademarks');

let currentValue = removedTrademarksField.value;
if (currentValue) {
currentValue += ',' + trademarkId;
} else {
currentValue = trademarkId;
}
removedTrademarksField.value = currentValue;

trademarkItem.remove();
}

function add_user_selection() {
const user_selection_child_html = document.createElement('div');
user_selection_child_html.classList.add('mt-2', 'flex', 'flex-row', 'items-center', 'w-[50%]', 'user-selection');
Expand Down
74 changes: 43 additions & 31 deletions company/templates/company/view_domain.html
Original file line number Diff line number Diff line change
Expand Up @@ -279,41 +279,53 @@ <h4 class="text-xl text-gray-900 font-bold">Statistics</h4>
</div>
</div>
</div>
<div class="bg-white w-full p-10 my-5">
<div class="w-full flex justify-between">
<h4 class="text-xl text-gray-900 font-bold mb-5">Ongoing Bughunts</h4>
<a href="{% url 'hunts' %}" class="text-md text-blue-600">View all</a>
</div>
<div class="flex justify-between w-full flex-wrap">
{% if ongoing_bughunts %}
{% for hunt in ongoing_bughunts %}
<div class="flex w-full md:w-[48%] lg:w-[30%] h-[180px] border-2 border-gray-300 p-2 cursor-pointer shadow-sm hover:scale-105 hover:shadow-lg transition-all m-2 sm:mt-5 rounded-lg">
<div class="flex justify-center items-center w-[40%]">
<img class="w-32 h-32 rounded-lg" {{ hunt.logo }} src="{% if hunt.logo %} {{ MEDIA_URL }}{{ hunt.logo }} {% else %} https://via.placeholder.com/128?text=No+Logo {% endif %}" alt="bughunt logo" width="128px" height="128px">
</div>
<div class="flex flex-col ml-5 w-[60%]">
<p class="text-lg font-extrabold mt-6">{{ hunt.name }}</p>
<p class="tw-font-extralight text-gray-500 text-sm mt-1">{{ hunt.url }}</p>
<div class="flex mt-5 justify-between items-center w-full">
<p class="font-bold">
$
{% if hunt.total_prize %}
{{ hunt.total_prize }}
{% else %}
0
{% endif %}
</p>
<a href="{% url 'show_bughunt' hunt.id %}"
class="bg-red-600 text-white px-3 py-1 font-bold rounded-md">More info</a>
<div class="w-full flex justify-between min-h-[80vh] py-5 flex-col md:flex-row">
<div class="flex flex-col w-full md:w-[80%] mr-5 items-start bg-white rounded-xl p-5 overflow-x-hidden overflow-y-scroll">
<div class="w-full flex justify-between">
<h4 class="text-xl text-gray-900 font-bold mb-5">Ongoing Bughunts</h4>
<a href="{% url 'hunts' %}" class="text-md text-blue-600">View all</a>
</div>
<div class="flex justify-between w-full flex-wrap">
{% if ongoing_bughunts %}
{% for hunt in ongoing_bughunts %}
<div class="flex w-full md:w-[48%] lg:w-[30%] h-[180px] border-2 border-gray-300 p-2 cursor-pointer shadow-sm hover:scale-105 hover:shadow-lg transition-all m-2 sm:mt-5 rounded-lg">
<div class="flex justify-center items-center w-[40%]">
<img class="w-32 h-32 rounded-lg" {{ hunt.logo }} src="{% if hunt.logo %} {{ MEDIA_URL }}{{ hunt.logo }} {% else %} https://via.placeholder.com/128?text=No+Logo {% endif %}" alt="bughunt logo" width="128px" height="128px">
</div>
<div class="flex flex-col ml-5 w-[60%]">
<p class="text-lg font-extrabold mt-6">{{ hunt.name }}</p>
<p class="tw-font-extralight text-gray-500 text-sm mt-1">{{ hunt.url }}</p>
<div class="flex mt-5 justify-between items-center w-full">
<p class="font-bold">
$
{% if hunt.total_prize %}
{{ hunt.total_prize }}
{% else %}
0
{% endif %}
</p>
<a href="{% url 'show_bughunt' hunt.id %}"
class="bg-red-600 text-white px-3 py-1 font-bold rounded-md">More info</a>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="w-full h-full flex items-center justify-center">
<p class="text-xl text-red-500">No ongoing bughunts available</p>
</div>
{% endif %}
</div>
</div>
<div class="bg-white rounded-lg shadow-xl p-8 w-full mt-5 md:w-[20%] md:mt-0 overflow-y-scroll">
<div class="flex items-center justify-between">
<h4 class="text-xl text-gray-900 font-bold">Trademark</h4>
</div>
<div class="flex flex-col mt-5">
{% for trademark in trademarks %}
<p class="text-center font-bold text-lg pt-2 mt-1">{{ trademark.name }}</p>
{% endfor %}
{% else %}
<div class="w-full h-full flex items-center justify-center">
<p class="text-xl text-red-500">No ongoing bughunts available</p>
</div>
{% endif %}
</div>
</div>
</div>
<div class="w-full flex justify-between min-h-[80vh] flex-col md:flex-row">
Expand Down
55 changes: 54 additions & 1 deletion company/tests.py
Original file line number Diff line number Diff line change
@@ -1 +1,54 @@
# Create your tests here.
import os

import chromedriver_autoinstaller
from django.test import LiveServerTestCase
from django.test.utils import override_settings
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

os.environ["DJANGO_LIVE_TEST_SERVER_ADDRESS"] = "localhost:8082"


class MySeleniumTests(LiveServerTestCase):
fixtures = ["initial_data.json"]

@classmethod
def setUpClass(cls):
options = webdriver.ChromeOptions()
options.add_argument("window-size=1920,1080")
options.set_capability("goog:loggingPrefs", {"browser": "ALL"})
service = Service(chromedriver_autoinstaller.install())
cls.selenium = webdriver.Chrome(service=service, options=options)

super(MySeleniumTests, cls).setUpClass()

@classmethod
def tearDownClass(cls):
cls.selenium.quit()
super(MySeleniumTests, cls).tearDownClass()

@override_settings(DEBUG=True)
def test_company_trademark(self):
self.selenium.set_page_load_timeout(70)
self.selenium.get("%s%s" % (self.live_server_url, "/accounts/login/"))
self.selenium.find_element("name", "login").send_keys("bugbug")
self.selenium.find_element("name", "password").send_keys("secret")
self.selenium.find_element("name", "login_button").click()
WebDriverWait(self.selenium, 30).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
self.selenium.get("%s%s" % (self.live_server_url, "/company/58/dashboard/edit_domain/99/"))
WebDriverWait(self.selenium, 10).until(
EC.presence_of_element_located((By.NAME, "trademarkInput"))
)
self.selenium.find_element("name", "trademarkInput").send_keys("bugbug.com")
self.selenium.find_element("name", "addtrademark_button").click()
self.selenium.get("%s%s" % (self.live_server_url, "/company/domain/99/"))
WebDriverWait(self.selenium, 30).until(
EC.presence_of_element_located((By.TAG_NAME, "body"))
)
body = self.selenium.find_element("tag name", "body")
self.assertIn("bugbug.com", body.text)
47 changes: 46 additions & 1 deletion company/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,16 @@
from django.views.decorators.http import require_http_methods
from django.views.generic import View

from website.models import Company, Domain, Hunt, HuntPrize, Issue, IssueScreenshot, Winner
from website.models import (
Company,
Domain,
Hunt,
HuntPrize,
Issue,
IssueScreenshot,
Trademark,
Winner,
)
from website.utils import is_valid_https_url, rebuild_safe_url

restricted_domain = ["gmail.com", "hotmail.com", "outlook.com", "yahoo.com", "proton.com"]
Expand Down Expand Up @@ -454,12 +463,14 @@ def get(self, request, id, *args, **kwargs):
users = User.objects.filter(is_active=True)
domain_id = kwargs.get("domain_id")
domain = Domain.objects.filter(id=domain_id).first() if domain_id else None
trademarks = Trademark.objects.filter(domain__id=domain_id).values if domain_id else None
context = {
"company": id,
"company_obj": Company.objects.filter(id=id).first(),
"companies": companies,
"users": users,
"domain": domain, # Pass the domain to the template if it exists
"trademarks": trademarks,
}

if domain:
Expand All @@ -470,14 +481,21 @@ def get(self, request, id, *args, **kwargs):
@validate_company_user
@check_company_or_manager
def post(self, request, id, *args, **kwargs):
domain_id = kwargs.get("domain_id")
domain_data = {
"name": request.POST.get("domain_name", None),
"url": request.POST.get("domain_url", None),
"github": request.POST.get("github_url", None),
"twitter": request.POST.get("twitter_url", None),
"facebook": request.POST.get("facebook_url", None),
"trademarkInput": request.POST.get("trademarkInput", None),
"remove-trademark": request.POST.get("removedTrademarks", None),
}

removed_trademarks = domain_data["remove-trademark"]
if removed_trademarks:
Trademark.objects.filter(id__in=removed_trademarks.split(",")).delete()

if domain_data["url"]:
parsed_url = urlparse(domain_data["url"])
if parsed_url.hostname is None:
Expand Down Expand Up @@ -582,6 +600,15 @@ def post(self, request, id, *args, **kwargs):
)

domain.managers.set(domain_managers)

trademark_name = domain_data["trademarkInput"]
if trademark_name:
trademark = Trademark.objects.create(
name=trademark_name,
domain=Domain.objects.get(id=domain_id),
)
trademark.save()

domain.save()

return redirect("company_manage_domains", id=id)
Expand All @@ -598,7 +625,14 @@ def put(self, request, id, *args, **kwargs):
"github": request.POST.get("github_url", None),
"twitter": request.POST.get("twitter_url", None),
"facebook": request.POST.get("facebook_url", None),
"trademarkInput": request.POST.get("trademarkInput", None),
"remove-trademark": request.POST.get("removedTrademarks", None),
}
removed_trademarks = domain_data["remove-trademark"]
if removed_trademarks:
trademark_ids = removed_trademarks.split(",")
for trademark_id in trademark_ids:
Trademark.objects.filter(id=trademark_id).delete()

if domain_data["name"] is None:
messages.error(request, "Enter domain name")
Expand Down Expand Up @@ -697,6 +731,15 @@ def put(self, request, id, *args, **kwargs):

domain_managers = User.objects.filter(email__in=managers_list, is_active=True)
domain.managers.set(domain_managers)

trademark_name = domain_data["trademarkInput"]
if trademark_name:
trademark = Trademark.objects.create(
name=trademark_name,
domain=Domain.objects.get(id=domain_id),
)
trademark.save()

domain.save()

return redirect("company_manage_domains", id=id)
Expand Down Expand Up @@ -829,6 +872,7 @@ def get(self, request, pk, *args, **kwargs):
.order_by("-count")[:5]
)

trademarks = Trademark.objects.filter(domain__id=domain["id"])
# Get first and last bugs
first_bug = Issue.objects.filter(domain__id=domain["id"]).order_by("created").first()
last_bug = Issue.objects.filter(domain__id=domain["id"]).order_by("-created").first()
Expand All @@ -849,6 +893,7 @@ def get(self, request, pk, *args, **kwargs):
"first_bug": first_bug,
"last_bug": last_bug,
"ongoing_bughunts": ongoing_bughunts,
"trademarks": trademarks,
}

return render(request, "company/view_domain.html", context)
Expand Down
Loading
Loading