Not a Member Yet?

Collaborate with other developers, ask questions, and get information. Register now

Already a member? Go log in!

Download Plugins

Want to embed video, manage tasks, display JIRA issues and more?

Download Plugins!

Make Plugins

Want to add a few cool new features or additional functionality to Clearspace?

Make a Plugin Now!

Click to view dombiak_gaston's profile

In my previous blog posts I talked about Connecting a chat client to Clearspace and Scheduling chats in Clearspace. Today we are going to explain another usage of Chat inside of Clearspace.

 

Lets say that we create a new social group that can be seen by anyone and anyone can join the group. As described in Connecting a chat client to Clearspace, I can use my XMPP client to log into Openfire using my Clearspace credentials. I will then see in my roster (aka contacts list) the newly created social group and its members. From there I can easily tell if they are available, away, unavailable, etc. If I want I can start a one-to-one conversation or even send messages to offline users knowing that they will get them when they come back online.

 

A room in Openfire was created when we created the social group in Clearspace. Rooms are also created when you create new spaces or projects. So what are these rooms? These rooms are defined by XEP-0045: Multi-User Chat and will exist as long as the social group, space or project exists. When someone tries to join the room, Openfire will ask Clearspace if that user is allowed to join the room. Clearspace will check the user permissions on the social group, space or project to answer that question.

 

Most XMPP clients allow you to browse rooms on the server. This is a very convenient way for users to discover rooms and join them. As we said, Clearspace has the ultimate control on who can join which room. Once in the room, everything that is said and information about users that join and left the room is stored in Clearspace. The chat transcript and presence information is updated every minute in Clearspace. It is also immediately available for searches.

 

Besides being able to join from your XMPP client of choice you will also have the choice to join the room from the Clearspace site. When you go to the page of the social group, project or space you can customize it to have a widget that will show the room activity (without actually joining the room). Users can then click the join button to actually join the room and participate from the widget. Beside the widget option we also provide other ways to join the room from your site.

 

Moreover, just like you can do in youtube.com it is also possible to copy some HTML instructions to embed the chat widget in your site outside of Clearspace. You can even pass the user/password from your site to the embedded widget so that the user does not need to log in again. However, if no user/password was passed then the widget will ask the user for his credentials before joining the room.

Click to view brockf's profile

Quick SSO on Clearspace 2.0 posted in Clearspace Development Blog

Posted by brockfJul 1, 2008 2:24:46 PM 6 comments

Below is a small filter that I co-authored recently to integrate with Oracle Access Manager (formerly called Oblix). With the release of CS 2.0 we have totally revamped the authentication process and it is now built on spring-security (formerly acegi). Doing this makes it super easy for most of the typical SSO use-cases to be implemented in a reasonable amount of time.

 

Here was the use case:

1. User Makes initiial request and is not authenticated yet.

2. Webgate routes user to the corporate login page

3. User supplies auth credentials

4. Webgate authenticates the user

5. Webgate sets an Authentication Cookie that identifies this user to Webgate

6. Webgate adds custom HTTP Headers to a new request to the originally requested resource, in this case clearspace.

7. Clearspace ACEGI Filter chain executes for /*** path, this is where I inserted the OblixSSOFilter right before the form authentication.

8. The Filter executes, grabs the HTTP Header "jwt-dn" and extracts the users DN (the user name).

9. The Filter retrieves the User and creates an Authentication and allows the rest of the filters to execute.

 

The User is now authenticated. The Default authoprovider ultimatly loads the Users permission etc downstream using the default AuthProvider.

 

Here is the code for the filter. The filter is pretty straight forward. It looks at the incoming HttpServletRequest and attempts to retrieve a HTTP Header that was sent along from the webgate authentication form previously visited by the user, as stated above, in this particular scenario I was able to assume authentication would always be done prior to accessing clearspace.

 

 

 package com.jivesoftware.clearspace.sso.oblix;
 
 
import com.jivesoftware.community.aaa.AnonymousAuthentication;
import com.jivesoftware.community.aaa.JiveUserAuthentication;
import com.jivesoftware.base.*;
 
 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.FilterChain;
import java.io.IOException;
 
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.Authentication;
import org.apache.commons.lang.StringUtils;
 
/**
 * Created by IntelliJ IDEA.
 * User: fred
 * Date: Jun 11, 2008
 * Time: 12:36:14 PM
 */
