Esempio n. 1
0
def activate(activationId, dbInstance):
  response = ControllerResponse()
  table = dbUtils.getTable('users', dbInstance)
  items = []

  if table is None:
    MentiiLogging.getLogger().error('Unable to get table users in activate')
    response.addError('Could not access table. Error', 'The DB did not give us the table')
    return response

  #Scan for the email associated with this activationId
  scanResponse = dbUtils.scanFilter('activationId', activationId, table)

  if scanResponse is not None:
    #scanResponse is a dictionary that has a list of 'Items'
    items = scanResponse['Items']

  if not items or 'email' not in items[0].keys():
    response.addError('No user with activationid', 'The DB did not return a user with the passed in activationId')
  else:
    email = items[0]['email']

    jsonData = {
      'Key': {'email': email},
      'UpdateExpression': 'SET active = :a',
      'ExpressionAttributeValues': { ':a': 'T' },
      'ReturnValues' : 'UPDATED_NEW'
    }

    #Update using the email we have
    res = dbUtils.updateItem(jsonData, table)
    response.addToPayload('status', 'Success')

  return response
Esempio n. 2
0
def createClass(dynamoDBInstance, classData, email=None, userRole=None):
    response = ControllerResponse()

    #g will be not be available during testing
    #and email and userRole will need to be passed to the function
    if g:  # pragma: no cover
        email = g.authenticatedUser['email']
        userRole = g.authenticatedUser['userRole']
    #role is confirmed here incase createClass is called from somewhere other
    #than app.py create_class()
    if userRole != 'teacher' and userRole != 'admin':
        response.addError('Role error', 'Only teachers can create classes')
    elif classData is None or not checkClassDataValid(classData):
        response.addError('createClass call Failed.',
                          'Invalid class data given.')
    else:
        classTable = dbUtils.getTable('classes', dynamoDBInstance)
        userTable = dbUtils.getTable('users', dynamoDBInstance)
        if classTable is None or userTable is None:
            response.addError('createClass call Failed.',
                              'Unable to locate necessary table(s).')
        else:
            classCode = str(uuid.uuid4())
            newClass = {
                'code': classCode,
                'title': classData['title'],
                'description': classData['description']
            }

            if 'department' in classData.keys() and classData['department']:
                newClass['department'] = classData['department']
            if 'section' in classData.keys() and classData['section']:
                newClass['classSection'] = classData['section']

            result = dbUtils.putItem(newClass, classTable)

            if result is None:
                response.addError('createClass call Failed.',
                                  'Unable to create class in classes table.')
            else:
                # Note: if teaching attribute does not previously exist, a set of class codes will be created
                # otherwise, the class code will be added to the set of class codes
                codeSet = set([classCode])
                jsonData = {
                    'Key': {
                        'email': email
                    },
                    'UpdateExpression': 'ADD teaching :classCode',
                    'ExpressionAttributeValues': {
                        ':classCode': codeSet
                    },
                    'ReturnValues': 'UPDATED_NEW'
                }
                res = dbUtils.updateItem(jsonData, userTable)
                if res is None:
                    response.addError('createClass call failed',
                                      'Unable to update user data')
                else:
                    response.addToPayload('Success', 'Class Created')
    return response
Esempio n. 3
0
def updateUserTemplateHistory(classId, activity, userId, index, didSucceed,
                              dynamoDBInstance):
    #Get the section so we can update the weights
    response = ControllerResponse()
    bookId, chapterTitle, sectionTitle = getBookInfoFromActivity(
        classId, activity, dynamoDBInstance)
    section = book_ctrl.getSectionFromBook(bookId, chapterTitle, sectionTitle,
                                           dynamoDBInstance)
    #Update the weights or create new ones if this is the first time
    currentWeights = section.get('users', {}).get(userId, [])
    newWeights = [0 for _ in xrange(len(section.get('problems', [])))
                  ]  #Initial value
    if len(currentWeights) != 0:  #Update if we can
        newWeights = currentWeights
    #Actually update the weights
    if index < len(newWeights):
        if didSucceed:
            newWeights[index] += 1
        else:
            newWeights[index] -= 1
    #Send it elsewhere to update the database
    updateSuccessful = book_ctrl.updateBookWithUserData(
        bookId, chapterTitle, sectionTitle, userId, newWeights,
        dynamoDBInstance)
    if not updateSuccessful:
        response.addError('History Update Error',
                          'Unable to update the users history')

    return response
