Glen Mazza's Weblog

Main | Next page »

https://web-gmazza.rhcloud.com/blog/date/20170326 Sunday March 26, 2017

Activating Transport Layer Security (SSL) for CXF web services

Using the DoubleIt web service as a starting point, this tutorial shows how to secure a Tomcat-hosted CXF web service and standalone SOAP client with transport layer security (TLS, aka SSL) and basic authentication. With TLS, the entire SOAP request and response is encrypted at the transport layer. See the security section of my blog index for alternative methods using message-layer encryption (such as UsernameToken or X.509 token profiles), where only portions of the SOAP envelope are encrypted during transmission.

The finished tutorial source code can be obtained from GitHub by using either the download ZIP button or git clone -v git://github.com/gmazza/blog-samples.git command.

Activating SSL for a Web Service:

  1. Create a server key for Tomcat if it does not already have one. The Tomcat SSL guide explains this process. For development mode only, you can use a self-signed certificate, in particular, if you are prototyping both the web service and client on the same machine, you can use Java keytool to create a server key with a commonName of "localhost":

    keytool -genkeypair -validity 730 -alias myserverkey -keystore serverKeystore.jks -dname "cn=localhost" -keypass ???? -storepass ????
    

    This will create a serverKeystore.jks keystore containing a new key for the server, valid for two years (730 days). For convenience, you may wish to place this file in Tomcat's base ($CATALINA_HOME) folder. Note that Tomcat expects the values of the keypass and storepass passwords to be the same. Also, for the client to accept the service certificate the commonName field needs to match the URL domain name (e.g., "cn=www.myserver.com") where the service will be hosted. I'm using "cn=localhost" above because I'm testing the client and service from the same machine.

  2. Activate Tomcat's SSL port. Edit Tomcat's $CATALINA_HOME/conf/server.xml file to activate (uncomment) the SSL connector running on port 8443 by default and configure it to use your new keystore:

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
        maxThreads="150" scheme="https" secure="true"
        clientAuth="false" sslProtocol="TLS"
        keystoreFile="serverKeystore.jks" keystorePass="????"/>
    

    The Tomcat documentation has more information on editing this file. The keystoreFile attribute above is assuming the keystore is located in $CATALINA_HOME, and be sure to update keystorePass with the actual (common key and keystore) password. After configuring this information, restart Tomcat to load this new information.

  3. Set server-side restrictions on the SSL cipher suites available for the SOAP calls (optional). The total set of cipher suites available is determined by the JSSE suite in use by the JRE being used by Tomcat. It can be further restricted however by either the web service provider or the SOAP client. On the service side, this process is container-dependent, with Tomcat having an SSL connector ciphers value that can be used to provide this information.

  4. Update the web.xml to require SSL and basic authentication. We'll use the web.xml security-constraint, login-config and security-role elements (tutorial) for this. Add the following configuration to the web.xml file listed in Step #4 of the DoubleIt tutorial:

    <security-constraint>
       <web-resource-collection>
          <web-resource-name>restricted web services</web-resource-name>
          <url-pattern>/*</url-pattern>
          <http-method>GET</http-method>
          <http-method>POST</http-method>
       </web-resource-collection>
       <auth-constraint>
          <!-- role listed in security-role element below and in tomcat-users.xml file -->
          <role-name>mywsrole</role-name>
       </auth-constraint>
       <user-data-constraint>
          <!-- require SSL -->
          <transport-guarantee>CONFIDENTIAL</transport-guarantee>
       </user-data-constraint>
    </security-constraint>
    
    <!-- require basic authentication -->
    <login-config>
      <auth-method>BASIC</auth-method>
    </login-config>
    
    <security-role>
    	<role-name>mywsrole</role-name>
    </security-role>
    
  5. Add users and a new role to the application server. In the previous step we created a new role mywsrole to designate the servlet container role that users must have in order to access the web service. We now need to add this role to the $CATALINA_HOME/conf/tomcat-users.xml file and grant this role to new or existing users in that file:

    <?xml version='1.0' encoding='utf-8'?>
    <tomcat-users>
       <role rolename="manager"/>
       <user username="tomcat" password="?????" roles="manager"/>
       <role rolename="mywsrole"/>
       <user username="alice"  password="clarinet"  roles="mywsrole"/>
       <user username="bob"    password="trombone"  roles="mywsrole"/>
       <user username="chuck"  password="harmonica" roles="mywsrole"/>
    </tomcat-users>
    
  6. Update the endpoint address in the WSDL service section to use the https protocol and port. This is the WSDL in Step #3 of the DoubleIt tutorial. The new SOAP address to use:

    <wsdl:service name="DoubleItService">
       <wsdl:port name="DoubleItPort" binding="tns:DoubleItBinding">
          <soap:address location="https://localhost:8443/doubleit/services/doubleit"/>
       </wsdl:port>
    </wsdl:service>
    
  7. Redeploy the web service. Follow Step #7 of the DoubleIt tutorial. We'll see that the SSL-enabled web service is working properly once we configure the SOAP client below. At this stage you might wish to confirm you can see the WSDL from a browser at https://localhost:8443/doubleit/services/doubleit?wsdl and that the browser requires you to use one of the usernames/passwords you configured above as a prerequisite. Note your browser will probably complain about the server's self-signed certificate and require you to accept the certificate before you can proceed.

Activating SSL for the SOAP Client:

  1. Import the server's public key into the web service client's truststore. The truststore can be either the cacerts file of the JRE that the SOAP client is using (which would result in all Java applications using that JRE to trust the server hosting the web service) or a SOAP-client specific truststore. Either way, export the certificate from the keystore you created above into a file:

    keytool -export -rfc -keystore serverKeystore.jks -alias myserverkey -file MyServer.cer
    

    Then import the certificate into the SOAP client's truststore. For the simpler case of relying on the JRE's default truststore ($JAVA_HOME/jre/lib/security/cacerts, with default password "changeit"), first (optionally) back up the cacerts file and then run:

    keytool -import -noprompt -trustcacerts -alias myserverkey -file MyServer.cer -keystore $JAVA_HOME/jre/lib/security/cacerts
    

    Alternatively, if you wish to use a client-specific truststore:

    1. Import the server certificate into a new (or already existing) truststore:

      keytool -import -noprompt -trustcacerts -alias myserverkey -file MyServer.cer -keystore clienttruststore.jks -storepass ????
      

      If the given clienttruststore.jks file doesn't exist, Keytool will first create it with the password provided by the -storepass value. If the truststore already exists, the -storepass value will need to be the correct for the truststore.

    2. Link the client-specific truststore to the SOAP client as shown here. Place this configuration in a cxf.xml file in a new src/main/resources folder in the client submodule.

    Note that after you are finished with this tutorial, you can remove this certificate from the cacerts (or client-specific) truststore by using a command similar to the below:

    keytool -delete -alias myserverkey -keystore $JAVA_HOME/jre/lib/security/cacerts
    
  2. Set client-side restrictions on the SSL cipher suites available for the SOAP calls (optional). This can be accomplished in CXF by use of the cipherSuitesFilter element in the cxf.xml configuration file (see also here).

  3. Update the SOAP client to provide the basic auth username and password. CXF allows for setting the BindingProvider's username and password properties to accomplish this. This information can also be placed in cxf.xml configuration files using the http:authorization element. The updated DoubleIt SOAP client below uses the former method:

    Running the client as shown in Step #9 of the tutorial should give the desired output. After confirming this, also test with incorrect usernames and/or passwords to make sure that the basic authentication checks are working. Note if you're using a cxf.xml configuration file, you'll need to include the spring-context dependency in the client pom.xml or the configuration file will not be read.

Additional Notes:

  • The default endpoint URL that the SOAP client uses is defined in the WSDL whose location is hardcoded in the Service subclass (DoubleItService here.) This can be overridden in the SOAP client by setting the ENDPOINT_ADDRESS_PROPERTY. In the SOAP client above I added a check to make sure SSL is being used prior to the SOAP call being made. This helps protect against sensitive data in the SOAP body being sent out unencrypted in case a non-https:// URL was accidentally configured.

  • The sample Tomcat server key created in this tutorial used "localhost" as its distinguished name (dname) so that clients having the server's public key in its truststore could access the service using an https://localhost:... endpoint URL. If the server key however has an actual dname (e.g., acme.com) but you are still accessing it via localhost while doing development, you can temporarily have the SOAP client ignore the dname when validating the server. CXF has a disableCNCheck setting that will accomplish this.

  • See the CXF wsdl_first_https sample (available in the CXF download) to learn how to set up two-way SSL, where the service must also confirm a client certificate for the SOAP call to proceed.

https://web-gmazza.rhcloud.com/blog/date/20170319 Sunday March 19, 2017

Using Apache CXF to access Salesforce's SOAP API

I've created a SOAP client using Apache CXF 3.1.x and Maven to access Salesforce's SOAP Web Services API, in particular the more generic Partner API. Salesforce's CXF sample, while it contains useful examples that go beyond my tutorial, uses the decade-old CXF 2.0.2 with Apache Ant, so I decided to post a more modern sample. The SOAP client in this tutorial creates a DataFolder with two subfolders in Email Studio of your Marketing Cloud account, something simple to confirm ability to make SOAP calls as well as use for starting boilerplate for your own projects. The tutorial source code can be obtained from GitHub by using either the download ZIP button or git clone -v git://github.com/gmazza/blog-samples.git command.

If you're new to SOAP, you may wish to review my intro web service tutorial.

The project has the following submodules, please take note of the changes needed for the code to work in your environment:

  • exacttarget-jaxws - This submodule primarily contains just the ExactTarget WSDL. The pom for this project uses CXF's wsdl-to-java generator to read the WSDL and from that generate the 300+ JAX-WS and JAXB Java classes used for accessing the Salesforce SOAP endpoint. This submodule in turn gets included as a dependency by the other two modules. The sample project does not contain the WSDL, as it is dependent on the instance (S1, S4, S6, S7, etc.) that you're using -- Salesforce support can help you if you're unsure which one. If wishing to run the sample, view the appropriate WSDL link in a browser, save it as text, and place it as "etframework.wsdl" in the src/main/resources folder of this submodule.

  • salesforce-access-lib - This is (the beginnings of) a library you can include in your application to make the Salesforce SOAP API calls, as stated earlier it just creates three data folders. You'll see that most SOAP actions in Salesforce involve repetitive configuration calls (for example, creating a DataFolder requires specifying several properties for it before saving) so that's it advantageous to factor out this configuration into service methods that you can efficiently call as needed.

  • testapp - This is a simple command-line application that calls a method in salesforce-access-lib to create the data folder. It uses Spring configuration to handle the UsernameToken (username and password) security requirements. To run the testapp:

    • You'll need to know the MID (Member ID) of the Business Unit of your Salesforce instance that you wish to have the SOAP client access, usually (?) a 7-digit number. That can normally be found in the upper-left portion of Email Studio, in the Business Unit dropdown, or contact Salesforce for this information. This value needs to go in the specified location in the testapp's pom.xml where it is read while running the application.
    • You'll need to populate the included creds.properties file with your Salesforce login and password while running the testapp. If you include this project in your own source control, for security you will probably want to exclude this file from your repo (for example, can use a .gitignore file to block its saving if you're using a Git-based version control system.)

After you've made the above-specified modifications, from the root folder run the Maven mvn clean install from a command-line prompt to build all the submodules. You may then navigate to the testapp folder and run mvn exec:exec to run the testapp and create the sample data folders that you'll be able to see once you log into Email Studio (Contents -> My Emails section). They can be deleted by right-clicking on them within Email Studio.

For further help on accessing the SOAP API and working with its objects and methods the Salesforce StackExchange is a good place to post questions.

https://web-gmazza.rhcloud.com/blog/date/20170312 Sunday March 12, 2017

Creating a WSDL-first web service with Apache CXF

This tutorial shows how to create a start-from-WSDL web service using Apache CXF along with a SOAP client to call that web service. Apache Maven is used as the build and run tool for this sample.[Read More]

https://web-gmazza.rhcloud.com/blog/date/20170218 Saturday February 18, 2017

Using AppleScript to quickly configure your work environment

At work, I use Mac OS' Script Editor to create and compile AppleScript scripts to quickly configure my desktop depending on the programming task at hand. Each compiled script, or application, I place in the desktop folder so it appears on my desktop and can be activated with a simple double-click.

Three tasks I commonly have that I include and adjust as needed depending on the task:

  • Activating a terminal window with tabs pre-opened to various directories and running various commands. A script that opens up three terminal windows in the specified directories, and optionally runs any commands in those directories, would look as follows (see here for more info):
    tell application "Terminal"
    	activate
    	do script
    	do script "cd /Users/gmazza/mydir1" in tab 1 of front window
    	my makeTab()
    	do script "cd /Users/gmazza/mydir2" in tab 2 of front window
    	my makeTab()
    	do script "cd /Users/gmazza/mydir3" in tab 3 of front window
    end tell
    
    on makeTab()
    	tell application "System Events" to keystroke "t" using {command down}
    	delay 0.2
    end makeTab
    
  • Running IntelliJ IDEA. Simple:
    activate application "IntelliJ IDEA"
    
  • Opening Chrome with a desired number of tabs to certain webpages:
    tell application "Google Chrome"
    	open location "http://www.websiteone.com/onpage"
    	open location "http://www.websitetwo.com/anotherpage"
    	open location "http://www.websitethree.com"
    end tell
    

Script editor has a "run" button allowing me to test the scripts as I develop them. Once done, I save the script both standalone (so I can edit it later if desired), but also export it as an application. Exporting it allows for a simple double-click to directly run the task, rather than bringing up the Script Editor and requiring the script to be run via the "run" button.

https://web-gmazza.rhcloud.com/blog/date/20170102 Monday January 02, 2017

TightBlog 2.0 update...

Happy New Year! I added a new tag management tab to the upcoming TightBlog 2.0 UI, it provides a pageable listing of all tags currently used by a blog, number of entries having that tag, as well as the following functionality:

  • View entries -- see the entries having a given tag
  • Delete tag -- remove a given tag from all blog entries having it
  • Add tag -- add a new tag (or an already existing one) to all blog entries having a given tag (sample use case: wanting to tag all blog entries currently tagged "Java" with the tag "Programming" for those entries not already having that tag)
  • Rename tag -- change the name of a tag to either a new tag or an already existing tag (sample use case: on the basis of a "Java7" tag no longer worth highlighting due to its age, switching the tag to the generic "Java" for blog entries having the former but not yet the latter and just deleting the "Java7" tag for those entries already having the latter.)

I also pulled out the "Planet" functionality in 2.0 (ability to read in, merge and display external RSS feeds) -- not to be mistaken for a home site page such as Oracle Blogs Aquarium or JRoller, that ability will still remain. I'm aware of only one of the fifty or so Roller users currently using planets, and that lone user very halfheartedly. While on the Roller team we simplified the planet functionality about 50%, and in developing TightBlog 1.0 I pulled out about another 50%, but it was still needing 3 database tables and about 3500 lines of code. I felt the effort spent maintaining it would be more productively spent elsewhere in the application. (By way of comparison, the much more utilizable Tag management page requires no extra tables and only about 600 extra lines of code.)

So far, TightBlog 2.0 has fallen to 163 Java class files from the 187 in TightBlog 1.0, making it just under 1/3 the class count of Roller 5.1.2's 493. The removal of the planet functionality dropped the database table count from 17 to 14, nineteen below Roller's 33. My main remaining prerequisite for releasing TightBlog 2.0 is completing the switch from Struts to Spring MVC, as so much of the application is now (Spring) REST API based that including a second web framework as a dependency is increasingly undesirable.

https://web-gmazza.rhcloud.com/blog/date/20161116 Wednesday November 16, 2016

Benefits of Retaining the Electoral College

  1. It respects the Great Compromise between the states - The Great Compromise, meant to protect small states from getting overwhelmed by the larger ones, necessary to get them to agree to form the Union, extended not just to the legislative branch but the executive as well. By adding the equal number of senators to the number of congressmen to determine each state's electoral votes, small states were given additional weighting in the say they would have in choosing the President.

    For example, one state A with twice as much population as B might have 6 representatives to B's 3. However, the number of electoral votes is not 6 to 3 or twice as much say but 8 to 5 due to the addition of the senators, resulting in just 1.6 times as much say, honoring the compromise. Switching to a popular vote would eliminate that weighing benefit, as state A would have roughly twice as many voters as B and hence twice as much say.

    This benefit given to the small states has shrunk by about a third since the country was formed. In the First Congress there were 68 congressmen and 26 senators generating a total of 94 electoral votes, so that a state's population was only a 68/94 = 72.3% factor of its say. Since the number of congressmen was fixed at 435, population now provides 435 / 535 (leaving out D.C.'s 3 electoral votes which aren't based on representation) or 81.3% of the weighting.

  2. States are better protected from voter irregularities occurring in other states - With the Electoral College, any ballot-box stuffing done by one state does not limit the say of others. Take one state with say 10 electoral votes, for example, they could have three, five, ten million falsified ballots for a candidate, they can go to town, it wouldn't matter, only that state's 10 electoral votes would be corrupted. Pennsylvania (20 votes), Iowa (6), Arizona (11), etc., would still have their say and their respective weighting. If we switched to a popular vote, those invalid votes would count to the national total, harming the say of states that run their elections more cleanly. In general:

    • With a national vote election, states which do a better job ensuring valid voting (photo ID, checking to make sure voter registrants are US citizens, alive, etc.) would lose say over states that tend to look the other way in such matters.

    • Conversely, because we use an Electoral College, there is much less incentive for ballot-box stuffing as it doesn't buy one party-dominant states tempted to engage in such activities anything. It results in cleaner elections, and hence a cleaner society, nationwide.

    • A national vote would encourage a race to the bottom in granting suffrage ("State A is now allowing their green card holders to vote, so we should also lest we lose our say...", "State B is now allowing 16 year olds to vote...", etc.)

  3. Close elections are much easier to resolve - The 2000 election between Bush and Gore took about one month to resolve but the focus thankfully was just with Florida and its then-25 electoral votes. Because the Electoral College was all that mattered, the other 49 states could be ignored, 20 inaccurate votes in Idaho for example or 30 missed votes in California could be disregarded. However, if we had a tightly close popular vote election, then every precinct in every county in every state would be subject to re-examination, to grab 5 votes here and 10 votes there because they all count towards the national vote total, not a situation anyone would relish.

  4. With the Electoral College, people are more likely to vote for a candidate based on his/her policies rather than on whether or not he/she has visited their state. - Voters in places like California and Tennessee where the outcome of the vote is not in doubt are perfectly fine with their candidate of choice never visiting their home state during the campaign. More than that, they don't actually want their candidate wasting time in their home states, instead wanting him or her to be in battleground states trying to win them over so their candidate can win. This provides a lot of relief to presidential candidates as it allows them to focus on visiting just 10-15 battleground states, a grueling enough task as it is.

    With a national popular vote, however, it would still make sense to visit vote-rich states regardless of their leanings, causing many voters to get offended if their candidate does not visit them, and possibly switch votes as a result. So the Electoral College is more likely to result in voters casting votes based on the candidate's policies than whether they visited their state, good for the nation as a whole.

  5. The Electoral College makes election night a lot more exciting to watch - A silly argument, but still true. With the Electoral College, viewers see a scoreboard of states that slowly get lit up in red and blue during the evening, for which viewers can celebrate or mourn each time a candidate wins or loses a state. With a national vote you're just waiting for a vote total at the very end, rather dull for all concerned. It would be similar to watching a football game in which all touchdowns and field goals are irrelevant but just the total yards gained within the 60 minutes of play determining the victor.

Finally, it should always be noted that a candidate who wins the popular vote and loses the electoral votes on an election based on the latter wouldn't necessarily have won the popular vote if it were based on the former, as the campaigning done--states visited, TV advertising strategy, issues chosen, voter turnout generated, etc.--is different under the two styles. A skilled candidate who can win with one set of rules quite frequently has the ability to win under another.

https://web-gmazza.rhcloud.com/blog/date/20160831 Wednesday August 31, 2016

TightBlog: August 2016 update

I'm back to work, my summer sabbatical is now complete, so I won't have nearly as much time to spend on TightBlog. The release of TightBlog 1.0 was a mission accomplished for me (similar to my prior time off, which I spent releasing Roller 5.1.) I did get a few simplifications in this month though, removing four more Java source files and 2 JSPs.

I advertised the release of TightBlog 1.0 on the Apache Roller users mailing list and got some more traffic from Roller users who did not yet know of my fork.

I said last month that "talk is cheap" and refrained from mentioning what I'd like to get done. But cheap talk is sometimes still useful: For TightBlog 2.0, I'd like to finish up the REST API for the application, a few more screens still rely on server-side screen generation. Once done, so little Struts code will be remaining that I plan on pulling out the Struts library and replacing it with Struts MVC, whose libraries are already being used for the REST controllers. I hope to get a tag management page in for deleting, renaming, and adding tags. Thymeleaf in addition to or replacing Velocity for the blog templates may also be a good idea. I might remove the Planet functionality as it was seldom used in Roller and the effort spent maintaining it can perhaps better be spent enhancing the rest. Finally, a package renaming and restructuring, replacing the legacy org.apache.roller.* naming with a new org.tightblog.* or similar.

(I still need to convert *this* blog to TightBlog--awaiting the new OpenShift PAAS update before doing so, but maybe I'll switch to Digital Ocean instead...)

https://web-gmazza.rhcloud.com/blog/date/20160731 Sunday July 31, 2016

TightBlog: July 2016 Update

I started a new TightBlog 2.0 branch, with more modernizations and new functionality planned for it. I'd like to list what I have planned, but talk is cheap--let me code and as I am able to complete new features I'll announce them. Just yesterday, for example, I switched to Thymeleaf for email messaging in the 2.0 branch with help from Jose Miguel Samper's article and Daniel Fernandez' sample application. I'm very happy with the results (no more placing HTML tags within Java strings) and expect to see Thymeleaf playing a role in more areas of the application. (A minor retirement, as well--I removed the "all blog" planet as it duplicates the front page theme and can anyway be manually created if desired.)

GitHub is reporting that I'm getting a few more people cloning my work since I announced its release, encouraging to see. TightBlog 1.0 was primarily about getting rid of yesterday's lard (and there was a mountain of it.) While there are still several classes that need refactoring or removal, its foundation is much more solid today, a good base for TightBlog 2.0 to build on.

https://web-gmazza.rhcloud.com/blog/date/20160717 Sunday July 17, 2016

First release - TightBlog v1.0.0 available!

I've found a good point to make my first TightBlog release, and so here it is. I held off on uploading a Java WAR file as TightBlog is primarily for Java enthusiasts who are well acquainted with the concept of mvn clean install and would presumably rely on that instead of any WAR I provided. After the dependencies (Spring, Struts, etc.) are downloaded, TightBlog takes less than a minute to build, and running mvn jetty:run from the app folder afterwards will allow you to quickly demo the application at http://localhost:8080/tightblog.

Some editing enhancements put in over the past week:

  • I pulled out the Xinha rich text editor, last updated in 2010, with the new Quill Editor which I'm downloading to the application via CDN.
  • I added Markdown (specifically CommonMark) as an editing option, giving bloggers now three options (including standard HTML entry) for their blogging pleasure.
  • JSoup was brought in to replace a 2009 script to filter out HTML tags disallowed by the TightBlog admin. Admins are provided six HTML sanitizing options for blog entries (including one option allowing everything), and three for blog comments.

These benefits are in addition to the "Notes" field on the blog edit page (to store metadata about the blog entry) I had added a while back.

Stats: 19 fewer Java source files, dropping me to 187, 62% fewer than the original 493 in the Roller release I forked. 209 issues closed, with eight open for the next release. 85K lines removed, with the removal of Xinha accounting for 15K of that. The GitHub contributors page and the OpenHub stats are indicating that, all told, I managed to drop the code about a third in size, even if I somehow sense I managed more than that.

https://web-gmazza.rhcloud.com/blog/date/20160705 Tuesday July 05, 2016

New user administration functionality in TightBlog

Over the past few days I've added some user administration options to upcoming TightBlog:

  1. Administrators can now require all new account registrants to be approved before they are able to log in. Upon a new registration, TightBlog administrators will be sent emails to either approve or decline the account request, with a subsequent response email sent to the registrant informing them that they can now log in or that their request has been disapproved.

    This option automatically activates email verification--after registration but before the approval routing the registrant will be sent an email to click on to verify ownership of the email account. This provides administrators higher confidence that the person requesting an account with the stated email address is indeed the email address' owner.

  2. Access rights within TightBlog are of two types: Global roles (one per user) and Weblog-specific roles (one for each blog a user has write access to). The former primarily specify whether a user is a regular blogger or a blog server administrator, the latter define the rights a user has for a given weblog: can make drafts but not publish (Contributor), can publish and handle comments and some design configuration (Publisher), or has full ownership of the blog (Owner)--can change the design templates, invite new members, etc.

    I added an additional Blog Creator global role to the Blogger and Admin roles already existing. Admin remains the same while Blog Creator has the former meaning of Blogger. The lone difference between Blogger and Blog Creator is that the latter can create new blogs while the former would need to have someone first invite them to a blog with whichever weblog role the inviter desires. This new option is helpful for administrators who have Contributors or Publishers whom they don't see a need to grant create blog rights, or for blog owners they wish to limit to one, already created, weblog.

    The system administration page allows administrators to choose Blogger or Blog Creator as the default role for new blog registrants, a setting which can be subsequently overridden by an administrator on the User Administration page.

  3. The User Administration page now shows account create date and last logged-in date to help administrators determine dormant accounts that should perhaps be disabled.


Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.