def lti_app(self): try: if len(settings.LTI_DEVELOP_APP) <= 0: raise BLTIException("Empty setting: LTI_DEVELOP_APP") return settings.LTI_DEVELOP_APP except AttributeError: raise BLTIException("Missing setting: LTI_DEVELOP_APP")
def authorize(self, blti, role='member'): if blti is None: raise BLTIException('Missing LTI parameters') lti_consumer = blti.data.get('tool_consumer_info_product_family_code', '').lower() if lti_consumer == 'canvas': if (not role or role == 'public'): pass elif (role in self.CANVAS_ROLES): # member/admin self._has_role(blti, self.CANVAS_ROLES[role]) else: # specific role? self._has_role(blti, [role]) else: raise BLTIException('authorize() not implemented for "%s"!' % (lti_consumer))
def _has_role(self, blti, valid_roles): roles = blti.data.get('roles', '').split(',') for role in roles: if role in valid_roles: return m = self.RE_ROLE_NS.match(role) if m and m.group(1) in valid_roles: return raise BLTIException('You are not authorized to view this content')
def get_consumer(self, key): try: model = BLTIKeyStore.objects.get(consumer_key=key) return oauth.Consumer(key, str(model.shared_secret)) except BLTIKeyStore.DoesNotExist: try: consumers = getattr(settings, 'LTI_CONSUMERS', {}) return oauth.Consumer(key, consumers[key]) except KeyError: raise BLTIException('No Matching Consumer')
def validate(self, request, params={}): oauth_server = oauth.Server() oauth_server.add_signature_method(oauth.SignatureMethod_HMAC_SHA1()) oauth_request = oauth.Request.from_request( request.method, request.build_absolute_uri(), headers=request.META, parameters=params) if oauth_request: try: key = oauth_request.get_parameter('oauth_consumer_key') consumer = self.get_consumer(key) oauth_server._check_signature(oauth_request, consumer, None) return oauth_request.get_nonoauth_parameters() except oauth.Error as err: raise BLTIException(str(err)) raise BLTIException('Invalid OAuth Request')
def validate(self, request): params = {} body = request.read() try: params = dict((k, v) for k, v in [ tuple(map(unquote_plus, kv.split('='))) for kv in body.split('&') ]) except Exception: raise BLTIException('Missing or malformed parameter or value') blti_params = BLTIOauth().validate(request, params=params) self.blti = BLTIData(**blti_params) self.authorize(self.authorized_role) self.set_session(request, **blti_params)
def validate(self, request): request_validator = BLTIRequestValidator() endpoint = SignatureOnlyEndpoint(request_validator) uri = request.build_absolute_uri() headers = {'Content-Type': 'application/x-www-form-urlencoded'} body = request.read() valid, oauth_req = endpoint.validate_request(uri, request.method, body, headers) # if non-ssl fixup scheme to validate signature generated # on the other side of ingress if (not valid and request_validator.enforce_ssl is False and uri[:5] == "http:"): valid, oauth_req = endpoint.validate_request( "https{}".format(uri[4:]), request.method, body, headers) if not valid: raise BLTIException('Invalid OAuth Request') blti_params = dict(oauth_req.params) self.set_session(request, **blti_params) super(BLTILaunchView, self).validate(request)