Package org.knopflerfish.service.um.useradmin.impl

Source Code of org.knopflerfish.service.um.useradmin.impl.UserAdminImpl

/*
* Copyright (c) 2003-2008, KNOPFLERFISH project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
*   copyright notice, this list of conditions and the following
*   disclaimer in the documentation and/or other materials
*   provided with the distribution.
*
* - Neither the name of the KNOPFLERFISH project nor the names of its
*   contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.knopflerfish.service.um.useradmin.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import java.security.AccessController;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import org.knopflerfish.service.um.useradmin.Condition;
import org.osgi.framework.Bundle;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.useradmin.Authorization;
import org.osgi.service.useradmin.Role;
import org.osgi.service.useradmin.User;
import org.osgi.service.useradmin.UserAdmin;
import org.osgi.service.useradmin.UserAdminEvent;
import org.osgi.service.useradmin.UserAdminListener;
import org.osgi.service.useradmin.UserAdminPermission;
import org.osgi.util.tracker.ServiceTracker;


/**
* Implementation of UserAdmin.
*
* @author Gatespace AB
* @version $Revision: 1.1.1.1 $
*/
public class UserAdminImpl implements ServiceFactory, UserAdmin,
        ServiceListener {
    static final UserAdminPermission adminPermission;

    protected ServiceReference uasr; // our service ref

    protected Hashtable /* String -> RoleImpl */roles; // role db

    protected Vector /* ServiceReferences */listeners; // UserAdminListener:s

    RoleImpl anyone; // predefined role

    EventQueue eventQueue;

    ServiceTracker eventAdminTracker;

    static {
        adminPermission = new UserAdminPermission(UserAdminPermission.ADMIN,
                                                  null);
    }

    UserAdminImpl() {
        revert(); // Read saved roles
        if (roles == null) {
          zap(); // Create "empty" roles table
        }
        listeners = new Vector();

        eventAdminTracker
          = new ServiceTracker(Activator.bc, EventAdmin.class.getName(), null );
        eventQueue = new EventQueue(Activator.bc);
    }

    /**
     * Initialization method for the user admin. We must wait for the service
     * reference before we can check out UserAdminListeners.
     *
     * @param sr
     *            service reference for UserAdmin.
     */
    private void init(ServiceReference sr) {
        this.uasr = sr;
        // Listen for UserAdminListeners, collect those already registered
        try {
            String clazz = UserAdminListener.class.getName();
            Activator.bc.addServiceListener(this, "(objectClass=" + clazz + ")");
            ServiceReference[] srs = Activator.bc.getServiceReferences(clazz, null);
            if (srs != null) {
                for (int i = 0; i < srs.length; i++) {
                    listeners.addElement(srs[i]);
                    if (Activator.log.doDebug())
                        Activator.log.debug("UserAdminListener found: " + srs[i]);
                }
            }
        } catch (InvalidSyntaxException ex) {
        }
        eventAdminTracker.open();

        if (Activator.log.doInfo())
            Activator.log.info("Service initialized", uasr);
    }


    /**
     * The bundle owning this service is stopping; terminate the worker
     * thread.
     */
    void stop() {
      save(); // Try to save roles table
    }

    /**
     * Sends an event to all user admin listeners.
     *
     * @param type
     *            the event type, one of <code>UserAdminEvent.ROLE_CHANGED
     * .ROLE_CREATED or .ROLE_REMOVED</code>.
     * @param role
     *            the role that the event is generated for.
     */
    void sendEvent(int type, Role role) {
        // dont send event if type = CHANGED and role has been removed
        if (!(type == UserAdminEvent.ROLE_CHANGED
              && roles.get(role.getName()) == null)) {
            UserAdminEvent event = new UserAdminEvent(uasr, type, role);
            eventQueue.enqueue( new SendUserAdminEventJob(Activator.bc,
                                                          eventAdminTracker,
                                                          event,
                                                          listeners) );
            if (Activator.log.doDebug())
                Activator.log.debug(event.toString(), uasr);
        } else {
            if (Activator.log.doDebug())
                Activator.log.debug("Event not sent, " + role.getName()
                        + " has been removed.", uasr);
        }
    }

    // - interface org.osgi.framework.ServiceFactory
    // ----------------------------
    public synchronized Object getService(Bundle bundle,
            ServiceRegistration registration) {
        // Factory is only used to be able to register and then later
        // get hold of our own ServiceReference before any bundle have
        // a chance to use the service.
        if (uasr == null) {
            // initialize ourself with the service reference the first time
            // the service is used by a bundle
            init(registration.getReference());
        }

        return this;
    }

    public void ungetService(Bundle bundle, ServiceRegistration registration,
            java.lang.Object service) {
    }

    // - interface org.osgi.service.useradmin.UserAdmin
    // -------------------------
    public Role createRole(String name, int type) {
        SecurityManager sm = System.getSecurityManager();
        if(null!=sm){
            sm.checkPermission(adminPermission);
        }
        if (roles.get(name) != null) {
            // role 'name' already exists, abort and return null
            return null;
        }

        Role role;
        switch (type) {
        case Role.USER:
            role = new UserImpl(name);
            break;
        case Role.GROUP:
            role = new GroupImpl(name);
            break;
        case Condition.CONDITION:
            role = new ConditionImpl(name);
            break;
        default:
            throw new IllegalArgumentException("UserAdminImpl: Unknown type '"
                    + type + "'.");
        }

        roles.put(name, role);
        sendEvent(UserAdminEvent.ROLE_CREATED, role);

        return role;
    }

    public boolean removeRole(String name) {
        SecurityManager sm = System.getSecurityManager();
        if(null!=sm){
            sm.checkPermission(adminPermission);
        }

        if (Role.USER_ANYONE.equals(name)) {
            // not OK to remove the predefined role
            return false;
        }

        RoleImpl role = (RoleImpl) roles.remove(name);
        if (role != null) {
            role.remove();
            sendEvent(UserAdminEvent.ROLE_REMOVED, role);

            return true;
        }

        return false;
    }

    public Role getRole(String name) {
        return (Role) roles.get(name);
    }

    public Role[] getRoles(String filter) throws InvalidSyntaxException {
        Vector v = new Vector();
        for (Enumeration en = roles.elements(); en.hasMoreElements();) {
            RoleImpl role = (RoleImpl) en.nextElement();
            if (filter == null || LDAPQuery.query(filter, role.getProperties())) {
                v.addElement(role);
            }
        }

        Role[] result = new Role[v.size()];
        v.copyInto(result);

        return result;
    }

    public User getUser(String key, String value) {
        User[] users = getUsers(key, value);

        return users.length == 1 ? users[0] : null;
    }

    private User[] getUsers(String key, String value) {
        Vector found = new Vector();
        for (Enumeration en = roles.elements(); en.hasMoreElements();) {
            Object o = en.nextElement();
            if (o instanceof UserImpl) {
                UserImpl user = (UserImpl) o;
                Object val = user.getProperties().get(key);
                if (val instanceof String && value.equals(val)) {
                    found.addElement(user);
                }
            }
        }

        User[] result = new User[found.size()];
        found.copyInto(result);

        return result;
    }

    public Authorization getAuthorization(User user) {
        RoleImpl role = user != null ? (UserImpl) user : anyone;

        return new AuthorizationImpl(role);
    }

    // - interface org.osgi.framework.ServiceListener --------------------------
    public void serviceChanged(ServiceEvent event) {
        ServiceReference sr = event.getServiceReference();
        switch (event.getType()) {
        case ServiceEvent.REGISTERED:
            listeners.addElement(sr);
            if (Activator.log.doDebug())
                Activator.log.debug("UserAdminListener found: " + sr);
            break;
        case ServiceEvent.UNREGISTERING:
            if (listeners.removeElement(sr) && Activator.log.doDebug())
                Activator.log.debug("UserAdminListener gone: " + sr);
            break;
        }
    }

    // remove contents of roles
    protected void zap() {
        roles = new Hashtable();
        // create the special roles (no events for these)
        roles.put(Role.USER_ANYONE,
                  anyone = new RoleImpl(Role.USER_ANYONE));
    }

    // Revert to the saved state
    protected void revert() {
      if (Boolean.getBoolean("org.knopflerfish.useradmin.dontsave")) {
        if (Activator.log.doDebug()) Activator.log.debug("read skipped");
        return;
      }
      String path
        = Activator.bc.getProperty("org.knopflerfish.useradmin.store");
      String oldPath
        = Activator.bc.getProperty("org.knopflerfish.useradmin.oldstore");
      File file;
      if (path == null) {
        file = Activator.bc.getDataFile("ua_store");
      } else {
        file = new File(path);
        if (file == null || !file.exists()) {
          file = new File(oldPath);
        }
      }
      try {
        if (file != null && file.exists()) {
          ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
          Object obj = ois.readObject();
          ois.close();
          if (obj instanceof Hashtable) {
            roles = (Hashtable) obj;
            if (null!=roles) {
              anyone = (RoleImpl) roles.get(Role.USER_ANYONE);
              if (null==anyone) {
                roles.put(Role.USER_ANYONE,
                          anyone = new RoleImpl(Role.USER_ANYONE));
              }
            }
            if (Activator.log.doDebug()) Activator.log.debug("roles reverted");
          } else {
            Activator.log.error("ua_store corrupted");
          }
        } else {
          if (Activator.log.doDebug()) Activator.log.debug("ua_store not found");
        }
      } catch (ClassNotFoundException e) {
        Activator.log.error("Failed to instantiate saved roles", e);
      } catch (IOException e) {
        Activator.log.error("Failed to read saved roles", e);
      }
    }

    // Save the current state
    protected void save() {
      if (Boolean.getBoolean("org.knopflerfish.useradmin.dontsave")) {
        if (Activator.log.doDebug()) Activator.log.debug("save skipped");
        return;
      }
      String path
        = Activator.bc.getProperty("org.knopflerfish.useradmin.store");
      File file;
      if (path == null) {
        file = Activator.bc.getDataFile("ua_store");
        if (file == null) {
          Activator.log.info("The platform cannot provide a data file. Cannot save roles.");
          return;
        }
      } else {
        file = new File(path);
      }
      try {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
        oos.writeObject(roles);
        oos.close();
      } catch (IOException e) {
        Activator.log.error("Failed to save roles", e);
      }
    }

}
TOP

Related Classes of org.knopflerfish.service.um.useradmin.impl.UserAdminImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.