Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/bindings/javahl/native/Prompter.cpp  view on Meta::CPAN

 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 * @endcopyright
 *
 * @file Prompter.cpp
 * @brief Implementation of the class Prompter
 */

#include "Prompter.h"
#include "Pool.h"
#include "JNIUtil.h"
#include "JNIStringHolder.h"
#include "../include/org_apache_subversion_javahl_callback_UserPasswordCallback.h"
#include <apr_strings.h>
#include "svn_auth.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_private_config.h"

/**
 * Constructor
 * @param jprompter     a global reference to the Java callback object
 */
Prompter::Prompter(jobject jprompter)
{
  m_prompter = jprompter;
}

Prompter::~Prompter()
{
  if (m_prompter!= NULL)
    {
      // Since the reference to the Java object is a global one, it
      // has to be deleted.
      JNIEnv *env = JNIUtil::getEnv();
      env->DeleteGlobalRef(m_prompter);
    }
}

/**
 * Create a C++ peer object for the Java callback object
 *
 * @param jprompter     Java callback object
 * @return              C++ peer object
 */
Prompter *Prompter::makeCPrompter(jobject jprompter)
{
  // If we have no Java object, we need no C++ object.
  if (jprompter == NULL)
    return NULL;

  JNIEnv *env = JNIUtil::getEnv();

  // Create a local frame for our references
  env->PushLocalFrame(LOCAL_FRAME_SIZE);
  if (JNIUtil::isJavaExceptionThrown())
    return NULL;

  // Sanity check that the Java object implements UserPasswordCallback.
  jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN_NULL;

  if (!env->IsInstanceOf(jprompter, clazz))
    POP_AND_RETURN_NULL;

  // Create a new global ref for the Java object, because it is
  // longer used that this call.
  jobject myPrompt = env->NewGlobalRef(jprompter);
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN_NULL;

  env->PopLocalFrame(NULL);

  // Create the C++ peer.
  return new Prompter(myPrompt);
}

/**
 * Retrieve the username from the Java object
 * @return Java string for the username or NULL
 */
jstring Prompter::username()
{
  JNIEnv *env = JNIUtil::getEnv();

  // Create a local frame for our references
  env->PushLocalFrame(LOCAL_FRAME_SIZE);
  if (JNIUtil::isJavaExceptionThrown())
    return NULL;

  // The method id will not change during the time this library is
  // loaded, so it can be cached.
  static jmethodID mid = 0;

  if (mid == 0)
    {
      jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
      if (JNIUtil::isJavaExceptionThrown())
        POP_AND_RETURN_NULL;

      mid = env->GetMethodID(clazz, "getUsername", "()Ljava/lang/String;");
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
        POP_AND_RETURN_NULL;
    }

  jstring ret = static_cast<jstring>(env->CallObjectMethod(m_prompter, mid));
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN_NULL;

  return (jstring) env->PopLocalFrame(ret);
}

/**
 * Retrieve the password from the Java object
 * @return Java string for the password or NULL
 */
jstring Prompter::password()
{
  JNIEnv *env = JNIUtil::getEnv();

  // Create a local frame for our references
  env->PushLocalFrame(LOCAL_FRAME_SIZE);
  if (JNIUtil::isJavaExceptionThrown())
    return NULL;

  // The method id will not change during the time this library is
  // loaded, so it can be cached.
  static jmethodID mid = 0;

  if (mid == 0)
    {
      jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
      if (JNIUtil::isJavaExceptionThrown())
        POP_AND_RETURN_NULL;

      mid = env->GetMethodID(clazz, "getPassword", "()Ljava/lang/String;");
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
        POP_AND_RETURN_NULL;
    }

  jstring ret = static_cast<jstring>(env->CallObjectMethod(m_prompter, mid));
  if (JNIUtil::isJavaExceptionThrown())
    return NULL;

  return (jstring) env->PopLocalFrame(ret);
}
/**
 * Ask the user a question, which can be answered by yes/no.
 * @param realm         the server realm, for which this question is asked
 * @param question      the question to ask the user
 * @param yesIsDefault  flag if the yes-button should be the default button
 * @return flag who the user answered the question
 */
bool Prompter::askYesNo(const char *realm, const char *question,
                        bool yesIsDefault)
{
  JNIEnv *env = JNIUtil::getEnv();

  // Create a local frame for our references
  env->PushLocalFrame(LOCAL_FRAME_SIZE);
  if (JNIUtil::isJavaExceptionThrown())
    return false;

  // The method id will not change during the time this library is
  // loaded, so it can be cached.
  static jmethodID mid = 0;

  if (mid == 0)
    {
      jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
      if (JNIUtil::isJavaExceptionThrown())
        POP_AND_RETURN(false);

      mid = env->GetMethodID(clazz, "askYesNo",
                             "(Ljava/lang/String;Ljava/lang/String;Z)Z");
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
        POP_AND_RETURN(false);
    }

  // convert the texts to Java strings
  jstring jrealm = JNIUtil::makeJString(realm);
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN(false);

  jstring jquestion = JNIUtil::makeJString(question);
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN(false);

  // execute the callback
  jboolean ret = env->CallBooleanMethod(m_prompter, mid, jrealm, jquestion,
                                        yesIsDefault ? JNI_TRUE : JNI_FALSE);
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN(false);

  env->PopLocalFrame(NULL);
  return ret ? true:false;
}

