org.apache.openmeetings.web.app.WebSession.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.openmeetings.web.app.WebSession.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") +  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   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.
 */
package org.apache.openmeetings.web.app;

import static java.text.DateFormat.SHORT;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_MYROOMS_KEY;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_RSS_KEY;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_LANG_KEY;
import static org.apache.openmeetings.web.app.Application.getAuthenticationStrategy;
import static org.apache.openmeetings.web.app.Application.getBean;
import static org.apache.openmeetings.web.app.Application.getClientByKeys;
import static org.apache.openmeetings.web.app.Application.getDashboardContext;
import static org.apache.openmeetings.web.app.Application.isInvaldSession;
import static org.apache.openmeetings.web.app.Application.removeInvalidSession;
import static org.apache.openmeetings.web.app.Application.removeOnlineUser;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;

import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.openmeetings.IWebSession;
import org.apache.openmeetings.core.ldap.LdapLoginManagement;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.label.LabelDao;
import org.apache.openmeetings.db.dao.room.InvitationDao;
import org.apache.openmeetings.db.dao.server.SOAPLoginDao;
import org.apache.openmeetings.db.dao.server.SessiondataDao;
import org.apache.openmeetings.db.dao.user.IUserManager;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.room.Invitation;
import org.apache.openmeetings.db.entity.server.RemoteSessionObject;
import org.apache.openmeetings.db.entity.server.SOAPLogin;
import org.apache.openmeetings.db.entity.server.Sessiondata;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.db.entity.user.User.Right;
import org.apache.openmeetings.db.entity.user.User.Type;
import org.apache.openmeetings.db.util.TimezoneUtil;
import org.apache.openmeetings.util.OmException;
import org.apache.openmeetings.web.user.dashboard.MyRoomsWidget;
import org.apache.openmeetings.web.user.dashboard.MyRoomsWidgetDescriptor;
import org.apache.openmeetings.web.user.dashboard.RssWidget;
import org.apache.openmeetings.web.user.dashboard.RssWidgetDescriptor;
import org.apache.openmeetings.web.user.dashboard.StartWidgetDescriptor;
import org.apache.openmeetings.web.user.dashboard.WelcomeWidgetDescriptor;
import org.apache.openmeetings.web.user.dashboard.admin.AdminWidget;
import org.apache.openmeetings.web.user.dashboard.admin.AdminWidgetDescriptor;
import org.apache.openmeetings.web.util.OmUrlFragment;
import org.apache.openmeetings.web.util.UserDashboard;
import org.apache.wicket.authentication.IAuthenticationStrategy;
import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession;
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
import org.apache.wicket.request.Request;
import org.apache.wicket.util.string.StringValue;
import org.apache.wicket.util.string.Strings;
import org.wicketstuff.dashboard.Dashboard;
import org.wicketstuff.dashboard.Widget;
import org.wicketstuff.dashboard.WidgetFactory;
import org.wicketstuff.dashboard.web.DashboardContext;

public class WebSession extends AbstractAuthenticatedWebSession implements IWebSession {
    private static final long serialVersionUID = 1L;
    public static final int MILLIS_IN_MINUTE = 60000;
    public static final String ISO8601_FORMAT_STRING = "yyyy-MM-dd'T'HH:mm:ssZ";
    public static final List<String> AVAILABLE_TIMEZONES = Arrays.asList(TimeZone.getAvailableIDs());
    public static final Set<String> AVAILABLE_TIMEZONE_SET = new LinkedHashSet<String>(AVAILABLE_TIMEZONES);
    public static final String WICKET_ROOM_ID = "wicketroomid";
    private Long userId = null;
    private Set<Right> rights = new HashSet<User.Right>(); //TODO renew somehow on user edit !!!!
    private long languageId = -1; //TODO renew somehow on user edit !!!!
    private String SID = null;
    private OmUrlFragment area = null;
    private TimeZone tz;
    private TimeZone browserTz;
    private FastDateFormat ISO8601FORMAT = null;
    private FastDateFormat sdf = null;
    private UserDashboard dashboard;
    private Locale browserLocale = null;
    private Invitation i = null;
    private Long roomId = null;
    private Long recordingId = null;
    private Long loginError = null;
    private String externalType;
    private boolean kickedByAdmin = false;