Esempio n. 4
0
def addActivity(classCode, jsonData, dynamodb, email=None, userRole=None):
    response = ControllerResponse()
    classTable = dbUtils.getTable('classes', dynamodb)

    if classTable is None:
        MentiiLogging.getLogger().error(
            'Unable to get classes table in getPublicClassList')
        response.addError('Failed to add activity', 'A database error occured')
    else:
        if g:  # pragma: no cover
            email = g.authenticatedUser['email']
            userRole = g.authenticatedUser['userRole']
        if isTeacherOfClass(email, userRole, classCode, dynamodb):
            classData = getClassByCode(classCode, dynamodb)
            if not classData:
                response.addError('Failed to add activity',
                                  'A database error occured')
            else:
                activities = classData.get('activities', [])
                activities.append(jsonData)
                classData['activities'] = activities
                result = dbUtils.putItem(classData, classTable)
                if result is None:
                    response.addError('Failed to add activity',
                                      'A database error occured')
                else:
                    response.addToPayload('Success', 'Activity Added')
        else:
            MentiiLogging.getLogger().error(
                email + ' is not the teacher of ' + classCode +
                ', but attempted to add an activity.')
            response.addError('Unable to add activity',
                              'A permissions error occured')
    return response
Esempio n. 5
0
def leaveClass(jsonData, dynamoDBInstance, email=None):
  response = ControllerResponse()
  data = None
  if g: # pragma: no cover
    email = g.authenticatedUser['email']
  if 'code' not in jsonData.keys() or not jsonData['code']:
    response.addError('Key Missing Error', 'class code missing from data')
  else:
    classCode = jsonData['code']
    data = {
      'email': email,
      'classCode': classCode
    }
  return class_ctrl.removeStudent(dynamoDBInstance, data, response=response, userRole=None)
Esempio n. 6
0
def resetUserPassword(jsonData, dbInstance):
  response = ControllerResponse()
  email = jsonData.get('email', None)
  password = jsonData.get('password', None)
  resetPasswordId = jsonData.get('id', None)
  if email is not None and password is not None and resetPasswordId is not None:
    res = updatePasswordForEmailAndResetId(email, password, resetPasswordId, dbInstance)
    if res is not None:
      response.addToPayload('status', 'Success')
    else:
      response.addError('Failed to Reset Password', 'We were unable to update the password for this account.')
  else:
    response.addError('Failed to Reset Password', 'We were unable to update the password for this account.')
  return response
Esempio n. 7
0
def changeUserRole(jsonData, dbInstance, adminRole=None):
  response = ControllerResponse()

  #g will be not be available during testing
  #and adminRole will need to be passed to the function
  if g: # pragma: no cover
    adminRole = g.authenticatedUser['userRole']
  #adminRole is confirmed here incase changeUserRole is called from somewhere
  #other than app.py changeUserRole()
  if adminRole != 'admin':
    response.addError('Role Error', 'Only admins can change user roles')
  elif 'email' not in jsonData.keys() or 'userRole' not in jsonData.keys():
    response.addError('Key Missing Error', 'Email or role missing from json data')
  else:
    email = jsonData['email']
    userRole = jsonData['userRole']

    userTable = dbUtils.getTable('users', dbInstance)
    if userTable is None:
      MentiiLogging.getLogger().error('Unable to get table "users" in changeUserRole')
      response.addError('No Access to Data', 'Unable to get data from database')
    else:
      if userRole != 'student' and userRole != 'teacher' and userRole != 'admin':
        MentiiLogging.getLogger().error('Invalid role: ' + userRole + ' specified. Unable to change user role')
        response.addError('Invalid Role Type', 'Invaid role specified')
      else:

        data = {
            'Key': {'email': email},
            'UpdateExpression': 'SET userRole = :ur',
            'ExpressionAttributeValues': { ':ur': userRole },
            'ReturnValues' : 'UPDATED_NEW'
        }

        result = dbUtils.updateItem(data, userTable)

        if result is None:
          MentiiLogging.getLogger().error('Unable to update the user with email: ' + email + ' in changeUserRole')
          response.addError('Result Update Error', 'Could not update the user role in database')
        else:
          response.addToPayload('Result:', result)
          response.addToPayload('success', 'true')

  return response
