package io.kaif.web.v1;
import java.util.Optional;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import com.rometools.utils.Strings;
import io.kaif.model.clientapp.ClientAppUserAccessToken;
import io.kaif.oauth.InsufficientScopeException;
import io.kaif.oauth.InvalidTokenException;
import io.kaif.oauth.MissingBearerTokenException;
import io.kaif.service.ClientAppService;
public class ClientAppUserAccessTokenArgumentResolver implements HandlerMethodArgumentResolver {
private final ClientAppService clientAppService;
public ClientAppUserAccessTokenArgumentResolver(ClientAppService clientAppService) {
this.clientAppService = clientAppService;
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType() == ClientAppUserAccessToken.class;
}
@Override
public ClientAppUserAccessToken resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
String tokenStr = Strings.trimToEmpty(webRequest.getHeader(HttpHeaders.AUTHORIZATION));
if (!tokenStr.startsWith("Bearer ")) {
throw new MissingBearerTokenException();
}
String token = tokenStr.substring("Bearer ".length(), tokenStr.length()).trim();
Optional<ClientAppUserAccessToken> accessToken = clientAppService.verifyAccessToken(token);
if (!accessToken.isPresent()) {
throw new InvalidTokenException();
}
RequiredScope requiredScope = parameter.getMethodAnnotation(RequiredScope.class);
if (!accessToken.get().containsScope(requiredScope.value())) {
throw new InsufficientScopeException(requiredScope.value());
}
return accessToken.get();
}
}