    public WebSession(Request request) {
        super(request);
        browserLocale = getLocale();
    }

    @Override
    public void invalidate() {
        removeOnlineUser(getClientByKeys(getUserId(), get().getId()));
        super.invalidate();
        userId = null;
        rights = Collections.unmodifiableSet(Collections.<Right>emptySet());
        SID = null;
        ISO8601FORMAT = null;
        sdf = null;
        i = null;
        roomId = null;
        recordingId = null;
        externalType = null;
        tz = null;
        browserTz = null;
        loginError = null;
        browserLocale = null;
    }

    @Override
    public Roles getRoles() {
        if (rights.isEmpty()) {
            isSignedIn();
        }
        Roles r = new Roles();
        for (Right right : rights) {
            r.add(right.name());
        }
        return r;
    }

    @Override
    public boolean isSignedIn() {
        if (userId == null) {
            IAuthenticationStrategy strategy = getAuthenticationStrategy();
            // get username and password from persistence store
            String[] data = strategy.load();
            if (data != null && data.length > 3 && data[2] != null) {
                Long domainId = null;
                try {
                    domainId = Long.valueOf(data[3]);
                } catch (Exception e) {
                    //no-op
                }
                // try to sign in the user
                if (!signIn(data[0], data[1], Type.valueOf(data[2]), domainId)) {
                    // the loaded credentials are wrong. erase them.
                    strategy.remove();
                }
            }
        }
        return userId != null && userId.longValue() > 0;
    }

    public void checkHashes(StringValue secure, StringValue invitation) {
        try {
            if (!secure.isEmpty()) {
                if (isSignedIn()) {
                    invalidate();
                }
                if (signIn(secure.toString(), false)) {
                    //TODO markUsed
                } else {
                    //TODO redirect to error
                }
            }
            if (!invitation.isEmpty()) {
                if (isSignedIn()) {
                    invalidate();
                }
                i = getBean(InvitationDao.class).getByHash(invitation.toString(), false, false);
                if (i.isAllowEntry()) {
                    Set<Right> rights = new HashSet<>();
                    //TODO markUsed
                    if (i.getRoom() != null) {
                        rights.add(Right.Room);
                        roomId = i.getRoom().getId();
                    } else if (i.getAppointment() != null && i.getAppointment().getRoom() != null) {
                        rights.add(Right.Room);
                        roomId = i.getAppointment().getRoom().getId();
                    } else if (i.getRecording() != null) {
                        recordingId = i.getRecording().getId();
                    }
                    setUser(i.getInvitee(), rights);
                }
            }
        } catch (Exception e) {
            //no-op, will continue to sign-in page
        }
    }

