Skip to content

Commit

Permalink
Merge/0706 (#12)
Browse files Browse the repository at this point in the history
* feature: creating dashboards, widgets and reports when a project its created

* feature: endpoint list dashboard

* feature: pin dashboard and list widgets in dashboard

* feature: pin dashboard

* feature: dashboard filters and get widget report

* feature: dashboard filters and get widget report

* feature: list sources from dashboard

* formating report serializer

* feature: changing base widget name type

* feat: fix settings

* feat: fix settings

* feat: fix static settings

* feat: fix project consumer

* feat: add openAPI and swagger

* feat: add django filters

* feat: instanciating create dashboard class and changing type name

* feat: rename dash to dashboard

* feat: add error treatment to project consumer

* feat: changing permission

* feature: config cors, fix in auth creation consumer and new permission to edit widgets

* feature: adding cors variable

* feat: dashboard constraint

* feat: formating json when creating dashboard, widgets and filters

* feat: formating if config is a list

* feat: is default true to human service dashboard

* feat: source endpoints

* feat: add rooms rest client

* feat: remove unused code

* feat: add user email to agents rest client as it's a needed param on the chats endpoint

* feat: remove dict_row and use dictfetchall as dict_row is not supported by django

* feat: fix get_cursor

* feat: fix dictfetchall

* feat: add query_args on queryexecutor and endpoint

feat: add chaturl var on settings

* feat: add project endpoint to router

* feat: rename action to operation

* feat: add widget data and report data actions on the dashboard endpoint

* feat: fix report data url path

* feat: add queryset to the project viewset

* feat: fix projectauthpermission

* feat: copy request data/params

* feat: remove json parser on query executor response

* feat: add limit to source config return in case of a timeseries_hour_group_count operation

* feat: fix error treatments

* feat: fix report creation

* feat: fix widget source names

* feat: remove try/except from get report/widget data

* feat: add return to project property on widget and report models ....

* feat: fix prev/next on rest queries

* feat: remove pagination from queries that return one field

* feat: remove tuple around nxt and prev

* feat: return the object if the list has only one index on dictfetchall

* feat: rename source data retrive endpoint

* feat: fix project filter

* feat: fix filter strategy

* feat: fix project

* feat: add isnull operation

* feat: return none on isnull

* feat: refactor isnull clause

* feat: refactor isnull clause

* feat: change field names on timeseries_hour_group_count query

* tempfeat: remove flow results dashboards from list

---------

Co-authored-by: AlanJaeger <[email protected]>
  • Loading branch information
helllllllder and AlanJaeger authored Jun 13, 2024
1 parent f3c594d commit 80c510f
Show file tree
Hide file tree
Showing 69 changed files with 2,219 additions and 78 deletions.
32 changes: 27 additions & 5 deletions insights/authentication/authentication.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import logging

from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from mozilla_django_oidc.auth import OIDCAuthenticationBackend

from insights.users.usecases import CreateUserUseCase

LOGGER = logging.getLogger("weni_django_oidc")

User = get_user_model()


def check_module_permission(claims, user):
if claims.get("can_communicate_internally", False):
content_type = ContentType.objects.get_for_model(User)
permission, created = Permission.objects.get_or_create(
codename="can_communicate_internally",
name="can communicate internally",
content_type=content_type,
)
if not user.has_perm("accounts.can_communicate_internally"):
user.user_permissions.add(permission)
return True
return False


class WeniOIDCAuthenticationBackend(OIDCAuthenticationBackend):
def verify_claims(self, claims):
Expand All @@ -18,14 +37,17 @@ def get_username(self, claims):
return username
return super(WeniOIDCAuthenticationBackend, self).get_username(claims=claims)

def create_user(self, claims):
# Override existing create_user method in OIDCAuthenticationBackend
email = claims.get("email")
return CreateUserUseCase().create_user(email)

def update_user(self, user, claims):
user.name = claims.get("name", "")
user.email = claims.get("email", "")
user.save()

return user

def create_user(self, claims):
email = claims.get("email")
user = CreateUserUseCase().create_user(email)

check_module_permission(claims, user)

return user
28 changes: 28 additions & 0 deletions insights/authentication/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from rest_framework import permissions
from rest_framework.exceptions import PermissionDenied

from insights.projects.models import Project, ProjectAuth


class ProjectAuthPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if type(obj) is Project:
project = obj
else:
project = obj.project

user = request.user
auth = ProjectAuth.objects.filter(project=project, user=user, role=1).first()
if not auth:
raise PermissionDenied("User does not have permission for this project")
return True


class WidgetAuthPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
project = obj.dashboard.project
user = request.user
auth = ProjectAuth.objects.filter(project=project, user=user, role=1).first()
if not auth:
raise PermissionDenied("User does not have permission for this project")
return True
18 changes: 18 additions & 0 deletions insights/dashboards/migrations/0002_dashboard_grid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.4 on 2024-05-29 20:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("dashboards", "0001_initial"),
]

