Skip to content

Commit

Permalink
Fix part of oppia#5002: Move user related variables form GLOBALS (opp…
Browse files Browse the repository at this point in the history
…ia#5659)

* Add UserInfoHandler

* Retrieve permission related info from handler

* Change docs for UserInfoHandler

* Move can_create_collections from GLOBALS

* Add caching to getUserInfoAsync

* Move preferredSiteLAnguageCode from GLOBALS

* Move username variable from GLOBALS

* Move part of userIsLoggedIn variable from GLOBALS

* Remove variables in base.html

* Remove permission related variables from base.py values

* Make userInfo into variable

* Refactor admin page navbar

* Revert some changes in base.py to fix tests

* Fix top nav bar

* Refactor CreateActivityButtonDirective

* Refactor Library

* Fix exploration creating error

* Add loading for user info request

* Rework promises

* Rework imports

* Add undefined state for top bar

* Add UseInfo domain object

* Use === instead of ==

* Improve UserInfo domain object

* Remove default info from profile info handler

* Use user info domain object everywhere

* Fix admin page

* Fix getUsername in admin

* Fix promise waits

* Fix create button showing twice

* Fix linting

* Change acces handler for profile

* Add UserInfoHandlerTests

* Add default values for create_button

* Add default values

* Fix linting

* UserInfoFactory refactor and tests

* UserInfoFactory refactor and tests
  • Loading branch information
vojtechjelinek authored and seanlip committed Nov 4, 2018
1 parent 8936be4 commit c77b54a
Show file tree
Hide file tree
Showing 37 changed files with 765 additions and 445 deletions.
Empty file added Makefile
Empty file.
12 changes: 1 addition & 11 deletions core/controllers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
from core.domain import config_domain
from core.domain import config_services
from core.domain import rights_manager
from core.domain import role_services
from core.domain import user_services
from core.platform import models
import feconf
Expand Down Expand Up @@ -156,7 +155,6 @@ def __init__(self, request, response): # pylint: disable=super-init-not-called
self.username = None
self.has_seen_editor_tutorial = False
self.partially_logged_in = False
self.preferred_site_language_code = None

if self.user_id:
user_settings = user_services.get_user_settings(
Expand All @@ -174,8 +172,6 @@ def __init__(self, request, response): # pylint: disable=super-init-not-called
self.user_id = None
else:
self.username = user_settings.username
self.preferred_site_language_code = (
user_settings.preferred_site_language_code)
self.values['username'] = self.username
if user_settings.last_started_state_editor_tutorial:
self.has_seen_editor_tutorial = True
Expand Down Expand Up @@ -245,9 +241,7 @@ def dispatch(self):
'Your session has expired, and unfortunately your '
'changes cannot be saved. Please refresh the page.')
except Exception as e:
logging.error(
'%s: payload %s',
e, self.payload)
logging.error('%s: payload %s', e, self.payload)

self.handle_exception(e, self.app.debug)
return
Expand Down Expand Up @@ -332,12 +326,8 @@ def render_template(
# The 'path' variable starts with a forward slash.
'FULL_URL': '%s://%s%s' % (scheme, netloc, path),
'SITE_FEEDBACK_FORM_URL': feconf.SITE_FEEDBACK_FORM_URL,
'can_create_collections': bool(
role_services.ACTION_CREATE_COLLECTION in self.user.actions),
'username': self.username,
'user_is_logged_in': user_services.has_fully_registered(
self.user_id),
'preferred_site_language_code': self.preferred_site_language_code,
'allow_yaml_file_upload': feconf.ALLOW_YAML_FILE_UPLOAD
})
if feconf.ENABLE_PROMO_BAR:
Expand Down
31 changes: 31 additions & 0 deletions core/controllers/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
from core.controllers import base
from core.domain import acl_decorators
from core.domain import email_manager
from core.domain import role_services
from core.domain import subscription_services
from core.domain import summary_services
from core.domain import user_services
from core.platform import models
import feconf
import utils

current_user_services = models.Registry.import_current_user_services()


class ProfilePage(base.BaseHandler):
"""The world-viewable profile page."""
Expand Down Expand Up @@ -364,3 +368,30 @@ def put(self):
user_services.update_preferred_site_language_code(
self.user_id, site_language_code)
self.render_json({})


class UserInfoHandler(base.BaseHandler):
"""Provides info about user."""

GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON

@acl_decorators.require_user_id
def get(self):
"""Handles GET requests."""