    public boolean signIn(String secureHash, boolean markUsed) {
        //FIXME code is duplicated from MainService, need to be unified
        SOAPLoginDao soapDao = getBean(SOAPLoginDao.class);
        SOAPLogin soapLogin = soapDao.get(secureHash);
        if (soapLogin == null) {
            return false;
        }
        if (!soapLogin.isUsed() || soapLogin.getAllowSameURLMultipleTimes()) {
            SessiondataDao sessionDao = getBean(SessiondataDao.class);
            Sessiondata sd = sessionDao.get(soapLogin.getSessionHash());
            if (sd != null && sd.getXml() != null) {
                RemoteSessionObject remoteUser = RemoteSessionObject.fromXml(sd.getXml());
                if (remoteUser != null && !Strings.isEmpty(remoteUser.getExternalUserId())) {
                    UserDao userDao = getBean(UserDao.class);
                    User user = userDao.getExternalUser(remoteUser.getExternalUserId(),
                            remoteUser.getExternalUserType());
                    if (user == null) {
                        user = userDao.getNewUserInstance(null);
                        user.setFirstname(remoteUser.getFirstname());
                        user.setLastname(remoteUser.getLastname());
                        user.setLogin(remoteUser.getUsername()); //FIXME check if login UNIQUE
                        user.setType(Type.external);
                        user.setExternalId(remoteUser.getExternalUserId());
                        user.setExternalType(remoteUser.getExternalUserType());
                        user.getRights().clear();
                        user.getRights().add(Right.Room);
                        user.getAddress().setEmail(remoteUser.getEmail());
                        user.setPictureuri(remoteUser.getPictureUrl());
                    } else {
                        user.setFirstname(remoteUser.getFirstname());
                        user.setLastname(remoteUser.getLastname());
                        user.setPictureuri(remoteUser.getPictureUrl());
                    }
                    user = userDao.update(user, null);
                    if (markUsed) {
                        soapLogin.setUsed(true);
                        soapLogin.setUseDate(new Date());
                        //soapLogin.setClientURL(clientURL); //FIXME
                        soapDao.update(soapLogin);
                    }
                    sessionDao.updateUser(SID, user.getId());
                    setUser(user, null);
                    roomId = soapLogin.getRoomId();
                    recordingId = soapLogin.getRecordingId();
                    return true;
                }
            }
        }
        return false;
    }

    private void setUser(User u, Set<Right> rights) {
        String _sid = SID;
        Long _recordingId = recordingId;
        Long _roomId = roomId;
        Invitation _i = i;
        replaceSession(); // required to prevent session fixation
        if (_sid != null) {
            SID = _sid;
        }
        if (_recordingId != null) {
            recordingId = _recordingId;
        }
        if (_roomId != null) {
            roomId = _roomId;
        }
        if (i != null) {
            i = _i;
        }
        userId = u.getId();
        if (rights == null || rights.isEmpty()) {
            this.rights = Collections.unmodifiableSet(u.getRights());
        } else {
            this.rights = Collections.unmodifiableSet(rights);
        }
        languageId = u.getLanguageId();
        externalType = u.getExternalType();
        tz = getBean(TimezoneUtil.class).getTimeZone(u);
        ISO8601FORMAT = FastDateFormat.getInstance(ISO8601_FORMAT_STRING, tz);
        setLocale(languageId == 3 ? Locale.GERMANY : LabelDao.languages.get(languageId));
        //FIXMW locale need to be set by User language first
        sdf = FastDateFormat.getDateTimeInstance(SHORT, SHORT, getLocale());
    }

    public boolean signIn(String login, String password, Type type, Long domainId) {
        try {
            User u = null;
            switch (type) {
            case ldap:
                u = getBean(LdapLoginManagement.class).login(login, password, domainId);
                break;
            case user:
                /* we will allow login against internal DB in case user 'guess' LDAP password */
                u = getBean(UserDao.class).login(login, password);
                break;
            case oauth:
                // we did all the checks at this stage, just set the user
                u = getBean(UserDao.class).getByLogin(login, Type.oauth, domainId);
                break;
            default:
                throw new OmException(-1L);
            }
            if (u == null) {
                return false;
            }
            signIn(u);
            return true;
        } catch (OmException oe) {
            loginError = oe.getCode() == null ? Long.valueOf(-1) : oe.getCode();
        }
        return false;
    }

    public boolean signIn(User u) {
        Sessiondata sessData = getBean(SessiondataDao.class).create();
        SID = sessData.getSessionId();
        if (u == null) {
            return false;
        }
        setUser(u, null);
        return true;
    }

    public Long getLoginError() {
        return loginError;
    }

    public static WebSession get() {
        return (WebSession) AbstractAuthenticatedWebSession.get();
    }