public class OblixSSOFilter implements Filter {
 
 
    private static String OAMHEADER = "jwt-unique";
    private static String HEADER_NAME = "jwt-dn";
    private UserManager userManager;
    //possible to use system properties to enable and change the header, for
    //now just keep it simple.
    private String oamHeaderName = HEADER_NAME;
    private boolean enabled = true;
 
    public OblixSSOFilter(){
        super();
    }
 
  
 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        Authentication authentication;
 
        if(!enabled){
            filterChain.doFilter(servletRequest,servletResponse);
        }else{
            try {
                Log.debug("executing oblix filter");
                HttpServletRequest request = (HttpServletRequest)servletRequest;
                String oamHeader = request.getHeader(getOamHeaderName());
                if(oamHeader != null){
                    Log.debug("got OAM header: " + oamHeader);
                    String userDN = extractUserDN(oamHeader);
 
                    User authenticationTarget = null;
                    try{
                        authenticationTarget = userManager.getUser(StringUtils.chomp(userDN));
                    }catch(UserNotFoundException e){
                        Log.error("no user found with username: " + userDN);
                    }
                    //Found an a
                    authentication = new JiveUserAuthentication(authenticationTarget);
                    authentication.setAuthenticated(true);
                }else{
                    Log.debug("no OAM Header");
                    authentication = new AnonymousAuthentication();
                }
                    SecurityContextHolder.getContext().setAuthentication(authentication);
               }catch (Exception e) {
                    Log.error("Exception occured while trying to authenticate OAM response: " + e.getMessage());
               }
           
               
          filterChain.doFilter(servletRequest,servletResponse);
       }
    }
 
 
    private String extractUserDN(String header){
        String userName = null;
        String[] elements = StringUtils.split(header,',');
        for(String element: elements){
            Log.debug("processing header: " + element);
            if(element.startsWith(OAMHEADER)){
                String[] uniqueID = StringUtils.split(element,'=');
                userName = uniqueID[1];
            }
        }
        return(userName);
    }
 
    public void destroy(){
    }
 
    public void setUserManager(UserManager userManager) {
        this.userManager = userManager;
    }
 
    public AuthenticationProvider getAuthenticationProvider() {
        return authenticationProvider;
    }
 
    public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) {
        this.authenticationProvider = authenticationProvider;
    }
 
    public String getOamHeaderName() {
        return oamHeaderName;
    }
 
    public void setOamHeaderName(String oamHeaderName) {
        this.oamHeaderName = oamHeaderName;
    }
 
    public boolean isEnabled() {
        return enabled;
    }
 
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}

 

I simply created a jar containing this one class that I deployed to the WEB-INF\lib directory of a expanded clearspace war file. You can use any IDE or VI and Ant to create the jar, nothing special about it or clearspace specific.

 

After I had the jar. I needed to tell clearspace about the filter. Since 2.0 there is a back door that can be utilized to override the default implementation of clearspace managers,DAOs and other spring managed beans, this back door is your jiveHome\etc directoy. Within the jiveHome\etc directory you can copy and modify the various spring context files packaged in the clearspace.jar file found in \WEB\lib. This is done by extracting the appropriate spring context file from the clearspace.jar file found in WEB-INF\lib, make your edits to it and copy it into \jiveHome\etc. In my case the authentication filter stack is configured in spring-securityContext.xml so I extracted that and made the changes listed below:

 


