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

Login API's for DevAuthBackEnd for Android project #851

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 49 additions & 0 deletions zerver/tests/test_auth_backends.py
Expand Up @@ -195,3 +195,52 @@ def test_deactivated_realm(self):
dict(username=self.email,
password=initial_password(self.email)))
self.assert_json_error_contains(result, "Your realm has been deactivated", 403)

class AndroidDevDirectLoginTest(AuthedTestCase):
def setUp(self):
# type: () -> None
self.email = "hamlet@zulip.com"
self.user_profile = get_user_profile_by_email(self.email)

def test_success(self):
# type: () -> None
result = self.client.post("/api/v1/dev_android_direct_login",
dict(username=self.email))
data = ujson.loads(result.content)
self.assertEqual(data.get("email"), self.email)
self.assertIsNotNone(data['api_key'])

def test_inactive_user(self):
# type: () -> None
do_deactivate_user(self.user_profile)
result = self.client.post("/api/v1/dev_android_direct_login",
dict(username=self.email))
self.assert_json_error_contains(result, "Your account has been disabled", 403)

def test_deactivated_realm(self):
# type: () -> None
do_deactivate_realm(self.user_profile.realm)
result = self.client.post("/api/v1/dev_android_direct_login",
dict(username=self.email))
self.assert_json_error_contains(result, "Your realm has been deactivated", 403)

def test_dev_auth_disabled(self):
# type: () -> None
with mock.patch('zerver.views.dev_auth_enabled', return_value=False):
result = self.client.post("/api/v1/dev_android_direct_login",
dict(username=self.email))
self.assert_json_error_contains(result, "Dev environment not enabled.", 400)

class AndroidDevGetEmailTest(AuthedTestCase):
def test_success(self):
# type: () -> None
result = self.client.get("/api/v1/dev_android_get_email")
self.assertIn("direct_admins", result.content)
self.assertIn("direct_users", result.content)
self.assert_json_success(result)

def test_dev_auth_disabled(self):
# type: () -> None
with mock.patch('zerver.views.dev_auth_enabled', return_value=False):
result = self.client.get("/api/v1/dev_android_get_email")
self.assert_json_error_contains(result, "Dev environment not enabled.", 400)
29 changes: 29 additions & 0 deletions zerver/views/__init__.py
Expand Up @@ -588,6 +588,35 @@ def dev_direct_login(request, **kwargs):
return HttpResponseRedirect("%s%s" % (settings.EXTERNAL_URI_SCHEME,
request.get_host()))

@csrf_exempt
@require_post
@has_request_variables
def api_dev_android_direct_login(request, username=REQ()):
# type: (HttpRequest, str) -> HttpResponse
# This function allows logging in without a password on Android app and should only be called in development
# environments. It may be called if the DevAuthBackend is included in settings.AUTHENTICATION_BACKENDS
if not dev_auth_enabled() or settings.PRODUCTION:
return json_error(_("Dev environment not enabled."))
return_data = {} # type: Dict[str, bool]
user_profile = authenticate(username=username, return_data=return_data)
if return_data.get("inactive_realm") == True:
return json_error(_("Your realm has been deactivated."), data={"reason": "realm deactivated"}, status=403)
if return_data.get("inactive_user") == True:
return json_error(_("Your account has been disabled."), data={"reason": "user disable"}, status=403)
login(request, user_profile)
return json_success({"api_key": user_profile.api_key, "email": user_profile.email})

@csrf_exempt
def api_android_get_dev_email(request):
# type: (HttpRequest) -> HttpResponse
if not dev_auth_enabled() or settings.PRODUCTION:
return json_error(_("Dev environment not enabled."))
MAX_DEV_BACKEND_USERS = 100 # type: int
users_query = UserProfile.objects.select_related().filter(is_bot=False, is_active=True)
users = users_query.order_by('email')[0:MAX_DEV_BACKEND_USERS]
return json_success(dict(direct_admins=[u.email for u in users if u.is_realm_admin],
direct_users=[u.email for u in users if not u.is_realm_admin]))

Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stylistically, we use just 1 newline between functions

@authenticated_json_post_view
@has_request_variables
def json_bulk_invite_users(request, user_profile,
Expand Down
4 changes: 2 additions & 2 deletions zproject/backends.py
Expand Up @@ -206,5 +206,5 @@ class DevAuthBackend(ZulipAuthMixin):
# Allow logging in as any user without a password.
# This is used for convenience when developing Zulip.

def authenticate(self, username):
return common_get_active_user_by_email(username)
def authenticate(self, username, return_data=None):
return common_get_active_user_by_email(username, return_data=return_data)
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you need to add the return_data argument here?

Copy link
Contributor Author

@kunall17 kunall17 Jun 17, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get the inactive_user and inactive_realm data as here

5 changes: 5 additions & 0 deletions zproject/urls.py
Expand Up @@ -140,6 +140,11 @@
# password/pair and returns an API key.
url(r'^api/v1/fetch_api_key$', 'api_fetch_api_key'),

# This is for the signing in through the devAuthBackEnd.
url(r'^api/v1/dev_android_direct_login$', 'api_dev_android_direct_login'),
# This is for fetching the emails of the admins and the users.
url(r'^api/v1/dev_android_get_email$', 'api_android_get_dev_email'),

# Used to present the GOOGLE_CLIENT_ID to mobile apps
url(r'^api/v1/fetch_google_client_id$', 'api_fetch_google_client_id'),

Expand Down