Skip to content

Commit

Permalink
Merge pull request #249 from istresearch/develop into main
Browse files Browse the repository at this point in the history
v4.0.13.1
  • Loading branch information
baracudda authored Apr 8, 2022
2 parents 7686b1e + 9625c99 commit c94035d
Show file tree
Hide file tree
Showing 27 changed files with 643 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
BRANCH=${CIRCLE_BRANCH#*/}
VERSION_STR=$(cat VERSION)
if [[ -n $CIRCLE_TAG ]]; then
VERSION_TAG="${CIRCLE_TAG}"
VERSION_TAG="${CIRCLE_TAG#*v}"
elif [[ "$BRANCH" == "develop" ]]; then
VERSION_TAG="${VERSION_STR}-dev"
elif [[ "$BRANCH" != "master" ]]; then
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.0.13
4.0.13.1
29 changes: 22 additions & 7 deletions docker/customizations/any/static/less/engage.less
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ body {

#splash {
/* margin-top: -30px; */
background: url("/sitestatic/brands/engage/images/splash.png") !important;
background: url("../images/splash.png") !important;
background-size: cover !important;
width: 100%;
height: 0px;
Expand Down Expand Up @@ -247,11 +247,11 @@ temba-modax > div.send-via-btn {
}
}
temba-modax#send-via-pm_element > div.send-via-btn {
background: url("/sitestatic/engage/img/element-chat.svg");
background: url("../../../engage/img/element-chat.svg");
background-size: 16px;
}
temba-modax#send-via-pm_signal > div.send-via-btn {
background: url("/sitestatic/engage/img/signal-chat.svg");
background: url("../../../engage/img/signal-chat.svg");
background-size: 16px;
}
/* ----------------------------------------------------*/
Expand Down Expand Up @@ -288,10 +288,20 @@ temba-modax#send-via-pm_signal > div.send-via-btn {
align-self: start;
margin-right: 1em;
cursor: pointer;
background-image: url("../../../engage/img/house-door.svg");
background-position: center;
background-repeat: no-repeat;
background-size: contain;
filter: invert(1);
height: 28px;
width: 28px;
border-width: 2px;
/* desire icon, not this emoji
&:after {
content: "🏠";
font-size: large;
}
*/
}

#org-name {
Expand All @@ -313,20 +323,20 @@ temba-modax#send-via-pm_signal > div.send-via-btn {
.state-disabled {
text-decoration: line-through;
}
.state-icon .state-disabled {
.state-icon.state-disabled {
text-decoration: unset;
padding-left: 0.5em;
&:after {
content: "🚫";
}
}
.state-icon .state-suspended {
.state-icon.state-suspended {
padding-left: 0.5em;
&:after {
content: "⚠️";
}
}
.state-icon .state-flagged {
.state-icon.state-flagged {
padding-left: 0.5em;
&:after {
content: "🚩";
Expand All @@ -336,4 +346,9 @@ temba-modax#send-via-pm_signal > div.send-via-btn {
}
@import "select2-theme-org-picker";


#assign-user-to-org-picker-widget #select2-id_organization-container {
min-width: 15em;
}
#assign-user-name .controls {
display: inline-block;
}
4 changes: 2 additions & 2 deletions docker/customizations/any/temba/channels/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ def get_gear_links(self):
dict(
id="action-purge",
title="Purge Outbox",
as_btn="true",
as_btn=True,
js_class="button-danger",
)
)
Expand All @@ -788,7 +788,7 @@ def get_gear_links(self):
title=_("Edit"),
href=reverse("channels.channel_update", args=[self.object.id]),
modax=_("Edit Channel"),
as_btn="true", # used to determine if placed in hamburger menu or as its own button
as_btn=True, # used to determine if placed in hamburger menu or as its own button
)
)

Expand Down
7 changes: 6 additions & 1 deletion docker/customizations/any/temba/settings_engage.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@

INSTALLED_APPS = (
tuple(filter(lambda tup : tup not in env('REMOVE_INSTALLED_APPS', '').split(','), INSTALLED_APPS)) + (
'engage.utils',
'engage.api',
'engage.auth',
'engage.channels',
'engage.contacts',
'engage.msgs',
'engage.orgs',
'engage.utils',
) + tuple(filter(None, env('EXTRA_INSTALLED_APPS', '').split(',')))
)