<!-- NOTICE THE ADDITION OF oblixSS0Filter -->
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /upgrade/**=httpSessionContextIntegrationFilter, upgradeAuthenticationFilter, upgradeExceptionTranslationFilter,jiveAuthenticationTranslationFilter
                /post-upgrade/**=httpSessionContextIntegrationFilter, postUpgradeAuthenticationFilter, postUpgradeExceptionTranslationFilter,jiveAuthenticationTranslationFilter
                /admin/**=httpSessionContextIntegrationFilter, adminAuthenticationFilter, adminExceptionTranslationFilter,jiveAuthenticationTranslationFilter
                /rpc/xmlrpc=wsRequireSSLFilter, httpSessionContextIntegrationFilter, basicAuthenticationFilter, wsExceptionTranslator, jiveAuthenticationTranslationFilter, wsAccessTypeCheckFilter
                /rpc/rest/**=wsRequireSSLFilter, httpSessionContextIntegrationFilter, basicAuthenticationFilter, wsExceptionTranslator, jiveAuthenticationTranslationFilter, wsAccessTypeCheckFilter
                /rpc/soap/**=wsRequireSSLFilter, httpSessionContextIntegrationFilter, jiveAuthenticationTranslationFilter 
                /**=httpSessionContextIntegrationFilter, oblixSSoFilter formAuthenticationFilter, rememberMeProcessingFilter, feedBasicAuthenticationFilter, jiveAuthenticationTranslationFilter
            </value>
        </property>
    </bean>

<!-- DECLARE THE NEW FILTER -->
<bean id="oblixSSoFilter" class="com.jivesoftware.clearspace.sso.oblix.OblixSSOFilter">
        <property name="userManager" ref="userManager" />
    </bean>

 

 

As you can see the stack is configured to protect various resources within clearspace, you can add to this stack as required for your particular case, in my case it was simply a matter of declaring my filter, this allows spring to handle the creation of the object and changing the filter stack for the root path of the application to ensure the oblixSSOFilter fired off prior to formAuthentication. If the oblix filter is able to vouch for the user making the request (via the headers) the filter sets the Authentication on the SecurityContext and life moves forward with an authenticated user, if not, I allow it to fall to the next filter in the stack and the process repeats, with this new framework in place it makes it easy to support multiple authentication sources while still staying on the peripheral edges of the product which will help when it comes time to upgrade.

 

 

After you have made the changes, restart your clearspace instance and you should be up and running with your new filter.

 

Enjoy!.

 

 

 

 

 

 

 

 

 

 

Click to view squareman's profile

Clearing or containing elements with class="clearfix"

I've had more than one engineer ask, "what is the CSS class 'clearfix'?"

Short answer:

It's an easy way to make sure floated content is contained by its container (when you want it to). It's cross-browser friendly and it prevents the need to start floating everything and their parents which can lead to other issues. See the attached file for a live example.

 

You don't need to go crazy and start adding class="clearfix" to everything. Just add it only to parent elements that need to contain floats where content coming after but sibling to that parent needs to clear the floats.

Long answer:

Floats are meant to break out of their parent container and ancestors on purpose, allowing for text or other sibling or descendent content to wrap something like an image. But as is often the case, UI designers want subsequent content to clear that float for the purpose of controlled layout and predictability. There are many ways to achieve this:

  • Adding extraneous elements like <div style="clear:both"> </div> or an HR or BR with styles applied. Drawbacks: code bloat; non-semantic markup; easy to disassociate with the floated element in the markup.

  • Add clear:left; to the next element (sibling to the float or sibling to the float's parent). Drawbacks: that will make that element clear all floats (including ones you don't want it to); can easily be disassociated with the original float context in the markup.

  • Start floating everything. Drawbacks: This creates more layer-caked problems; it's compounded by IE on Windows (up until, but not including IE8) with its hasLayout rendering property (see technical answer).

  • Rely on a class name with browser targeted properties in CSS fix. This is our rock star …

Technical answer (see attachment):

Floats, as mentioned, are meant to break out of their parent containers. When we want a subsequent item to clear that float, what we really want is the float or floats to be contained by its parent element and not break out. With one class="clearfix" on a parent element (the CSS definitions for which have been added to jive-global.css as of 2.0) we can achieve that.

 

For compliant browsers (any modern browser that is not IE, and IE8), we do that with generated content, this is future proof as it's also standards compliant. For IE on Windows (below IE8) we do that with targeted CSS hacks that are ignored by modern browsers, giving it the mysterious, completely non-compliant property of hasLayout. The mumbo jumbo black magic of hasLayout is just nasty nasty and nasty. It's responsible for or related to all kinds of bugs in IE Windows. For the best explanation in existence on hasLayout, see http://www.satzansatz.de/cssd/onhavinglayout.html. We can even target the other dead IE, IE mac, and give it its own CSS fix; but it's not really needed for CS support.

 

Here's the CSS definitions:

* for compliant browsers */
.clearfix:after {
    clear: both; 
    content:".";
    display: block;
    height: 0;
    visibility: hidden
    }