Esempio n. 8
0
def getPublicClassList(dynamodb, email=None):
    response = ControllerResponse()
    classCodes = getClassCodesFromUser(dynamodb, email)
    classes = []
    classesTable = dbUtils.getTable('classes', dynamodb)
    if classesTable is None:
        MentiiLogging.getLogger().error(
            'Unable to get classes table in getPublicClassList')
        response.addError('Failed to get class list',
                          'A database error occured')
    else:
        res = classesTable.scan()
        for pclass in res.get('Items', []):
            if pclass[
                    'code'] not in classCodes and 'private' not in pclass and pclass.get(
                        'private') != True:
                classes.append(pclass)
        response.addToPayload('classes', classes)
    return response
Esempio n. 9
0
def getProblemTree(problemTemplate):
    #When problem templates work problem could
    # be a problem template instead. If that's the case
    # we could get the problem from the template here
    response = ControllerResponse()
    numberOfFailurePoints = 2  #TODO: Replace this with the recommender system output
    problem = getProblem(problemTemplate)
    problemPath = mathsteps.getStepsForProblem(problem)
    if len(problemPath) <= 1:
        #We couldn't get a path for the problem
        response.addError(
            'Problem Solve Error',
            'Could not generate path for problem {0}'.format(problem))
    else:
        problemTree = generateTreeWithBadSteps(problemPath,
                                               numberOfFailurePoints)
        response.addToPayload('problemTree', problemTree)

    return response
Esempio n. 10
0
def getBookList(dynamoDBInstance):
    response = ControllerResponse()
    booksTable = dbUtils.getTable('books', dynamoDBInstance)
    if booksTable is None:
        MentiiLogging.getLogger().error('Could not get book table')
        response.addError('Failed to get book list',
                          'A database error occured')
    else:
        books = dbUtils.scan(booksTable)
        bookList = []
        if books is not None and 'Items' in books:
            for book in books.get('Items'):
                bookList.append({
                    'id': book.get('bookId'),
                    'title': book.get('title')
                })
            response.addToPayload('books', bookList)
        else:
            MentiiLogging.getLogger().warning('Could not scan books table')
    return response
Esempio n. 11
0
def joinClass(jsonData, dynamoDBInstance, email=None, userRole=None):
  response = ControllerResponse()
  #g will be not be available during testing
  #and email will need to be passed to the function
  if g: # pragma: no cover
    email = g.authenticatedUser['email']
    userRole = g.authenticatedUser['userRole']

  if 'code' not in jsonData.keys() or not jsonData['code']:
    response.addError('Key Missing Error', 'class code missing from data')
  elif userRole == 'teacher' or userRole == 'admin':
    if class_ctrl.isCodeInTaughtList(jsonData, dynamoDBInstance, email):
      response.addError('Role Error', 'Teachers cannot join their taught class as a student')
    else:
      classCode = jsonData['code']
      addDataToClassAndUser(classCode, email, response, dynamoDBInstance)
  else:
    classCode = jsonData['code']
    addDataToClassAndUser(classCode, email, response, dynamoDBInstance)
  return response
