""" Various decorators for endpoint and API handlers. """

import features
from flask import abort
from auth.auth_context import (get_validated_oauth_token, get_authenticated_user,
                               get_validated_token, get_grant_user_context)
from functools import wraps


def anon_allowed(func):
  """ Marks a method to allow anonymous access where it would otherwise be disallowed. """
  func.__anon_allowed = True
  return func


def anon_protect(func):
  """ Marks a method as requiring some form of valid user auth before it can be executed. """
  func.__anon_protected = True
  return check_anon_protection(func)


def check_anon_protection(func):
  """ Validates a method as requiring some form of valid user auth before it can be executed. """
  @wraps(func)
  def wrapper(*args, **kwargs):
    # Skip if anonymous access is allowed.
    if features.ANONYMOUS_ACCESS or '__anon_allowed' in dir(func):
      return func(*args, **kwargs)

    # Check for validated context. If none exists, fail with a 401.
    if (get_authenticated_user() or get_validated_oauth_token() or get_validated_token() or
        get_grant_user_context()):
      return func(*args, **kwargs)

    abort(401)
  return wrapper