/* affects only IE7 */
.clearfix {
    min-width: 0;
    }
/* targets only IE5-6 and hidden from lowly IEmac \*/
    * html .clearfix { height: 1%; } 
/* end hide IEmac */
/* What? You want to get crazy and do IEmac too? Okay. \*//*/
    .clearfix { display: inline-table; } 
/* end IEmac only */

 

EDIT: I realized I never attached the example HTML file.

 

Click to view ajohnson1200's profile

During the last couple weeks of the 2.0 development cycle we pushed some really helpful search improvements (some of them bug fixes) into Clearspace. There are a numberof posts scattered around our intranet (which is called Brewspace) where the actual improvements / bug fixes are discussed but I don't believe those improvements made it into the documentation (there are a number of improvements listed in the changelog, but no description of what the improvements are). Hence this blog post.

 

First, in 2.0, the default search operator was changed to 'AND' from 'OR', the end result being that if you did a search like this:

clearspace openid

Clearspace would look for all the blog posts, discussions and documents that contained the term "clearspace" AND contained the term "openid". Way back in Clearspace 1.0 the thought was that we should deviate from what Google does (they AND the terms you input) because we're not searching the entire web; our thinking was that most of our installations would only have a couple thousand documents, blog posts and threads and so we didn't ever want a search for 'clearspace openid ldap' to return nothing if there was a document that discussed two of the three. The reality is that when the search operator was 'OR' the number of results from a search query in Clearspace was almost always greater than 500 results (the maximum number of results we would return in a search): in fact, the more words you used in your query, the more likely that you'd end up with a large number of results, which in theory is great (we found a bunch of stuff that for you!) but in practice doesn't make for a great user experience (thirty four pages of search results? come on!). One of the articles (discussed below) had this to say about lots of search results:

Users sometimes measure the success of a query primarily by the number of results it returns. If they feel the number is too large, they add more terms in an effort to bring back a more manageable set.

So not only did "OR" result in more results per query, if you decided that you wanted to refine your query by adding a term, the number of results would actually grow, not shrink, which is the opposite of what you'd expect.

 

The funny thing about changing this default is that when we turned it on for brewspace (our intranet, no other changes had been made at that point), a number of people noticed right away and were amazed at the 'improvement'. It's really crazy how something as simple as "AND" versus "OR" could make such a big difference in user experience.

 

Before I move on, here are a couple interesting articles I found that talk about search as it relates to user experience:

  • Greg Linden, an ex-Amazon guy, wrote a great blog post a couple months agothat summarized a talk that Marissa Mayer gave about Google and their results page and the number of results per page and also added some notes about his own experience while working at Amazon. The bottom line from the presentation? Speed kills. The faster that we can return search results, the happier Clearspace users will be (although the comments on that post tell a potentially different story, don't miss'em).

  • A BBC News article from 2006 had this to say about search results:

At most, people will go through three pages of results before giving up, found the survey by Jupiter Research and marketing firm iProspect. It also found that a third of users linked companies in the first page of results with top brands. It also found 62% of those surveyed clicked on a result on the first page, up from 48% in 2002. Some 90% of consumers clicked on a link in these pages, up from 81% in 2002. And 41% of consumers changed engines or their search term if they did not find what they were searching for on the first page.

Takeaway? Relevant results are more important than many results.

The essential problem of search — too many irrelevant results — has not gone away.

More and more, our ongoing research is telling us that Search has to be perfect. Users expect it to "just work" the first time, every time.

 

