javacommons/security/javasrc/com/nokia/mj/impl/security/midp/authorization/SecurityPromptHandler.java
changeset 21 2a9601315dfc
child 34 71c436fe3ce0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javacommons/security/javasrc/com/nokia/mj/impl/security/midp/authorization/SecurityPromptHandler.java	Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,372 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.mj.impl.security.midp.authorization;
+
+import com.nokia.mj.impl.security.midp.common.UserSecuritySettings;
+import com.nokia.mj.impl.security.midp.common.GeneralSecuritySettings;
+import com.nokia.mj.impl.security.midp.common.UserSecuritySettingsImpl;
+import com.nokia.mj.impl.security.midp.common.UserPermission;
+import com.nokia.mj.impl.security.common.PermissionBase;
+import com.nokia.mj.impl.security.utils.SecurityPromptMessage;
+import com.nokia.mj.impl.rt.ui.RuntimeUiFactory;
+import com.nokia.mj.impl.rt.ui.RuntimeUi;
+import com.nokia.mj.impl.rt.ui.ConfirmData;
+import com.nokia.mj.impl.utils.exception.UserCancelException;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * Offers and handles runtime security user prompts. It maintains the logic
+ * about when to prompt according to MIDlet suite's security settings and
+ * MIDlet suite's states
+ */
+public class SecurityPromptHandler
+{
+    // handler to runtime UI used to display the runtime prompts
+    private RuntimeUi ui;
+
+    // handler to localized security prompt messages
+    private SecurityPromptMessage securityPromptMessages;
+
+    // name of the running application
+    private String appName;
+
+    // keeps track of the prompts for session mode for
+    // different function groups
+    private Hashtable sessionPromptsShown;
+
+    // keeps track of the denied answers for session mode for
+    // different function groups
+    private Hashtable sessionsDenied;
+
+    // keeps track of the prompt texts shown, so that within the same session
+    // it does not show same promtp text twice
+    private Vector promptTexts;
+
+    // the mode in which the security prompts operate
+    // GeneralSecuritySettings.DEFAULT_SECURITY_MODE or
+    // GeneralSecuritySettings.USER_SECURITY_MODE
+    private int iSecurityPromptsMode = GeneralSecuritySettings.DEFAULT_SECURITY_MODE;
+
+    /**
+     * Constructor
+     */
+    public SecurityPromptHandler(String appName, int securityPromptsMode)
+    {
+        securityPromptMessages = SecurityPromptMessage.getInstance();
+        sessionPromptsShown = new Hashtable();
+        sessionsDenied = new Hashtable();
+        promptTexts = new Vector();
+        this.appName = appName;
+        switch (securityPromptsMode)
+        {
+        case GeneralSecuritySettings.DEFAULT_SECURITY_MODE:
+        case GeneralSecuritySettings.USER_SECURITY_MODE:
+            iSecurityPromptsMode = securityPromptsMode;
+        }
+    }
+
+    public UserSecuritySettings handleUserPermission(
+        UserPermission userPermission, boolean blanketPromptShown)
+    {
+        UserSecuritySettings settings = userPermission
+                                        .getUserSecuritySettings();
+        Boolean tmp = (Boolean)sessionsDenied.get(settings.getName());
+        boolean sessionDenied = (tmp == null ? false : tmp.booleanValue());
+        if (sessionDenied)
+        {
+            // return immediately with a NO_INTERACTION_MODE
+            return getDenyAnswer(settings);
+        }
+        tmp = (Boolean)sessionPromptsShown.get(settings.getName());
+        boolean sessionPromptShown = (tmp == null ? false : tmp.booleanValue());
+        int currentInteractionMode = settings.getCurrentInteractionMode();
+        if (currentInteractionMode
+                == UserSecuritySettings.ONESHOT_INTERACTION_MODE
+                || (currentInteractionMode
+                    == UserSecuritySettings.SESSION_INTERACTION_MODE
+                    && !sessionPromptShown)
+                || (currentInteractionMode
+                    == UserSecuritySettings.BLANKET_INTERACTION_MODE
+                    && !blanketPromptShown))
+        {
+            // figure out the texts for the current & most powerful interaction modes
+            String currentInteractionModeText = null;
+            String mostPowerfulInteractionModeText = null;
+            int mostPowerfulInteractionMode = currentInteractionMode;
+            switch (currentInteractionMode)
+            {
+            case UserSecuritySettings.ONESHOT_INTERACTION_MODE:
+                currentInteractionModeText = userPermission.getPromptDetails()
+                                             .getSecurityPromptAnswerOption(
+                                                 PermissionBase.ONESHOT_ANSWER_OPTION);
+                if (settings.isInteractionModeAllowed(UserSecuritySettings
+                                                      .BLANKET_INTERACTION_MODE))
+                {
+                    mostPowerfulInteractionModeText = userPermission.getPromptDetails()
+                                                      .getSecurityPromptAnswerOption(
+                                                          PermissionBase.BLANKET_ANSWER_OPTION);
+                    mostPowerfulInteractionMode = UserSecuritySettings
+                                                  .BLANKET_INTERACTION_MODE;
+                }
+                else if (settings.isInteractionModeAllowed(UserSecuritySettings
+                         .SESSION_INTERACTION_MODE))
+                {
+                    mostPowerfulInteractionModeText = userPermission.getPromptDetails()
+                                                      .getSecurityPromptAnswerOption(
+                                                          PermissionBase.SESSION_ANSWER_OPTION);
+                    mostPowerfulInteractionMode = UserSecuritySettings
+                                                  .SESSION_INTERACTION_MODE;
+                }
+                break;
+            case UserSecuritySettings.SESSION_INTERACTION_MODE:
+                currentInteractionModeText = userPermission.getPromptDetails()
+                                             .getSecurityPromptAnswerOption(
+                                                 PermissionBase.SESSION_ANSWER_OPTION);
+                if (settings.isInteractionModeAllowed(UserSecuritySettings
+                                                      .BLANKET_INTERACTION_MODE))
+                {
+                    mostPowerfulInteractionModeText = userPermission.getPromptDetails()
+                                                      .getSecurityPromptAnswerOption(
+                                                          PermissionBase.BLANKET_ANSWER_OPTION);
+                    mostPowerfulInteractionMode = UserSecuritySettings
+                                                  .BLANKET_INTERACTION_MODE;
+                }
+                break;
+            case UserSecuritySettings.BLANKET_INTERACTION_MODE:
+                currentInteractionModeText = userPermission.getPromptDetails()
+                                             .getSecurityPromptAnswerOption(
+                                                 PermissionBase.BLANKET_ANSWER_OPTION);
+                break;
+            }
+            String promptText = null;
+            switch (iSecurityPromptsMode)
+            {
+            case GeneralSecuritySettings.DEFAULT_SECURITY_MODE:
+                if (mostPowerfulInteractionModeText != null)
+                {
+                    currentInteractionModeText = null;
+                }
+                promptText = userPermission.getPromptDetails()
+                             .getSecurityPromptQuestion(mostPowerfulInteractionMode);
+                break;
+            case GeneralSecuritySettings.USER_SECURITY_MODE:
+                mostPowerfulInteractionModeText = null;
+                promptText = userPermission.getPromptDetails()
+                             .getSecurityPromptQuestion(currentInteractionMode);
+                break;
+            }
+            // check if the two texts are equal
+            if ((mostPowerfulInteractionModeText != null
+                    && mostPowerfulInteractionModeText.equalsIgnoreCase(
+                        currentInteractionModeText)))
+            {
+                // no sense in showing the text for the current interaction mode,
+                // since it is identical with the one for the most powerful one
+                // (in this way we promote the most powerful interaction mode)
+                currentInteractionModeText = null;
+            }
+            String[] answerOptions =
+                new String[((mostPowerfulInteractionModeText != null
+                             && currentInteractionModeText != null) ? 3 : 2)];
+            int i = 0;
+            if (mostPowerfulInteractionModeText != null)
+            {
+                // first answer option for the security prompt is the most powerful one (if applicable)
+                answerOptions[i] = mostPowerfulInteractionModeText;
+                i++;
+            }
+            if (currentInteractionModeText != null)
+            {
+                // second one is the current interaction mode
+                answerOptions[i] = currentInteractionModeText;
+                i++;
+            }
+            // third answer option for the security prompt is no
+            answerOptions[i] = securityPromptMessages.getText(
+                                   SecurityPromptMessage.ANSWER_ID_DENY, null /* no params*/);
+            ConfirmData cData = new ConfirmData(promptText,
+                                                answerOptions,
+                                                0 /* highlight always the first option */);
+            // optimization for the amount of security prompts: if the security
+            // prompt text has been shown already, and the security mode is
+            // normal and the most powerful interaction mode is NOT oneshot
+            // then treat it as if the user has allowed access
+            int answer = -1;
+            if (iSecurityPromptsMode
+                    == GeneralSecuritySettings.DEFAULT_SECURITY_MODE
+                    && mostPowerfulInteractionMode != UserSecuritySettings.ONESHOT_INTERACTION_MODE
+                    && promptTexts.contains(promptText))
+            {
+                // treat it as if the user has selected the first answer
+                // option the most powerful one
+                answer = 0;
+            }
+            else
+            {
+                RuntimeUi ui = getUiInstance();
+                boolean responseAvailable = ui.confirm(
+                                                appName,
+                                                cData);
+                if (!responseAvailable)
+                {
+                    throw new UserCancelException("User canceled the security prompt");
+                }
+                if (cData.getAnswer() == ConfirmData.NO_ANSWER
+                        || cData.getAnswer() < 0
+                        || cData.getAnswer() >= answerOptions.length)
+                {
+                    // return same settings
+                    return settings;
+                }
+                answer = cData.getAnswer();
+            }
+            UserSecuritySettings newSettings = null;
+            switch (answer)
+            {
+                // the user chose the first answer option
+            case 0:
+                if (mostPowerfulInteractionModeText == null)
+                {
+                    // the first option is the current interaction mode
+                    // -> setting has not been changed
+                    newSettings = settings;
+                }
+                else
+                {
+                    // the first option is the most powerful interaction mode
+                    // -> change the settings accordingly
+                    newSettings = new UserSecuritySettingsImpl(
+                        settings.getName(),
+                        mostPowerfulInteractionMode,
+                        settings.getAllowedInteractionModes());
+                }
+                break;
+                // the user chose the second answer option
+            case 1:
+                if (answerOptions.length == 2)
+                {
+                    // the second answer option is NO -> change the settings accordingly
+                    newSettings = handleDenyAnswer(settings);
+                }
+                else
+                {
+                    // the second answer option is the curent interaction text
+                    // -> setting has not been changed
+                    newSettings = settings;
+                }
+                break;
+                // the user chose the third answer option (which is alway NO if present)
+            case 2:
+                // current interaction mode has been changed to NO
+                newSettings = handleDenyAnswer(settings);
+                break;
+            }
+            // cache the security prompt text
+            if (iSecurityPromptsMode
+                    == GeneralSecuritySettings.DEFAULT_SECURITY_MODE
+                    && newSettings.getCurrentInteractionMode()
+                    != UserSecuritySettings.NO_INTERACTION_MODE)
+            {
+                promptTexts.addElement(promptText);
+            }
+            // mark that the prompt was shown (for the case of session)
+            if (newSettings.getCurrentInteractionMode()
+                    != UserSecuritySettings.NO_INTERACTION_MODE &&
+                    (currentInteractionMode
+                     == UserSecuritySettings.SESSION_INTERACTION_MODE
+                     || newSettings.getCurrentInteractionMode()
+                     == UserSecuritySettings.SESSION_INTERACTION_MODE))
+            {
+                sessionPromptsShown.put(settings.getName(),
+                                        new Boolean(true));
+            }
+            return newSettings;
+        }
+        return settings;
+    }
+
+    /*
+     * Checks if user prompt is required for a certain settings
+     *
+     * @return  0 if user denied a session prompt already,
+     *          1 if user accepted a session prompt already,
+     *         -1 if a session prompt was not shown yet,
+     */
+    public int getSessionPromptStatus(String settingsName)
+    {
+        Boolean tmp = (Boolean)sessionsDenied.get(settingsName);
+        boolean sessionDenied = (tmp == null ? false : tmp.booleanValue());
+        if (sessionDenied)
+        {
+            return 0;
+        }
+        tmp = (Boolean)sessionPromptsShown.get(settingsName);
+        boolean sessionPromptShown = (tmp == null ? false : tmp.booleanValue());
+        return (sessionPromptShown ? 1 : -1);
+    }
+
+    public void destroy()
+    {
+        if (ui != null)
+        {
+            ui.destroy();
+        }
+    }
+
+    private RuntimeUi getUiInstance()
+    {
+        if (ui == null)
+        {
+            ui = RuntimeUiFactory.getRuntimeUi();
+        }
+        return ui;
+    }
+
+    private UserSecuritySettings handleDenyAnswer(UserSecuritySettings settings)
+    {
+        // if the securityMode is Normal and Session/Blanket is Allowed interaction mode or
+        // (the securityMode is User and the currentInteractionMode is Session/Blanket)
+        // -> treat this a session no
+        if ((iSecurityPromptsMode
+                == GeneralSecuritySettings.DEFAULT_SECURITY_MODE
+                && (settings.isInteractionModeAllowed(
+                        UserSecuritySettings.SESSION_INTERACTION_MODE)
+                    || settings.isInteractionModeAllowed(
+                        UserSecuritySettings.BLANKET_INTERACTION_MODE)))
+                || (iSecurityPromptsMode
+                    == GeneralSecuritySettings.USER_SECURITY_MODE
+                    && (settings.getCurrentInteractionMode()
+                        == UserSecuritySettings.SESSION_INTERACTION_MODE
+                        || settings.getCurrentInteractionMode()
+                        == UserSecuritySettings.BLANKET_INTERACTION_MODE)))
+        {
+            sessionsDenied.put(settings.getName(),
+                               new Boolean(true));
+        }
+        return getDenyAnswer(settings);
+    }
+
+    private UserSecuritySettings getDenyAnswer(UserSecuritySettings settings)
+    {
+        return new UserSecuritySettingsImpl(
+                   settings.getName(),
+                   UserSecuritySettings.NO_INTERACTION_MODE,
+                   settings.getAllowedInteractionModes());
+    }
+}