def filter(self, *va, **kw):
		# did the client even try to authenticate?
		if 'HTTP_AUTHORIZATION' not in App.current.request.env:
			return self.respond_unauthorized(self.require_authentication, *va, **kw)
		
		# not digest auth?
		if not App.current.request.env['HTTP_AUTHORIZATION'].startswith('Digest '):
			raise http.BadRequest('only Digest authorization is allowed')
		
		# parse
		params = {}
		required = len(self.required)
		for k, v in [i.split("=", 1) for i in App.current.request.env['HTTP_AUTHORIZATION'][7:].strip().split(',')]:
			k = k.strip()
			params[k] = v.strip().replace('"', '')
			if self.required in k:
				required -= 1
		
		# missing required parameters?
		if required > 0:
			raise http.BadRequest('insufficient authorization parameters')
		
		# user exists?
		if params['username'] not in self.users:
			return self.respond_unauthorized(True, *va, **kw)
		
		# build A1 and A2
		A1 = '%s:%s:%s' % (params['username'], self.realm, self.users[params['username']])
		A2 = App.current.request.method + ':' + App.current.request.url.uri
		
		# build expected response
		expected_response = None
		if 'qop' in params:
			# if qop is sent then cnonce and nc MUST be present
			if not 'cnonce' in params or not 'nc' in params:
				raise http.BadRequest('cnonce and/or nc authorization parameters missing')
			
			# only auth type is supported
			if params['qop'] != 'auth':
				raise http.BadRequest('unsupported qop ' + params['qop'])
			
			# build
			expected_response = self.KD(self.H(A1), '%s:%s:%s:%s:%s' % (
				params['nonce'], params['nc'], params['cnonce'], params['qop'], self.H(A2)))
		else:
			# qop not present (compatibility with RFC 2069)
			expected_response = self.KD(self.H(A1), params['nonce'] + ':' + self.H(A2))
		
		# 401 on realm mismatch
		if params['realm'] != self.realm:
			log.debug('auth failure: unexpected realm')
			return self.respond_unauthorized(True, *va, **kw)
		
		# 401 on unexpected response
		if params['response'] != expected_response:
			log.debug('auth failure: unexpected digest response')
			return self.respond_unauthorized(True, *va, **kw)
		
		# authorized -- delegate further down the filter chain
		return self.respond_authorized(params['username'], *va, **kw)
dataset/ETHPy150Open rsms/smisk/lib/smisk/mvc/filters.py/DigestAuthFilter.filter/swapped operands of `in`