const char *Prompter::askQuestion(const char *realm, const char *question,
                                  bool showAnswer, bool maySave)
{
  JNIEnv *env = JNIUtil::getEnv();

  // Create a local frame for our references
  env->PushLocalFrame(LOCAL_FRAME_SIZE);
  if (JNIUtil::isJavaExceptionThrown())
    return NULL;

  static jmethodID mid = 0;
  static jmethodID mid2 = 0;
  if (mid == 0)
    {
      jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
      if (JNIUtil::isJavaExceptionThrown())
        POP_AND_RETURN_NULL;

      mid = env->GetMethodID(clazz, "askQuestion",
                             "(Ljava/lang/String;Ljava/lang/String;"
                             "ZZ)Ljava/lang/String;");
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
        POP_AND_RETURN_NULL;

      mid2 = env->GetMethodID(clazz, "userAllowedSave", "()Z");
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
        POP_AND_RETURN_NULL;
    }

  jstring jrealm = JNIUtil::makeJString(realm);
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN_NULL;

  jstring jquestion = JNIUtil::makeJString(question);
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN_NULL;

  jstring janswer = static_cast<jstring>(
                       env->CallObjectMethod(m_prompter, mid, jrealm,
                                    jquestion,
                                    showAnswer ? JNI_TRUE : JNI_FALSE,
                                    maySave ? JNI_TRUE : JNI_FALSE));
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN_NULL;

  JNIStringHolder answer(janswer);
  if (answer != NULL)
    {
      m_answer = answer;
      m_maySave = env->CallBooleanMethod(m_prompter, mid2) ? true: false;
      if (JNIUtil::isJavaExceptionThrown())
        POP_AND_RETURN_NULL;
    }
  else
    {
      m_answer = "";
      m_maySave = false;
    }

  env->PopLocalFrame(NULL);
  return m_answer.c_str();
}

int Prompter::askTrust(const char *question, bool maySave)
{
   static jmethodID mid = 0;
   JNIEnv *env = JNIUtil::getEnv();

   // Create a local frame for our references
   env->PushLocalFrame(LOCAL_FRAME_SIZE);
   if (JNIUtil::isJavaExceptionThrown())
     return -1;

   if (mid == 0)
     {
       jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
       if (JNIUtil::isJavaExceptionThrown())
         POP_AND_RETURN(-1);

       mid = env->GetMethodID(clazz, "askTrustSSLServer",
                              "(Ljava/lang/String;Z)I");
       if (JNIUtil::isJavaExceptionThrown() || mid == 0)
         POP_AND_RETURN(-1);
     }
   jstring jquestion = JNIUtil::makeJString(question);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN(-1);

   jint ret = env->CallIntMethod(m_prompter, mid, jquestion,
                                 maySave ? JNI_TRUE : JNI_FALSE);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN(-1);

   env->PopLocalFrame(NULL);
   return ret;
}

bool Prompter::prompt(const char *realm, const char *pi_username, bool maySave)
{
  JNIEnv *env = JNIUtil::getEnv();
  jboolean ret;

  // Create a local frame for our references
  env->PushLocalFrame(LOCAL_FRAME_SIZE);
  if (JNIUtil::isJavaExceptionThrown())
    return false;

  static jmethodID mid = 0;
  static jmethodID mid2 = 0;
  if (mid == 0)
    {
      jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/UserPasswordCallback");
      if (JNIUtil::isJavaExceptionThrown())
        POP_AND_RETURN(false);

      mid = env->GetMethodID(clazz, "prompt",
                             "(Ljava/lang/String;Ljava/lang/String;Z)Z");
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
        POP_AND_RETURN(false);

      mid2 = env->GetMethodID(clazz, "userAllowedSave", "()Z");
      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
        POP_AND_RETURN(false);
    }

  jstring jrealm = JNIUtil::makeJString(realm);
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN(false);

  jstring jusername = JNIUtil::makeJString(pi_username);
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN(false);

  ret = env->CallBooleanMethod(m_prompter, mid, jrealm, jusername,
                               maySave ? JNI_TRUE: JNI_FALSE);
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN(false);

  m_maySave = env->CallBooleanMethod(m_prompter, mid2) ? true : false;
  if (JNIUtil::isJavaExceptionThrown())
    POP_AND_RETURN(false);

  env->PopLocalFrame(NULL);
  return ret ? true:false;
}

svn_auth_provider_object_t *Prompter::getProviderSimple(SVN::Pool &in_pool)
{
  apr_pool_t *pool = in_pool.getPool();
  svn_auth_provider_object_t *provider;
  svn_auth_get_simple_prompt_provider(&provider,
                                      simple_prompt,
                                      this,
                                      2, /* retry limit */
                                      pool);

  return provider;
}

svn_auth_provider_object_t *Prompter::getProviderUsername(SVN::Pool &in_pool)
{
  apr_pool_t *pool = in_pool.getPool();
  svn_auth_provider_object_t *provider;



( run in 1.073 second using v1.01-cache-2.11-cpan-df04353d9ac )