user_actions = user_services.UserActionsInfo(self.user_id).actions
user_settings = user_services.get_user_settings(
self.user_id, strict=False)
self.render_json({
'is_moderator': (
user_services.is_at_least_moderator(self.user_id)),
'is_admin': user_services.is_admin(self.user_id),
'is_super_admin': (
current_user_services.is_current_user_super_admin()),
'can_create_collections': bool(
role_services.ACTION_CREATE_COLLECTION in user_actions),
'preferred_site_language_code': (
user_settings.preferred_site_language_code),
'username': user_settings.username,
'user_is_logged_in': True
})
22 changes: 22 additions & 0 deletions core/controllers/profile_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -686,3 +686,25 @@ def test_user_bio_exceeds_limit(self):
self.assertIn('User bio exceeds maximum character limit: 2000',
user_bio_response['error'])
self.logout()


class UserInfoHandlerTests(test_utils.GenericTestBase):

def test_user_info_handler(self):
"""Test the language is saved in the preferences when handler is
called.
"""
self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
self.login(self.EDITOR_EMAIL)
json_response = self.get_json('/userinfohandler')
self.assertDictContainsSubset({
'is_moderator': False,
'is_admin': False,
'is_super_admin': False,
'can_create_collections': False,
'username': self.EDITOR_USERNAME,
'user_is_logged_in': True}, json_response)
self.logout()

self.get_json('/userinfohandler', expect_errors=True,
expected_status_int=401)
26 changes: 26 additions & 0 deletions core/domain/acl_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,32 @@ def test_can_manage_question_skill_status(self, **kwargs):
return test_can_manage_question_skill_status


def require_user_id(handler):
"""Decorator that checks if a user_id is associated to the current
session. If not, NotLoggedInException is raised.
"""

def test_login(self, **kwargs):
"""Checks if the user for the current session is logged in.
If not, raises NotLoggedInException.
Args:
**kwargs: *. Keyword arguments.
Returns:
*. The return value of the decorated function.
Raises:
NotLoggedInException: The user is not logged in.
"""
if not self.user_id:
raise base.UserFacingExceptions.NotLoggedInException
return handler(self, **kwargs)
test_login.__wrapped__ = True

return test_login