operations = [
migrations.AddField(
model_name="dashboard",
name="grid",
field=models.JSONField(default=list, verbose_name="Grid"),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 5.0.4 on 2024-06-11 13:04

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("dashboards", "0002_dashboard_grid"),
("projects", "0001_initial"),
]

operations = [
migrations.RemoveConstraint(
model_name="dashboard",
name="unique_true_default_dashboard",
),
migrations.AddConstraint(
model_name="dashboard",
constraint=models.UniqueConstraint(
condition=models.Q(("is_default", True)),
fields=("project", "is_default"),
name="unique_default_dashboard_per_project",
),
),
]
7 changes: 3 additions & 4 deletions insights/dashboards/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,16 @@ class Dashboard(BaseModel, ConfigurableModel):
null=True,
blank=True,
)
grid = models.JSONField("Grid", default=list)

def __str__(self):
return f"{self.project.name} - {self.name}"

class Meta:
constraints = [
models.UniqueConstraint(
fields=[
"is_default",
],
fields=["project", "is_default"],
condition=models.Q(is_default=True),
name="unique_true_default_dashboard",
name="unique_default_dashboard_per_project",
)
]
66 changes: 66 additions & 0 deletions insights/dashboards/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from django.conf import settings
from rest_framework import serializers

from insights.dashboards.models import Dashboard
from insights.widgets.models import Report, Widget


class DashboardSerializer(serializers.ModelSerializer):
class Meta:
model = Dashboard
fields = ["uuid", "name", "is_default", "grid"]


class DashboardIsDefaultSerializer(serializers.ModelSerializer):
class Meta:
model = Dashboard
fields = ["is_default"]


class DashboardReportSerializer(serializers.ModelSerializer):
url = serializers.SerializerMethodField()
type = serializers.SerializerMethodField()

def get_url(self, obj):
config = obj.config

if isinstance(config, dict):
if config.get("external_url"):
return config["external_url"]
return f"{settings.INSIGHTS_DOMAIN}/v1/dashboards/{obj.widget.dashboard.uuid}/widgets/{obj.widget.uuid}/report/"
elif isinstance(config, list):
for item in config:
if isinstance(item, dict) and item.get("external_url"):
return item["external_url"]
return f"{settings.INSIGHTS_DOMAIN}/v1/dashboards/{obj.widget.dashboard.uuid}/widgets/{obj.widget.uuid}/report/"

def get_type(self, obj):
config = obj.config

if isinstance(config, dict) and config.get("external_url"):
return "external"

elif isinstance(config, list):
for item in config:
if isinstance(item, dict) and item.get("external_url"):
return "external"

return "internal"

class Meta:
model = Report
fields = ["url", "type"]


class ReportSerializer(serializers.ModelSerializer):
class Meta:
model = Report
fields = "__all__"


class DashboardWidgetsSerializer(serializers.ModelSerializer):
report = DashboardReportSerializer()

class Meta:
model = Widget
fields = "__all__"
Loading

0 comments on commit 80c510f

Please sign in to comment.