def allow(self, ctx, ops):
        ''' Checks that the authorizer's request is authorized to
        perform all the given operations. Note that allow does not check
        first party caveats - if there is more than one macaroon that may
        authorize the request, it will choose the first one that does
        regardless.

        If all the operations are allowed, an AuthInfo is returned holding
        details of the decision and any first party caveats that must be
        checked before actually executing any operation.

        If operations include LOGIN_OP, the request should contain an
        authentication macaroon proving the client's identity. Once an
        authentication macaroon is chosen, it will be used for all other
        authorization requests.

        If an operation was not allowed, an exception will be raised which may
        be:

        - DischargeRequiredError holding the operations that remain to
        be authorized in order to allow authorization to proceed
        - PermissionDenied when no operations can be authorized and there's
        no third party to discharge macaroons for.

        @param ctx AuthContext
        @param ops an array of Op
        :return: an AuthInfo object.
        '''
        auth_info, _ = self.allow_any(ctx, ops)
        return auth_info