feat!: remove "Text Me the App" page from web app because of security concern
Someone at edx was able to quickly send a few texts to himself using the tool. Each text came from a different number and there was no message about the ability to unsubscribe or stop. This could potentially be used to spam users as well as potentially result in charges to edX for high volume. page url https://courses.edx.org/text-me-the-app LEARNER-8286
This commit is contained in:
@@ -13,8 +13,6 @@ from unittest.mock import patch
|
||||
import ddt
|
||||
from completion.test_utils import CompletionWaffleTestMixin, submit_completions_for_testing
|
||||
from django.conf import settings
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import now
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
@@ -886,13 +884,3 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
|
||||
|
||||
assert expected_button in dashboard_html
|
||||
assert unexpected_button not in dashboard_html
|
||||
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
@override_settings(BRANCH_IO_KEY='test_key')
|
||||
class TextMeTheAppViewTests(UrlResetMixin, TestCase):
|
||||
""" Tests for the TextMeTheAppView. """
|
||||
|
||||
def test_text_me_the_app(self):
|
||||
response = self.client.get(reverse('text_me_the_app'))
|
||||
self.assertContains(response, 'Send me a text with the link')
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
"""
|
||||
Fragment for rendering text me the app.
|
||||
"""
|
||||
|
||||
|
||||
from django.template.loader import render_to_string
|
||||
from web_fragments.fragment import Fragment
|
||||
|
||||
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
|
||||
|
||||
|
||||
class TextMeTheAppFragmentView(EdxFragmentView):
|
||||
"""
|
||||
A fragment to text me the app.
|
||||
|
||||
In future we can add this to learner dashboard.
|
||||
"""
|
||||
def render_to_fragment(self, request, **kwargs):
|
||||
"""
|
||||
Render text me the app fragment.
|
||||
"""
|
||||
html = render_to_string('learner_dashboard/text-me-fragment.html', {})
|
||||
return Fragment(html)
|
||||
@@ -69,7 +69,6 @@ from common.djangoapps.student.models import ( # lint-amnesty, pylint: disable=
|
||||
)
|
||||
from common.djangoapps.student.signals import REFUND_ORDER
|
||||
from common.djangoapps.student.tasks import send_activation_email
|
||||
from common.djangoapps.student.text_me_the_app import TextMeTheAppFragmentView
|
||||
from common.djangoapps.util.db import outer_atomic
|
||||
from common.djangoapps.util.json_request import JsonResponse
|
||||
from xmodule.modulestore.django import modulestore
|
||||
@@ -863,19 +862,3 @@ def change_email_settings(request):
|
||||
)
|
||||
|
||||
return JsonResponse({"success": True})
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def text_me_the_app(request):
|
||||
"""
|
||||
Text me the app view.
|
||||
"""
|
||||
text_me_fragment = TextMeTheAppFragmentView().render_to_fragment(request)
|
||||
context = {
|
||||
'nav_hidden': True,
|
||||
'show_dashboard_tabs': True,
|
||||
'show_program_listing': ProgramsApiConfig.is_enabled(),
|
||||
'fragment': text_me_fragment
|
||||
}
|
||||
|
||||
return render_to_response('text-me-the-app.html', context)
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
@import 'views/financial-assistance';
|
||||
@import 'course/auto-cert';
|
||||
@import 'views/api-access';
|
||||
@import 'views/text-me-the-app';
|
||||
|
||||
// features
|
||||
@import 'features/bookmarks-v1';
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
.text-me-content {
|
||||
box-sizing: border-box;
|
||||
|
||||
@include outer-container;
|
||||
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
background: $white;
|
||||
display: block;
|
||||
flex-wrap: wrap;
|
||||
-webkit-flex-wrap: wrap;
|
||||
-moz-flex-wrap: wrap;
|
||||
|
||||
.text-me-container {
|
||||
$grid-columns: 12;
|
||||
|
||||
background: $white;
|
||||
min-height: 100%;
|
||||
padding: ($baseline*6) ($baseline/2);
|
||||
display: block;
|
||||
max-width: 350px;
|
||||
min-width: 250px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.text-me-fragment {
|
||||
h2 {
|
||||
@extend %t-title4;
|
||||
|
||||
letter-spacing: normal;
|
||||
font-family: $font-family-sans-serif;
|
||||
color: $uxpl-blue-hover-active;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@extend %t-title6;
|
||||
@extend %t-light;
|
||||
|
||||
margin: 0;
|
||||
letter-spacing: normal;
|
||||
font-family: $font-family-sans-serif;
|
||||
color: $uxpl-gray-dark;
|
||||
}
|
||||
|
||||
form {
|
||||
@include clearfix();
|
||||
|
||||
clear: both;
|
||||
|
||||
.form-field {
|
||||
@include clearfix();
|
||||
|
||||
clear: both;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin: ($baseline/2) 0 0 0;
|
||||
|
||||
label,
|
||||
input {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
line-height: 1.5em;
|
||||
border-radius: 0;
|
||||
font-family: $font-family-sans-serif;
|
||||
font-style: normal;
|
||||
font-weight: font-weight(normal);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.action-primary {
|
||||
@extend %btn-primary-blue;
|
||||
|
||||
padding: 1ex 1em;
|
||||
text-transform: none;
|
||||
font-weight: font-weight(semi-bold);
|
||||
letter-spacing: normal;
|
||||
margin-top: $baseline;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
## mako
|
||||
|
||||
<%page expression_filter="h"/>
|
||||
|
||||
<%namespace name='static' file='/static_content.html'/>
|
||||
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from openedx.core.djangolib.js_utils import js_escaped_string
|
||||
%>
|
||||
|
||||
<%block name="headextra">
|
||||
<script type="text/javascript">
|
||||
(function(b,r,a,n,c,h,_,s,d,k){if(!b[n]||!b[n]._q){for(;s<_.length;)c(h,_[s++]);d=r.createElement(a);d.async=1;d.src="https://cdn.branch.io/branch-latest.min.js";k=r.getElementsByTagName(a)[0];k.parentNode.insertBefore(d,k);b[n]=h}})(window,document,"script","branch",function(b,r){b[r]=function(){b._q.push([r,arguments])}},{_q:[],_v:1},"addListener applyCode banner closeBanner creditHistory credits data deepview deepviewCta first getCode init link logout redeem referrals removeListener sendSMS setBranchViewData setIdentity track validateCode".split(" "), 0);
|
||||
branch.init('${static.get_value("BRANCH_IO_KEY", settings.BRANCH_IO_KEY) | n, js_escaped_string}');
|
||||
function sendSMS(form) {
|
||||
var phone = form.phone.value;
|
||||
var linkData = {
|
||||
tags: [],
|
||||
channel: 'Website',
|
||||
feature: 'TextMeTheApp',
|
||||
data: {}
|
||||
};
|
||||
var options = {};
|
||||
var callback = function(err, result) {
|
||||
if (err) {
|
||||
alert(gettext("Sorry, something went wrong."));
|
||||
}
|
||||
else {
|
||||
alert(gettext("SMS sent!"));
|
||||
}
|
||||
};
|
||||
branch.sendSMS(phone, linkData, options, callback);
|
||||
form.phone.value = "";
|
||||
}
|
||||
</script>
|
||||
</%block>
|
||||
|
||||
<section class="text-me-fragment">
|
||||
<h2>${_("Get the {platform_name} Mobile App!").format(platform_name=static.get_platform_name())}</h2>
|
||||
<h3>${_("We'll send you a one time SMS with a link to download the app.")}</h3>
|
||||
<form onsubmit="sendSMS(this); return false;">
|
||||
<div class="form-field">
|
||||
<label class="label">${_("Mobile phone number")}</label>
|
||||
<input id="phone" name="phone" type="tel" placeholder="+1 (123) 123-1234" />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<button class="action action-primary" type="submit">
|
||||
<span class="fa fa-send"></span>
|
||||
<span class="action-text">${_("Send me a text with the link")}</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
@@ -1,20 +0,0 @@
|
||||
## mako
|
||||
|
||||
<%page expression_filter="h"/>
|
||||
<%inherit file="main.html" />
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
%>
|
||||
|
||||
<%block name="title">
|
||||
<title>${_("Text Me The App")}</title>
|
||||
</%block>
|
||||
|
||||
<div class="text-me-content">
|
||||
<div class="container text-me-container">
|
||||
${HTML(fragment.body_html())}
|
||||
</div>
|
||||
</div>
|
||||
@@ -970,12 +970,6 @@ if settings.FEATURES.get('ENABLE_FINANCIAL_ASSISTANCE_FORM'):
|
||||
)
|
||||
]
|
||||
|
||||
# Branch.io Text Me The App
|
||||
if settings.BRANCH_IO_KEY:
|
||||
urlpatterns += [
|
||||
url(r'^text-me-the-app', student_views.text_me_the_app, name='text_me_the_app'),
|
||||
]
|
||||
|
||||
# API docs.
|
||||
urlpatterns += make_docs_urls(api_info)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user