One thing that was easy to add which has also come up a couple times was search by author. I'm happy to report that in 2.1 we added the ability to search for content authored by a specific user. So just like you can click 'more options' on the search results page today and choose what types of content you want to search for, you'll be able to select a user whose content you want to find and filter the results using that selection. Side note: that functionality has always been in our API and if you're a URL hacker like I am, you can actually perform Clearspace searches using a pretty URL like this:

http://example.com/clearspace/search/openID

or if you want to search for any content written by the user 'aaron' that contains the word 'openID', you'd use this URL:

http://example.com/clearspace/search/~aaron/openID

 

Another thing that I believe has worked in the past but that we haven't talked about is the idea of a simple syntax for search. Much like the operators you can use in Google (ie: 'site:jivesoftware.com lucene' will find all the references to 'lucene' on the domain 'jivesoftware.com'), we now support the following operators: 'subject:', 'body:', 'tags:' and 'attachmentstext:'. While I admit that they're not the most user-friendly things to type in, it does give advanced users a little bit more flexibility. For example: you can now ignore tags if you want by doing a search like this: 'subject:lucene OR body:lucene'. The search syntax operators are scoped to be in the search tips documentation that sits right alongside the search box. Again, this is for 2.1.

 

Those were the improvements. Now the bug fixes (which just so happen to also really improve your searching experience).

  • Search stemming doesn't seem to be working (CS-3645): Not sure how long this wasn't working, but the existence of this bug meant that if you put the word "error" in a document and then did a search for "errors", our search engine wouldn't find your document. Read more about stemming if you're curious about that sort of thing. If you're seeing this bug, make sure a) you upgrade to at least Clearspace 2.x and b) make sure that you're using a stemming indexer. The default analyzer does not stem. You can change the indexer by going to the admin console --> system --> settings --> search --> search settings tab --> indexer type.

  • Group search results by thread setting in admin console doesn't change search behavior (CS-3656): I'm not sure how long this feature has been around, but there is a search setting in the admin console that gives you the ability to group all messages in a thread into one result in a search results page so that the messages in a single thread don't overwhelm the search results (since messages share the subject and tags from the thread, that actually happened quite a bit). Fixed in 2.0, I highly recommend turning it on in your instance if you haven't already.

  • Search updates to better balance queries across content types (CS-3638): Some improvements were made in 2.0.0 toward this issue, but it's 100% fixed in 2.0.3 and 2.1. There were two really big but really really hard to see problems with the way that we were executing our search queries. First, a quick background on how a search query is performed in Clearspace against all content types. We have a single Lucene index for all the content in Clearspace (there is a separate index for user data, but that's a different story) so when a search for 'bananas' is executed, we did something like this (don't read too much into the language I'm using, I'm just trying to illustrate how it works at a 30,000 foot level):

  1. get blog posts that match query

    • find all the blog posts where the subject matches 'bananas' OR the body matches 'bananas' OR the tags matches 'bananas' OR the attachments matches 'bananas' or the blogID matches 'bananas'

  2. get discussions that match query

    • find all the messages where the subject matches 'bananas' OR the body matches 'bananas' OR the tags matches 'bananas' OR the attachments matches 'bananas' or the threadID matches 'bananas'

  3. get documents that match query

    • find all the documents where the subject matches 'bananas' OR the body matches 'bananas' OR the summary matches 'bananas' OR the fieldsText matches 'bananas' OR the tags matches 'bananas' OR the attachments matches 'bananas' or the documentID matches 'bananas'

  4. merge results from steps 1-3 using the relevance score from each item in the result set as the comparator

  5. display results

The assumption we made when writing this code was that the scores that Lucene returns for each item of all content type will be relatively similar. More concisely, if I had a document and a blog post which for some reason had identical content, I'd expect they would both have the exact same Lucene relevance score if they came up in the results of a search. But that assumption turned out to be wrong, not once but twice.

 

First, as you can see from glancing at the sample queries I pasted above, we searched a different number of fields per content type. Who cares right? Why would the number fields that you search on influence anything? Turns out that Lucene cares: the way scoring works in Lucene is that if you search on ten fields and only get a hit on two of them in document 'X' that the resulting relevance score should be less than a hit on blog post 'Y' where you search on five fields and get a hit on two of them. It makes perfect sense when you think about it: it's just like the tests you had in school. Getting a 4 out of 5 on a test works out to be 80%, about a B. If you got 4 out of 10 on a test, that's 40%, you failed. You probably called them grades... maybe sometimes even a score, which just so happens to be exactly how Lucene refers to the relevance that a particular document has to a given query (if you're curious about how Lucene does scoring / relevance you should check out the JavaDoc for the Similarity class and also read this document on scoring). Anyway, this behavior was actually fixed in 2.0: so now when we execute a search on mixed content we search the exact same number of fields for each content type: subject, body, tags, attachmentsText.

 

The second assumption that turned out to be wrong was just as nebulous. I illustrated above how we search in Clearspace: we do searches for each content type and then we merge the results of those searches into a single result set. In order to do a query for just blog posts that match the word 'token', we do a query that in Lucene looks like this:

+objectType:38 +(subject:token body:token attachmentsText:token tags:token)

It kinds of looks like a SQL subselect: get me all the things where one of subject, body tags or attachmentsText match and then, from those results, only return the results where the objectType is 38 (which is the int that JiveConstants.BLOGPOST refers too). The thing that killed us here was outer statement

+objectType:38

because:

a) when Lucene executes a query, it computes a query weight and field weight for each statement in your query and multiplies those two values together to get the total weight for that statement and

b) the query weight is basically a measure of how many times the key (in this case 'objectType') appears divided by the number of times the value appears (in this case '38') which means that