def require_user_id_else_redirect_to_homepage(handler):
"""Decorator that checks if a user_id is associated to the current
session. If not, the user is redirected to the main page.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,13 @@ oppia.directive('outcomeDestinationEditor', [
templateUrl: UrlInterpolationService.getDirectiveTemplateUrl(
'/components/outcome_destination_editor_directive.html'),
controller: [
'$scope', 'StateEditorService',
'StateGraphLayoutService', 'PLACEHOLDER_OUTCOME_DEST',
'FocusManagerService', 'EditorFirstTimeEventsService',
'EXPLORATION_AND_SKILL_ID_PATTERN',
'$scope', 'EditorFirstTimeEventsService', 'FocusManagerService',
'StateEditorService', 'StateGraphLayoutService', 'UserService',
'EXPLORATION_AND_SKILL_ID_PATTERN', 'PLACEHOLDER_OUTCOME_DEST',
function(
$scope, StateEditorService,
StateGraphLayoutService, PLACEHOLDER_OUTCOME_DEST,
FocusManagerService, EditorFirstTimeEventsService,
EXPLORATION_AND_SKILL_ID_PATTERN) {
$scope, EditorFirstTimeEventsService, FocusManagerService,
StateEditorService, StateGraphLayoutService, UserService,
EXPLORATION_AND_SKILL_ID_PATTERN, PLACEHOLDER_OUTCOME_DEST) {
var currentStateName = null;
$scope.canAddPrerequisiteSkill = constants.ENABLE_NEW_STRUCTURES;

Expand All @@ -54,11 +52,15 @@ oppia.directive('outcomeDestinationEditor', [
}
});

// We restrict editing of refresher exploration IDs to
// admins/moderators for now, since the feature is still in
// development.
$scope.canEditRefresherExplorationId = (
GLOBALS.isAdmin || GLOBALS.isModerator);
$scope.canEditRefresherExplorationId = null;
UserService.getUserInfoAsync().then(function(userInfo) {
// We restrict editing of refresher exploration IDs to
// admins/moderators for now, since the feature is still in
// development.
$scope.canEditRefresherExplorationId = (
userInfo.isAdmin() || userInfo.isModerator());
});

$scope.explorationAndSkillIdPattern =
EXPLORATION_AND_SKILL_ID_PATTERN;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,21 @@ oppia.directive('createActivityButton', [
controller: [
'$scope', '$timeout', '$window', '$uibModal',
'ExplorationCreationService', 'CollectionCreationService',
'SiteAnalyticsService', 'UrlService',
'SiteAnalyticsService', 'UrlService', 'UserService',
function(
$scope, $timeout, $window, $uibModal,
ExplorationCreationService, CollectionCreationService,
SiteAnalyticsService, UrlService) {
SiteAnalyticsService, UrlService, UserService) {
$scope.creationInProgress = false;

$scope.userIsLoggedIn = GLOBALS.userIsLoggedIn;
$scope.allowYamlFileUpload = GLOBALS.allowYamlFileUpload;

$scope.canCreateCollections = null;
$scope.userIsLoggedIn = null;
UserService.getUserInfoAsync().then(function(userInfo) {
$scope.canCreateCollections = userInfo.canCreateCollections();
$scope.userIsLoggedIn = userInfo.isLoggedIn();
});

$scope.showUploadExplorationModal = (
ExplorationCreationService.showUploadExplorationModal);

Expand All @@ -56,7 +61,7 @@ oppia.directive('createActivityButton', [

$scope.creationInProgress = true;

if (!GLOBALS.can_create_collections) {
if (!$scope.canCreateCollections) {
ExplorationCreationService.createNewExploration();
} else if (UrlService.getPathname() !== '/creator_dashboard') {
$window.location.replace('/creator_dashboard?mode=create');
Expand All @@ -69,6 +74,11 @@ oppia.directive('createActivityButton', [
controller: [
'$scope', '$uibModalInstance',
function($scope, $uibModalInstance) {
UserService.getUserInfoAsync().then(function(userInfo) {
$scope.canCreateCollections = (
userInfo.canCreateCollections());
});

$scope.chooseExploration = function() {
ExplorationCreationService.createNewExploration();
$uibModalInstance.close();
Expand All @@ -79,10 +89,6 @@ oppia.directive('createActivityButton', [
$uibModalInstance.close();
};

$scope.canCreateCollections = (
GLOBALS.can_create_collections
);

$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
Expand All @@ -106,7 +112,7 @@ oppia.directive('createActivityButton', [
// open the create modal immediately (or redirect to the exploration
// editor if the create modal does not need to be shown).
if (UrlService.getUrlParams().mode === 'create') {
if (!GLOBALS.can_create_collections) {
if (!$scope.canCreateCollections) {
ExplorationCreationService.createNewExploration();
} else {
$scope.initCreationProcess();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<div class="oppia-navbar-button-container">
<!-- User must complete the registration process. -->
<button class="btn oppia-navbar-button oppia-navbar-hide-on-small-width protractor-test-create-activity oppia-transition-200"
ng-click="onRedirectToLogin('/creator_dashboard?mode=create')" ng-if="!userIsLoggedIn">
ng-click="onRedirectToLogin('/creator_dashboard?mode=create')" ng-if="userIsLoggedIn === false">
<!-- "userIsLoggedIn === false" is needed because we want to show the button when we know that user is not logged in
when userIsLoggedIn is undefined or null we don't want to show the button thus we can't use ""userIsLoggedIn"!-->
<span class="oppia-navbar-tab-content" translate="I18N_CREATE_EXPLORATION_CREATE"></span>
</button>
<button class="btn oppia-navbar-button oppia-navbar-hide-on-small-width protractor-test-create-activity oppia-transition-200"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,14 @@ oppia.directive('collectionSummaryTile', [
'/components/summary_tile/' +
'collection_summary_tile_directive.html'),
controller: [
'$scope', 'DateTimeFormatService',
'$scope', 'DateTimeFormatService', 'UserService',
'COLLECTION_VIEWER_URL', 'COLLECTION_EDITOR_URL', function(
$scope, DateTimeFormatService,
$scope, DateTimeFormatService, UserService,
COLLECTION_VIEWER_URL, COLLECTION_EDITOR_URL) {
$scope.userIsLoggedIn = GLOBALS.userIsLoggedIn;
$scope.userIsLoggedIn = null;
UserService.getUserInfoAsync().then(function(userInfo) {
$scope.userIsLoggedIn = userInfo.isLoggedIn();
});
$scope.DEFAULT_EMPTY_TITLE = 'Untitled';
$scope.ACTIVITY_TYPE_COLLECTION = constants.ACTIVITY_TYPE_COLLECTION;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,17 @@ oppia.directive('explorationSummaryTile', [
);
},
controller: [
'$scope', '$http', '$window',
'DateTimeFormatService', 'RatingComputationService',
'WindowDimensionsService', 'UrlService',
'$scope', '$http', '$window', 'DateTimeFormatService',
'RatingComputationService', 'UrlService', 'UserService',
'WindowDimensionsService',
function(
$scope, $http, $window,
DateTimeFormatService, RatingComputationService,
WindowDimensionsService, UrlService) {
$scope.userIsLoggedIn = GLOBALS.userIsLoggedIn;
$scope, $http, $window, DateTimeFormatService,
RatingComputationService, UrlService, UserService,
WindowDimensionsService) {
$scope.userIsLoggedIn = null;
UserService.getUserInfoAsync().then(function(userInfo) {
$scope.userIsLoggedIn = userInfo.isLoggedIn();
});
$scope.ACTIVITY_TYPE_EXPLORATION = (
constants.ACTIVITY_TYPE_EXPLORATION);
var contributorsSummary = $scope.getContributorsSummary() || {};
Expand Down
Loading

0 comments on commit c77b54a

Please sign in to comment.