Autorisierung in RCP-Anwendungen

Implementierungsklasse zu diesem Zeitpunkt bereits benötigt wird. Vom RCP Framework wird zu diesem Zweck automatisch eine eigene Aktion (Proxy) erzeugt. Dieser Proxy wird dann in der Oberfläche (Menü, Toolbar) angezeigt. Zur Ausführung der Aktion benötigt der Proxy eine Implementierungsklasse (Delegate), die das Interface org.eclipse.ui.IActionDelegate implementiert. An diese Klasse wird die tatsächliche Ausführung der Aktion delegiert. Die Implementierungsklasse bzw. das zugehörige Plug-in werden gegebenenfalls erst dann geladen, wenn die Aktion zum ersten Mal ausgeführt wird. Folglich kann die Implementierungsklasse nicht ohne Weiteres für die Berechtigungsprüfung verwendet werden.

Abhilfe schafft das Interface org.eclipse.ui.IActionDelegate2, das eine init(IAction) -Methode bereitstellt, die zur Initialisierung des Delegates genutzt werden kann. Diese Methode wird vom Proxy direkt aufgerufen, nachdem die Delegate-Instanz erzeugt wurde und bevor irgendeine andere Methode auf der Delegate-Instanz aufgerufen wird. Als Parameter wird der Proxy übergeben, sodass man Zugriff auf die in der Oberfläche angezeigte Aktion erhält.

Die Durchführung der Berechtigungsprüfung wird wieder in einer Basisklasse implementiert (Listing 2), von der dann alle Delegate-Klassen für Aktionen abgeleitet werden. Die Proxy-Aktion wird als Instanzvariable gespeichert, um die in der Oberfläche angezeigte Aktion zu (de-)aktivieren. Analog zu Listing 1 existiert zu diesem Zweck die Methode setEnabled(boolean) , in der die Berechtigungsprüfung erfolgt. Auch hier muss die Methode zur korrekten Initialisierung mindestens einmal aufgerufen werden! Der Proxy delegiert die Ausführung der Aktion an die Methode runWithEvent(IAction, Event) der Delegate-Instanz, die ihrerseits die Ausführung an die konkrete Unterklasse delegiert: execute(IAction, Event). Da der Proxy in einigen Methoden an die Unterklasse weitergereicht wird, könnte dort die Aktion aktiviert werden, obwohl der Anwender keine Berechtigung besitzt. Aus diesem Grund ist die Methode runWithEvent(IAction, Event) final deklariert, und es findet dort eine zusätzliche Überprüfung statt. So ist sichergestellt, dass nur Aktionen ausgeführt werden können, zu denen der Anwender auch berechtigt ist. Andernfalls wird die Ausführung durch das Werfen einer RuntimeException abgebrochen.

import org.eclipse.jface.action.IAction;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.IActionDelegate2;

public abstract class AbstractAuthorizedActionDelegate 
        implements IActionDelegate2 {
    
    /** the action proxy created by the RCP */
    private IAction m_proxy = null;
    /** enable state for this action */
    private boolean m_enabled = false;
    
    /* (non-Javadoc)
     * @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction)
     */
    public final void init(IAction action) {
        m_proxy = action;
        // Ensure that user permission for this action is checked (by default
        // the RCP action is enabled).
        setEnabled(true);
    }

    /**
     * The execution of this method is delegated to 
     * execute(IAction, Event)
     * 
     * @param action
     * @param event
     * @throws RuntimeException if access is permitted
     * @see org.eclipse.ui.IActionDelegate2#runWithEvent(
     * org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event)
     */
    public final void runWithEvent(IAction action, Event event) {
        if (m_enabled) { // delegate execution
            execute(action, event);
        } else {
            throw new RuntimeException("Executing disabled action"); //$NON-NLS-1$
        }
    }

    /**
     * Delegation method called from runWithEvent() 
     * To be implemented by subclasses to execute the action.
     * 
     * @param action
     * @param event
     */
    protected abstract void execute(IAction action, Event event);
    
    /**
     * Enable/disable the action.
     * 
     * @param enabled
     */
    protected void setEnabled(boolean enabled) {
        m_enabled = enabled && AccessControl.hasPermission(getClass().getName());
        m_proxy.setEnabled(m_enabled);
    }
} 

Beim Starten des Plug-ins wird die Methode earlyStartup()aus dem Interface aufgerufen, die für zusätzliche Initialisierungen genutzt werden kann. In unserem Fall kann die Methode jedoch leer bleiben, da wir lediglich die frühzeitige Aktivierung des Plug-ins erzwingen wollen.

Weitere Elemente

Neben Aktionen kann es weitere Funktionen geben, auf die nur autorisierte Anwender zugreifen dürfen. Im konkreten Projekt, in dem die hier vorgestellten Konzepte erarbeitet wurden, müssen zusätzlich Perspektiven und Wizards zum Neuanlegen von Daten berechtigt werden. Für beide stellt die RCP Erweiterungspunkte zur Verfügung, sodass diese im Plug-in-Manifest deklariert werden können: org.eclipse.ui.perspectives und org.eclipse.ui.newWizards. Die Darstellung in der Oberfläche erfolgt dann automatisch durch das Framework, so wie man es auch von der Eclipse IDE kennt (Abb. 3 und 4).

Abb. 2: Plug-in-Manifest: org.eclipse.ui.startup

Abb. 3: Auswahl eines Wizards
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.