c) content objects that you have less of (in our case: blog posts) will tend to have a score much higher than content objects that you have a lot of (in our case: documents). Again, this makes sense: items that appears in the index a relatively small number of times are in some sense rare and so they should get a relatively higher weight. Regardless, it turns out there's a really easy fix for this problem as well: you can boost specific fields in your query like this:

subject:token^3

and you can effectively neuter a field by boosting it to zero:

subject:token^0

which means that Lucene will look for all the items in the index whose subject is 'token' but the weight, which usually influences the score that it assigns to the field 'subject' will not influence the score that the resulting item receives.

 

We're continually looking to improve the search tools in Clearspace. If you're seeing something you don't expect or if there's something cool you'd like us to add, please pipe up in our Support and Feature Discussion spaces here on Jivespace.

 

 

Click to view dombiak_gaston's profile

This is the second blog post about real time communication support in Clearspace that started with Connecting a chat client to Clearspace. Today we are going to cover chat events that are going to be available in Clearspace 2.1. Lets start giving some personal examples to illustrate real usages for chat events.

 

  1. Every Wednesday at 10:00 AM PST developers of igniterealtime.org projects join the chat service to answer development questions. Members of the community can join the chat service using their XMPP client of choice or using the web client. Moreover, users of other XMPP servers can also join the chat service as long as server-to-server is enabled.

  2. Every Monday morning developers of the Real Time Communication team, that includes local and remote developers, join a chat room to discuss status updates and goals for the week.

  3. Last week I was invited to a meeting to discuss some technical problem about clustering.

 

In the above examples we see different usages for chat events. The first example is showing a repetitive chat event that is not associated to any space, project or social group but to the entire site. In the second example we have a project, but it could be a space or social group, whose members meet every week to discuss their work. As you would expect, permissions of the container are applied to determine who can join the group chat. And finally, we see that scheduled chats could be a one time only activity.

 

A chat transcript is created for each occurrence of the chat event. When the event is over the transcript is "closed" and moderators can moderate/edit it. As any content in Clearspace, transcripts are indexed on real time and can be searched just like you search for a document or a blog.

 

A persistent room in Openfire is created for each chat event. A new groupchat service was added to Openfire that interacts with Clearspace to control who can create, join, configure and delete rooms. As I said in my previous blog, it is possible to use your own XMPP client to join a chat event or you can just chat from the Clearspace site. File transfers in rooms was also added to Openfire but the Clearspace side is not ready yet so the feature will be ready for the next release of Clearspace. However, since you can use your own XMPP client it is still possible to make use of the new functionality to share files in a room. The file transfer feature is based on WebDAV File Transfers

 