Expand Down
20 changes: 8 additions & 12 deletions docker/customizations/any/templates/frame.haml
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,10 @@
-if not COMPONENTS_DEV_MODE
-include "components-head.html"
-# Favicon works without the need to be explicit
-# -if brand.favico
-# %link{type:"image/ico", rel:"shortcut icon", href:"{% static brand.favico %}"}
-# -else
-# %link{type:"image/ico", rel:"shortcut icon", href:"{% static 'images/favicon.ico' %}"}
-if brand.favico
%link{type:"image/ico", rel:"shortcut icon", href:"{% static brand.favico %}"}
-else
%link{type:"image/ico", rel:"shortcut icon", href:"{% static 'images/favicon.ico' %}"}
-block styles
-# do not want to use non-local fonts
Expand Down Expand Up @@ -111,6 +110,7 @@
-compress css
%link{rel:"stylesheet", href:"{% static 'css/tailwind.css' %}", type:"text/css"}
%link{rel:"stylesheet", href:"{% static 'less/refresh.less' %}", type:"text/less"}
%link{rel:"stylesheet", href:"{% static 'engage/less/frame.less' %}", type:"text/less"}
-if brand.final_style
%link{rel:"stylesheet", href:"{% static brand.final_style %}", type:"text/less"}
Expand Down Expand Up @@ -162,14 +162,12 @@
-block nav
-include 'includes/nav.html'
-if messages
-block messages
-for msg in messages
%div{class:"alert alert-{{ message.tags }}"}
%div{class:"blert blert-{{ msg.tags }}"}
{{ msg }}
-block post-header
<!-- Content -->
-block page-container
Expand Down Expand Up @@ -198,7 +196,6 @@
-block post-title
.mt-6
-block content
Expand All @@ -223,10 +220,9 @@
:javascript
var org_home_url_format = '{% url "orgs.org_home" %}?org=%s';
var org_chosen_url_format = '{% url "orgs.org_choose" %}?organization=%s';
{% if user.is_superuser %}
var org_chosen_url_format = '{% url "orgs.org_service" %}?organization=%s';
{% else %}
var org_chosen_url_format = '{% url "orgs.org_choose" %}?organization=%s';
var org_service_url_format = '{% url "orgs.org_service" %}?organization=%s';
{% endif %}
{% if user_org %}
{% if user_org.is_anon %}
Expand Down
11 changes: 11 additions & 0 deletions engage/auth/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.apps import AppConfig as BaseAppConfig

default_app_config = 'engage.auth.AppConfig'

class AppConfig(BaseAppConfig):
"""
django app labels must be unique; so override AppConfig to ensure uniqueness
"""
name = "engage.auth"
label = "engage_auth"
verbose_name = "Engage Auth"
125 changes: 125 additions & 0 deletions engage/auth/account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
"""
Django provides a means to override the default User class, but if you started
you project before such a means was provided, it's really a lot of work to
subclass. RP decided to just continue with the Monkey Patch method of hacking
in methods and properties they want to add to the User class as defined in
temba.orgs.models. Monkey Patching is invisible to our IDEs, however, so to
help developers, this static utilities class was created so we could at least
_FIND_ what kinds of added methods were available. You can then either call
the appropriate method on the User object directly, or you can use these
static methods: e.g. user_obj.get_org() vs UserAcct.get_org(user_obj)
"""


class UserAcct:
"""
Provide a means to extend the Django User class without replacing it.
Alternative means to accessing the monkey patches made to User class.
"""
@staticmethod
def is_allowed(user, permission) -> bool:
"""
NOT AVAILABLE ON THE User OBJECT ITSELF!
Check to see if we have the perimssion naturally, then if org is
defined, check there, too.
:param user: The User object.
:param permission: A permission to check.
:return: Returns True if permission is granted.
"""
if user.has_perm(permission):
return True
org = user.get_org()
if org:
return user.has_org_perm(org, permission)
return False

#### EVERYTHING BELOW THIS LINE IS A MONKEY PATCH PASSTHRU CALL ============

@staticmethod
def release(user, releasing_user, *, brand):
"""
Releases this user, and any orgs of which they are the sole owner
"""
return user.release(releasing_user, brand=brand)