Esempio n. 12
0
def getTaughtClassList(dynamoDBInstance, email=None):
    response = ControllerResponse()
    if email is None:  # pragma: no cover
        email = g.authenticatedUser['email']
    usersTable = dbUtils.getTable('users', dynamoDBInstance)
    classTable = dbUtils.getTable('classes', dynamoDBInstance)
    if usersTable is None or classTable is None:
        response.addError('Get Taught Class List Failed',
                          'Unable to access users and/or classes')
    else:
        classes = []
        classCodes = getTaughtClassCodesFromUser(dynamoDBInstance, email)
        if classCodes is not None:
            for code in classCodes:
                request = {'Key': {'code': code}}
                res = dbUtils.getItem(request, classTable)
                if res is not None and 'Item' in res:
                    classes.append(res['Item'])
        response.addToPayload('classes', classes)
    return response
Esempio n. 13
0
def getClass(classCode, dynamoDBInstance, email=None, userRole=None):
    response = ControllerResponse()
    classData = getClassByCode(classCode, dynamoDBInstance)
    if not classData:
        response.addError('Get Class Failed', 'Unable to load class data')
    else:
        if g:  # pragma: no cover
            email = g.authenticatedUser['email']
            userRole = g.authenticatedUser['userRole']
        #Checks that user is the teacher of the class w/ classCode
        if ((userRole == 'teacher' or userRole == 'admin')
                and classCode in getTaughtClassCodesFromUser(
                    dynamoDBInstance, email)):
            classData['isTeacher'] = True
        #Else remove students[] from classData, if it exists, because:
        #Only the teacher of a class can get the class's students
        elif 'students' in classData:
            if email in classData.get('students', []):
                classData['isStudent'] = True
            del classData['students']
        response.addToPayload('class', classData)
    return response
Esempio n. 14
0
def register(httpOrigin, jsonData, mailer, dbInstance):
  response = ControllerResponse()
  if not validateRegistrationJSON(jsonData):
    response.addError('Register Validation Error', 'The json data did not have an email or did not have a password')
  else:
    email = parseEmail(jsonData)
    password = parsePassword(jsonData)

    if not isEmailValid(email):
      response.addError('Email invalid', 'The email is invalid')

    if not isPasswordValid(password):
      response.addError('Password Invalid', 'The password is invalid')

    if isEmailInSystem(email, dbInstance) and isUserActive(getUserByEmail(email, dbInstance)):
      response.addError('Registration Failed', 'We were unable to register this user')

    if not response.hasErrors():
      hashedPassword = hashPassword(parsePassword(jsonData))
      activationId = addUserAndSendEmail(httpOrigin, email, hashedPassword, mailer, dbInstance)
      if activationId is None:
        response.addError('Activation Id is None', 'Could not create an activation Id')

  return response
Esempio n. 15
0
def removeStudent(dynamoDBInstance, jsonData, response=None, userRole=None):
    currentUserEmail = None
    if response is None:
        response = ControllerResponse()
    email = jsonData.get('email')
    classCode = jsonData.get('classCode')
    if g:
        userRole = g.authenticatedUser['userRole']
        currentUserEmail = g.authenticatedUser['email']
    if not (userRole == 'teacher' or userRole == 'admin'
            or currentUserEmail == email):
        response.addError(
            'Role error',
            'Only those with teacher privileges can remove students from classes'
        )
    elif email is None or classCode is None:
        response.addError('Failed to remove student from class',
                          'Invalid data given')
    else:
        removeClassFromStudent(dynamoDBInstance, response, email, classCode)
        if not response.hasErrors():
            removeStudentFromClass(dynamoDBInstance, response, email,
                                   classCode)
    return response