Next week we will cover other type of conversations that are going to be part of Clearspace 2.1.

 

 

 

Click to view dombiak_gaston's profile

As many of you know we have been working heavily for the last months integrating Openfire with Clearspace. This is the first of a series of blog posts that will cover the things that you are already able to do in Clearspace 2.0 when using Openfire 3.5 and new things that you will be able to do in Clearspace 2.1.

 

I will start first describing what is Openfire. Openfire is the award-winning, open alternative to proprietary instant messaging. It uses the only widely adopted open protocol for instant messaging, XMPP (also called Jabber). Since XMPP is a standard protocol, it means that clients that understand the protocol can connect to the server. Example of clients are: Pidgin (ex Gaim), Adium, Trillian, Psi, Spark and many others. Moreover, you can also use web clients like meebo or our own SparkWeb client to connect to Openfire.

 

Openfire can be configured to read the list of users, groups and user authentication from different backends. As of Openfire 3.5 we added the option to instruct Openfire to obtain that information from Clearspace. That means that if you have an account in Clearspace then you can use the same credentials to connect to Openfire and chat with other Clearspace users. If server-2-server is enabled on the Openfire server then you can also chat with GTalk users or other users of other Clearspace instances that installed Openfire. Moreover, you can also chat with AOL, MSN, Yahoo or ICQ users by just installing the gateway plugin in Openfire.

 

One popular feature in Openfire is called shared groups. Shared groups are groups that are pre-populated in the contact list of your chat client from the server. Clearspace 2.1 will use the shared group functionality to automatically expose your social groups in your roster. That means that if you are part of a social group then all the members of that group will appear in your roster. Next in the list is to expose project team mates and lastly in the list is your friending network.

 

Next week we are going to cover how to use groupchat from Clearspace.

 

Click to view RobAlexander's profile

At the university where I work, we use Clearspace X for student communities that are moderated by faculty members. A new position, Director of Social Network Development, was recently created in our IT department, and I will be applying for it. In preparation for my application, here are a few pieces of information I've gathered regarding possible integration of Clearspace with social networks.

 

  • Jive, with initial development by Face It!, recently released a Facebook *Beta* Plugin for Clearspace 1.10x. In the Jivespace Chat for 4/3/08, Dawn said that plugin will need to be ported to Clearspace 2.0 before it can no longer be considered beta. The Facebook plugin integrates the users' Facebook profiles into their Clearspace profiles, while allowing each user to control how (or if) their Facebook information is shown.

 

  • The Flickr Slideshow macro displays a flickr slideshow in a Clearspace blog post, document, or discussion message.

 

  • The YouTube Macro makes it easy to display YouTube videos in Clearspace documents, blog posts, and discussion messages.

 

  • Clearspace's PhotoManager plugin helps you to scrape images from various social networks like MySpace, Socializer, etc.

 

  • Clearspace's blog pinging will send a ping to weblogs.com, Google blog search, and Technorati if blog pinging is enabled when a new blog post is created/published on your system. By default it is disabled in Clearspace and enabled in Clearspace X.

 

 

  • In What does Google and Facebook's validation of DataPortability mean for the Enterprise?, Sam mentioned that Jive has committed to clear standards, like XMPP, and will commit to new standards as they clarify. Given the gravity of Google and Facebook, he feels DataPortability should be one of them. The purpose of the DataPortability project is to put existing technologies, techniques, policies and initiatives in context in order to facilitate translation, education, advocacy and ultimately implementation of data portability. Portability is defined as both physically moving data or simply porting the context in which the data is used.

 

 

 

 

 

I'm looking for additional social features and plugins to appear in Clearspace in the near future. Maybe Jive can find ways to use the new Ringside Social Application Server to further the social aspects of Clearspace.

Click to view erik.onnen's profile

Clearspace 2.0 made several improvements to the internal security mechanisms within the product that serve to streamline and standardize the way authentication, authorization and auditing occur within the application. Following on Dolan's blog about Spring in Clearspace 2.0, this post will cover the Acegi-related changes for 2.0 security.

 