@staticmethod
def get_org(user):
return user.get_org()

@staticmethod
def set_org(user, org):
return user.set_org(org)

@staticmethod
def is_alpha(user) -> bool:
return user.is_alpha()

@staticmethod
def is_beta(user) -> bool:
return user.is_beta()

@staticmethod
def is_support(user) -> bool:
return user.is_support()

@staticmethod
def get_user_orgs(user, brands=None):
return user.get_user_orgs(brands)

@staticmethod
def get_org_group(user):
return user.get_org_group()

@staticmethod
def get_owned_orgs(user, brands=None):
"""
Gets all the orgs where this is the only user for the current brand
"""
return user.get_owned_orgs(brands)

@staticmethod
def has_org_perm(user, org, permission) -> bool:
"""
Determines if a user has the given permission in this org
"""
return user.has_org_perm(org, permission)

@staticmethod
def get_settings(user):
"""
Gets or creates user settings for this user
"""
return user.get_settings()

@staticmethod
def record_auth(user):
return user.record_auth()

@staticmethod
def enable_2fa(user):
"""
Enables 2FA for this user
"""
return user.enable_2fa()

@staticmethod
def disable_2fa(user):
"""
Disables 2FA for this user
"""
return user.disable_2fa()

@staticmethod
def verify_2fa(user, *, otp: str = None, backup_token: str = None) -> bool:
"""
Verifies a user using a 2FA mechanism (OTP or backup token)
"""
return user.verify_2fa(otp=otp, backup_token=backup_token)

@staticmethod
def as_engine_ref(user) -> dict:
return user.as_engine_ref()

@staticmethod
def name_of(user) -> str:
return user.name
6 changes: 6 additions & 0 deletions engage/channels/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

class ManageChannelMixin:

@classmethod
def get_actions(cls):
return (
"manage",
)

class Manage(OrgPermsMixin, SmartListView):
paginate_by = settings.PAGINATE_CHANNELS_COUNT
title = _("Manage Channels")
Expand Down
21 changes: 14 additions & 7 deletions engage/channels/purge_outbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@
from temba.orgs.views import OrgPermsMixin
from temba.utils import json

from engage.auth.account import UserAcct
from engage.utils import get_required_arg
from engage.utils.logs import OrgPermLogInfoMixin


class PurgeOutboxMixin:

@classmethod
def get_actions(cls):
return (
"purge_outbox",
)

class PurgeOutbox(OrgPermLogInfoMixin, OrgPermsMixin, View): # pragma: no cover
permission = "msgs.broadcast_send"

Expand All @@ -24,26 +31,26 @@ def derive_url_pattern(cls, path, action):

def dispatch(self, request: HttpRequest, *args, **kwargs):
# non authenticated users without orgs get an error (not the org chooser)
user = request.user
user = self.get_user()
if not user.is_authenticated:
return HttpResponse('Not authorized', status=401)

return super().dispatch(request, *args, **kwargs)

def get(self, request, *args, **kwargs):
def get(self, request: HttpRequest, *args, **kwargs):
logger = logging.getLogger(__name__)

user = self.get_user()
if user.is_authenticated and not user.derive_org():
if not UserAcct.get_org(user):
theOrgPK = request.GET.get('org')
if theOrgPK:
org = Org.objects.filter(id=theOrgPK).first()
if org is not None:
user.set_org(org)
if not user.derive_org():
UserAcct.set_org(user, org)
if not UserAcct.get_org(user):
return HttpResponse('Org ambiguous, please specify', status=400)

if not user.has_org_perm(self.permission):
if not UserAcct.is_allowed(user, self.permission):
return HttpResponse('Forbidden', status=403)

# ensure we have the necessary args
Expand Down Expand Up @@ -75,7 +82,7 @@ def get(self, request, *args, **kwargs):
'channel_type': theChannelType,
'channel_uuid': theChannelUUID,
'status_code': r.status_code,
'message': theMessage,
'courier_response': theMessage,
}))
return HttpResponse(f"The courier service returned with status {r.status_code}: {theMessage}")
except ConnectionError as ex:
Expand Down
Loading

0 comments on commit c94035d

Please sign in to comment.