    @Override
    public void setLanguage(long languageId) {
        this.languageId = languageId;
    }

    public static long getLanguage() {
        checkIsInvalid();
        WebSession session = get();
        if (session.languageId < 0) {
            if (session.isSignedIn()) {
                session.languageId = getBean(UserDao.class).get(session.userId).getLanguageId();
            } else {
                session.languageId = getBean(ConfigurationDao.class).getConfValue(CONFIG_DEFAULT_LANG_KEY,
                        Long.class, "1");
            }
        }
        return session.languageId;
    }

    public String getValidatedSid() {
        SessiondataDao sessionDao = getBean(SessiondataDao.class);
        Long _userId = sessionDao.check(SID);
        if (_userId == null || !_userId.equals(userId)) {
            Sessiondata sessionData = sessionDao.get(SID);
            if (sessionData == null) {
                sessionData = sessionDao.create();
            }
            if (!sessionDao.updateUser(sessionData.getSessionId(), userId, false, languageId)) {
                //something bad, force user to re-login
                invalidate();
            } else {
                SID = sessionData.getSessionId();
            }
        }
        return SID;
    }

    public static String getSid() {
        return get().getValidatedSid();
    }

    public static Long getUserId() {
        checkIsInvalid();
        return get().userId;
    }

    public static Long getRecordingId() {
        return get().recordingId;
    }

    public Long getRoomId() {
        return get().roomId;
    }

    public Invitation getInvitation() {
        return i;
    }

    public static String getExternalType() {
        return get().externalType;
    }

    public static TimeZone getUserTimeZone() {
        return get().tz;
    }

    public static Calendar getCalendar() {
        return Calendar.getInstance(get().tz);
    }

    public static Calendar getClientCalendar() {
        return Calendar.getInstance(getClientTimeZone());
    }

    public static FastDateFormat getIsoDateFormat() {
        return get().ISO8601FORMAT;
    }

    public static FastDateFormat getDateFormat() {
        return get().sdf;
    }

    public static Set<Right> getRights() {
        checkIsInvalid();
        return get().rights;
    }

    public static void setKickedByAdmin(boolean kicked) {
        get().kickedByAdmin = kicked;
    }

    public boolean isKickedByAdmin() {
        return kickedByAdmin;
    }

    public OmUrlFragment getArea() {
        return area;
    }

    public void setArea(OmUrlFragment area) {
        this.area = area;
    }

    public static Dashboard getDashboard() {
        Dashboard d = get().dashboard;
        if (d == null) {
            get().initDashboard();
            d = get().dashboard;
        }
        return d;
    }

    public Locale getBrowserLocale() {
        return browserLocale;
    }

    public Long getLanguageByBrowserLocale() {
        return getBean(IUserManager.class).getLanguage(getBrowserLocale());
    }

    public String getClientTZCode() {
        TimeZone _zone = browserTz;
        if (browserTz == null) {
            try {
                browserTz = getClientInfo().getProperties().getTimeZone();
                if (browserTz != null && !AVAILABLE_TIMEZONE_SET.contains(browserTz.getID())) {
                    for (String availableID : AVAILABLE_TIMEZONES) {
                        TimeZone zone = TimeZone.getTimeZone(availableID);
                        if (zone.hasSameRules(browserTz)) {
                            browserTz = zone;
                            break;
                        }
                    }
                }
                _zone = browserTz;
            } catch (Exception e) {
                //no-op
            }
            if (browserTz == null) {
                _zone = Calendar.getInstance(getBrowserLocale()).getTimeZone();
            }
        }
        return _zone == null ? null : _zone.getID();
    }

    public static TimeZone getClientTimeZone() {
        String tzCode = get().getClientTZCode();
        return tzCode == null ? null : TimeZone.getTimeZone(tzCode);
    }