Motivation

There were several motivations for using Acegi Security in Clearspace 2.0:

  • Reuse of standard, community reviewed code - At the time of writing, Acegi is planned to be incorporated into Spring proper in the near future. Particularly with security-related code, community review is essential to producing a more robust end result.

  • Removal of unnecessary, Jive-specific code - There really wasn't a need for us to manage our own authentication framework, authorization framework, X509 handling, etc. when Acegi has already made available a solid implementation. Additionally, Acegi gives us out of the box AuthenticationProvider and Filter implementations for things that previously we had to roll from scratch such as SiteMinder integration or X509 authentication. Acegi's implementations will still require some customization, largely due to the way we perform authorization, but the jive-managed code can be substantially reduced.

  • Community - As with Spring, Acegi has a healthy community that we can leverage, both through shared code as well as by contributing back to the project.

  • Flexibility - Acegi is well written and tends to give us extension points where we need them. For example, we needed to support existing LDAP configurations from Clearspace 1.x installations. This required us to inject custom LDAP search properties into the Acegi BindAuthenticator which was easily done through the setUserSearch method on the authenticator.

  • Leverage Existing Enterprise Competencies - Acegi and Spring are fairly well known in Java enterprise development. Existing skill sets around Acegi will translate to SSO implementations with Clearspace 2.0 as opposed to the 1.x model which required a customer's developers to learn an entirely new security model.

 

Implementation

Authentication

The Clearspace 2.0 authentication model follows standard Acegi authentication, defining a Spring-managed FilterChainProxy bean in web.xml which then delegates to URL-mapped filter chains. These chains manage various security-related concerns including Session expiration, authentication cookie management, password encoding, user profile loading and federated identity features of Clearspace. One notable change is the move to a stronger password hash using a SHA-256 hash of a salted password. Additionally, the amount of Jive-specific LDAP code has been dramatically reduced instead delegating to Acegi's LDAP lookup and bind implementation.

 

Authorization

Clearspace 2.0 authorization has not changed substantially from 1.x with the exception that contextual information about a user is now accessed via the Acegi SecurityContext rather than explicitly passed through the application as AuthToken objects. This change focused the APIs on business concerns and moved security concerns to more of a cross-cutting realm, a change we're leveraging in 2.1 to make authorization driven by annotation rather than proxied objects. The hope for 2.1 is that this will greatly reduce the amount of authoirzation code while improving security.

 

Auditing

Acegi fundamentally feeds into the new auditing features of Clearspace 2.0. Based on contextual authentication information accessed by Acegi's SecurityContext, the auditing functionality logs operations performed by the effective user performing an action in the system.

 

Customization

 

Customization of authentication and authorization have several extension mechanisms in Clearspace 2.0 and the required APIs have been simplified. The older AuthFactory class has been removed and implementing jive-specific interfaces is no-longer required to customize the authentication mechanism. The goal for 2.0 authentication customization has shifted focus to a more modular, composition and inversion of control-driven approach. This better aligns with the Spring-standard Acegi approach and focuses customization on Spring-managed filters and/or AuthenticationProvider implementations. The Clearspace 2.0 documentation has more information on creating new authentication customizations or migrating 1.x authentication customizations.

 

 

 

 

The hope for these changes is that they will improve, standardize and simplify security as it exists in Clearspace. Let us know your feedback!

 

 

Join Our Group Chat!

Every Thursday at 9:00am PST, you can join us on a group chat to ask Jive engineers live questions about Clearspace development.

Free Clearspace License

Get a free license of Clearspace
for your open source project or user group

Featured Plugin: Appfire FlashCharts

Want to display great charts in your Clearspace content? If so, you can learn more or download the Appfire FlashCharts Plugin on Jivespace.

Recent Community Activity

rss feed

Jivespace Video Podcasts

Subscribe to our video podcasts to watch interviews and tutorials. Get Podcasts Now

Monthly Newsletter

More Info | Privacy Policy
<#if request.serverName?contains("jivesoftware.com")>