class EmbargoedCourse(models.Model): """ Enable course embargo on a course-by-course basis. """ objects = NoneToEmptyManager() # The course to embargo course_id = CourseKeyField(max_length=255, db_index=True, unique=True) # Whether or not to embargo embargoed = models.BooleanField(default=False) @classmethod def is_embargoed(cls, course_id): """ Returns whether or not the given course id is embargoed. If course has not been explicitly embargoed, returns False. """ try: record = cls.objects.get(course_id=course_id) return record.embargoed except cls.DoesNotExist: return False def __unicode__(self): not_em = "Not " if self.embargoed: not_em = "" # pylint: disable=no-member return u"Course '{}' is {}Embargoed".format( self.course_id.to_deprecated_string(), not_em)
class CertificateWhitelist(models.Model): """ Tracks students who are whitelisted, all users in this table will always qualify for a certificate regardless of their grade unless they are on the embargoed country restriction list (allow_certificate set to False in userprofile). """ class Meta(object): app_label = "certificates" objects = NoneToEmptyManager() user = models.ForeignKey(User) course_id = CourseKeyField(max_length=255, blank=True, default=None) whitelist = models.BooleanField(default=0) created = CreationDateTimeField(_('created')) notes = models.TextField(default=None, null=True) @classmethod def get_certificate_white_list(cls, course_id, student=None): """ Return certificate white list for the given course as dict object, returned dictionary will have the following key-value pairs [{ id: 'id (pk) of CertificateWhitelist item' user_id: 'User Id of the student' user_name: 'name of the student' user_email: 'email of the student' course_id: 'Course key of the course to whom certificate exception belongs' created: 'Creation date of the certificate exception' notes: 'Additional notes for the certificate exception' }, {...}, ...] """ white_list = cls.objects.filter(course_id=course_id, whitelist=True) if student: white_list = white_list.filter(user=student) result = [] for item in white_list: result.append({ 'id': item.id, 'user_id': item.user.id, 'user_name': unicode(item.user.username), 'user_email': unicode(item.user.email), 'course_id': unicode(item.course_id), 'created': item.created.strftime("%A, %B %d, %Y"), 'notes': unicode(item.notes or ''), }) return result
class CertificateWhitelist(models.Model): """ Tracks students who are whitelisted, all users in this table will always qualify for a certificate regardless of their grade unless they are on the embargoed country restriction list (allow_certificate set to False in userprofile). """ objects = NoneToEmptyManager() user = models.ForeignKey(User) course_id = CourseKeyField(max_length=255, blank=True, default=None) whitelist = models.BooleanField(default=0)
class AnonymousUserId(models.Model): """ This table contains user, course_Id and anonymous_user_id Purpose of this table is to provide user by anonymous_user_id. We generate anonymous_user_id using md5 algorithm, and use result in hex form, so its length is equal to 32 bytes. """ objects = NoneToEmptyManager() user = models.ForeignKey(User, db_index=True) anonymous_user_id = models.CharField(unique=True, max_length=32) course_id = CourseKeyField(db_index=True, max_length=255, blank=True) unique_together = (user, course_id)
class CourseAccessRole(models.Model): """ Maps users to org, courses, and roles. Used by student.roles.CourseRole and OrgRole. To establish a user as having a specific role over all courses in the org, create an entry without a course_id. """ objects = NoneToEmptyManager() user = models.ForeignKey(User) # blank org is for global group based roles such as course creator (may be deprecated) org = models.CharField(max_length=64, db_index=True, blank=True) # blank course_id implies org wide role course_id = CourseKeyField(max_length=255, db_index=True, blank=True) role = models.CharField(max_length=64, db_index=True) class Meta: unique_together = ('user', 'org', 'course_id', 'role') @property def _key(self): """ convenience function to make eq overrides easier and clearer. arbitrary decision that role is primary, followed by org, course, and then user """ return (self.role, self.org, self.course_id, self.user) def __eq__(self, other): """ Overriding eq b/c the django impl relies on the primary key which requires fetch. sometimes we just want to compare roles w/o doing another fetch. """ return type(self) == type(other) and self._key == other._key def __hash__(self): return hash(self._key) def __lt__(self, other): """ Lexigraphic sort """ return self._key < other._key def __unicode__(self): return "[CourseAccessRole] user: {} role: {} org: {} course: {}".format( self.user.username, self.role, self.org, self.course_id)
class Role(models.Model): objects = NoneToEmptyManager() name = models.CharField(max_length=30, null=False, blank=False) users = models.ManyToManyField(User, related_name="roles") course_id = CourseKeyField(max_length=255, blank=True, db_index=True) class Meta(object): # use existing table that was originally created from django_comment_client app db_table = 'django_comment_client_role' def __unicode__(self): # pylint: disable=no-member return self.name + " for " + (self.course_id.to_deprecated_string() if self.course_id else "all courses") # TODO the name of this method is a little bit confusing, # since it's one-off and doesn't handle inheritance later def inherit_permissions(self, role): """ Make this role inherit permissions from the given role. Permissions are only added, not removed. Does not handle inheritance. """ if role.course_id and role.course_id != self.course_id: logging.warning( "%s cannot inherit permissions from %s due to course_id inconsistency", self, role, ) for per in role.permissions.all(): self.add_permission(per) def add_permission(self, permission): self.permissions.add( Permission.objects.get_or_create(name=permission)[0]) def has_permission(self, permission): """Returns True if this role has the given permission, False otherwise.""" course = modulestore().get_course(self.course_id) if course is None: raise ItemNotFoundError(self.course_id) if permission_blacked_out(course, {self.name}, permission): return False return self.permissions.filter(name=permission).exists()
class Role(models.Model): objects = NoneToEmptyManager() name = models.CharField(max_length=30, null=False, blank=False) users = models.ManyToManyField(User, related_name="roles") course_id = CourseKeyField(max_length=255, blank=True, db_index=True) class Meta: # use existing table that was originally created from django_comment_client app db_table = 'django_comment_client_role' def __unicode__(self): # pylint: disable=no-member return self.name + " for " + (self.course_id.to_deprecated_string() if self.course_id else "all courses") def inherit_permissions( self, role): # TODO the name of this method is a little bit confusing, # since it's one-off and doesn't handle inheritance later if role.course_id and role.course_id != self.course_id: logging.warning("%s cannot inherit permissions from %s due to course_id inconsistency", \ self, role) for per in role.permissions.all(): self.add_permission(per) def add_permission(self, permission): self.permissions.add( Permission.objects.get_or_create(name=permission)[0]) def has_permission(self, permission): course = modulestore().get_course(self.course_id) if course is None: raise ItemNotFoundError(self.course_id) if self.name == FORUM_ROLE_STUDENT and \ (permission.startswith('edit') or permission.startswith('update') or permission.startswith('create')) and \ (not course.forum_posts_allowed): return False return self.permissions.filter(name=permission).exists()