Esempio n. 16
0
def createBook(bookData, dynamoDBInstance, userRole=None):
    response = ControllerResponse()

    #g will be not be available during testing
    #userRole will need to be passed to the function
    if g:  # pragma: no cover
        userRole = g.authenticatedUser['userRole']
    #role is confirmed here incase createBook is called from somewhere other
    #than app.py createBook()
    if userRole != 'admin':
        response.addError('Role error', 'Only admins can create books')
    # check for required options
    elif 'title' not in bookData.keys() or 'description' not in bookData.keys(
    ):
        response.addError('Book creation failed.', 'Invalid book data given.')
    else:
        # Get books table
        booksTable = dbUtils.getTable('books', dynamoDBInstance)
        if booksTable is None:
            response.addError('Get Books Table Failed',
                              'Unable to get books table from database')
        else:
            bookId = str(uuid.uuid4())
            # prep json data
            book = {
                'bookId': bookId,
                'title': bookData['title'],
                'description': bookData['description'],
                'chapters': bookData.get('chapters', [])
            }
            # put item into table
            result = dbUtils.putItem(book, booksTable)
            if result is None:
                response.addError('Book creation failed.',
                                  'Unable to create Book in database.')
            else:
                response.addToPayload('Success', 'Book Created')

    return response
Esempio n. 17
0
def editBook(bookData, dynamoDBInstance):
    response = ControllerResponse()
    # check for required options
    if not bookData or 'title' not in bookData.keys(
    ) or 'description' not in bookData.keys() or 'bookId' not in bookData.keys(
    ):
        response.addError('Book update failed.', 'Invalid book data given.')
    else:
        # Get books table
        booksTable = dbUtils.getTable('books', dynamoDBInstance)
        if booksTable is None:
            response.addError('Get Books Table Failed',
                              'Unable to get books table from database')
        else:
            # put item into table
            result = dbUtils.putItem(bookData, booksTable)
            if result is None:
                response.addError('Book update failed.',
                                  'Unable to update Book in database.')
            else:
                response.addToPayload('Success', 'Book Updated')

    return response
Esempio n. 18
0
def updateClassDetails(jsonData, dynamodb, email=None, userRole=None):
    response = ControllerResponse()
    classesTable = dbUtils.getTable('classes', dynamodb)

    if classesTable is None:
        MentiiLogging.getLogger().error(
            'Unable to get classes table in getPublicClassList')
        response.addError('Failed to get class list',
                          'A database error occured')
    else:
        # get data from request body
        code = jsonData.get('code')
        title = jsonData.get('title')
        desc = jsonData.get('description')
        dept = jsonData.get('department')  # optional
        sec = jsonData.get('section')  # optional

        if g:  # pragma: no cover
            email = g.authenticatedUser['email']
            userRole = g.authenticatedUser['userRole']
        #check if teacher is teacher of the class
        if ((userRole == 'teacher' or userRole == 'admin')
                and code in getTaughtClassCodesFromUser(dynamodb, email)):

            updateExprString = 'SET title =:t, description =:dn'
            expresionAttrDict = {':t': title, ':dn': desc}

            removeString = ''
            # if empty string is given, remove the attribute
            if dept == '' and sec == '':
                removeString = removeString + ' REMOVE department, classSection'
            else:
                if dept == '':
                    removeString = removeString + ' REMOVE department'
                else:
                    updateExprString = updateExprString + ', department = :dt'
                    expresionAttrDict[':dt'] = dept
                if sec == '':
                    removeString = removeString + ' REMOVE classSection'
                else:
                    updateExprString = updateExprString + ', classSection = :s'
                    expresionAttrDict[':s'] = sec

            updateExprString = updateExprString + removeString

            # update item
            updateData = {
                'Key': {
                    'code': code
                },
                'UpdateExpression': updateExprString,
                'ExpressionAttributeValues': expresionAttrDict,
                'ReturnValues': 'UPDATED_NEW'
            }

            res = dbUtils.updateItem(updateData, classesTable)
            if res is None:
                response.addError('updateClassDetails has error',
                                  'Unable to update class details')
            else:
                response.addToPayload('Success', 'Class Details Updated')
        else:
            response.addError('Teacher permissions incorrect',
                              'Unable to update class details')
    return response