    private void initDashboard() {
        DashboardContext dashboardContext = getDashboardContext();
        dashboard = (UserDashboard) dashboardContext.getDashboardPersister().load();
        boolean existMyRoomWidget = false, existRssWidget = false, existAdminWidget = false;
        ConfigurationDao cfgDao = getBean(ConfigurationDao.class);
        boolean showMyRoomConfValue = 1 == cfgDao.getConfValue(CONFIG_DASHBOARD_SHOW_MYROOMS_KEY, Integer.class,
                "0");
        boolean showRssConfValue = 1 == cfgDao.getConfValue(CONFIG_DASHBOARD_SHOW_RSS_KEY, Integer.class, "0");
        boolean showAdminWidget = getRights().contains(User.Right.Admin);
        boolean save = false;

        WidgetFactory widgetFactory = dashboardContext.getWidgetFactory();

        if (dashboard == null) {
            dashboard = new UserDashboard("default", "Default");

            dashboard.addWidget(widgetFactory.createWidget(new WelcomeWidgetDescriptor()));
            dashboard.addWidget(widgetFactory.createWidget(new StartWidgetDescriptor()));
            if (showMyRoomConfValue) {
                dashboard.addWidget(widgetFactory.createWidget(new MyRoomsWidgetDescriptor()));
            }
            if (showRssConfValue) {
                dashboard.addWidget(widgetFactory.createWidget(new RssWidgetDescriptor()));
            }
            if (showAdminWidget) {
                dashboard.addWidget(widgetFactory.createWidget(new AdminWidgetDescriptor()));
            }
            save = true;
        } else {
            for (Iterator<Widget> iter = dashboard.getWidgets().iterator(); iter.hasNext();) {
                Widget w = iter.next();
                // PrivateRoomWidget is stored in the profile of user. Now, Show_MyRooms_key is disable.
                if (w.getClass().equals(MyRoomsWidget.class)) {
                    existMyRoomWidget = true;
                    if (!showMyRoomConfValue) {
                        iter.remove();
                    }
                } else if ((w.getClass().equals(RssWidget.class))) {
                    // RssWidget is stored in the profile of user. Now, Show_RSS_Key is disable.
                    existRssWidget = true;
                    if (!showRssConfValue) {
                        iter.remove();
                    }
                } else if ((w.getClass().equals(AdminWidget.class))) {
                    // AdminWidget is stored in the profile of user. check if user is admin.
                    existAdminWidget = true;
                    if (!showAdminWidget) {
                        iter.remove();
                    }
                } else {
                    w.init();
                }
            }
            // PrivateRoomWidget was deleted from profile and now it's enabled. It's added again to dashboard.
            if (!existMyRoomWidget && showMyRoomConfValue && !dashboard.isWidgetMyRoomsDeleted()) {
                dashboard.addWidget(widgetFactory.createWidget(new MyRoomsWidgetDescriptor()));
                save = true;
            }
            // RssWidget was deleted from profile and now it's enabled. It's added again to dashboard.
            if (!existRssWidget && showRssConfValue && !dashboard.isWidgetRssDeleted()) {
                dashboard.addWidget(widgetFactory.createWidget(new RssWidgetDescriptor()));
                save = true;
            }
            // user had no admin rights, now he/she has.
            if (!existAdminWidget && showAdminWidget && !dashboard.isWidgetAdminDeleted()) {
                dashboard.addWidget(widgetFactory.createWidget(new AdminWidgetDescriptor()));
                save = true;
            }
        }
        if (save) {
            dashboardContext.getDashboardPersister().save(dashboard);
        }
    }

    @Override
    public long getOmLanguage() {
        return getLanguage();
    }

    private static void checkIsInvalid() {
        if (isInvaldSession(get().getId())) {
            setKickedByAdmin(true);
            removeInvalidSession(get().getId());
            org.apache.wicket.Session session = (org.apache.wicket.Session) get();
            session.invalidate();
            Application.get().restartResponseAtSignInPage();
        }
    }
}