DotNetNuke Admin Pages

DotNetNuke divides the admin pages for a website into two sections:  common settings and advanced settings.

To view the admin options hover over the

Section Common Settings covers:

Section Advanced Settings covers …

Blocking xml-rpc Access

I’ve heard that I should disable xml-rpc on a WordPress website.

Why should I disable it and how?

XML-RPC What is it? And how to Disable.

What is xml-rpc?

This is the connection for the WordPress API interface.

It allows apps such as the WordPress app on an iPhone or Android device to connect to the WordPress website. With the app I can readily edit and crate blogs posts.

No need to navigate to the website with a browser to login and perform these actions.

Trackbacks and Pingbacks whereby the website checks to see who is referencing its post content.

The popular JetPack plugin, developed by Automattic, relies heavily on the use of xml-rpc.

Why would you want to restrict it?

It poses a security risk.

There’s potentially less chance of detection attempting to gain access this way.

Has the potential to be the target for a denial of service attack.

How to restrict it?

xml-rpc is implemented using the file xmlrpc.php.

Access to the file can be restricted completely or limited to configured IP addresses.

To do this we’ll use the file .htaccess, located in the root of the website, restricting file access by IP Address.

Here’s the block of lines which we’ll add to the file.

# block xml-rpc
<Files "xmlrpc.php">
Order Deny,Allow
deny from all
allow from 192.0.2.52
</Files>

We’ll chose to set the order as deny first then allow

Order Deny, Allow

This allows us to block all sites with the simple

deny from all

A one line global block on access.

If we are implementing a full restriction on access that’s all we would need.

But to allow access from a single IP address we add the following

allow from 192.0.2.52

Further instances of this can be added with single IP addresses or ranges.

Further thoughts

Its going to be a compromise. is there a plugin or app which you can’t do without? If the answer is yes then completely shutting down xml-rpc is probably not going to be an option.

Maybe restrict the access to a limited range or IP addresses. Dependant upon what you wish to connect to it this may be an option. Do you only blog with the WordPress app from a fixed location? Then not a problem.

If none of these is an option for you then leaving access to xml-rpc open will be your option.

Anything more?

Yes, you can use one of the WordPress security plugins to monitor and take action against attempts to gain access via xml-rpc.

And there’s the development of the WordPress Rest API – check to see whether there’s an equivalent of your must have app or program which uses this.

References

WordPress Codex: XML RPC Support

Wikipedia: XML RPC

DotNetNuke Admin Themes

The DotNetNuke admin themes page shows the skins and containers available for use by the website.

The page is dividend into 4 sections:

  • Theme editor
  • Themes
  • Containers
  • Edit Theme Attributes

Theme editor

Use the dropdown lists and checkboxes to restrict the themes and containers listed.

Whilst reviewing the page I found that older themes were showing the message: This is a Legacy Theme. Although the entries are still apearing in the lists.

Themes

The themes available for use on the website are shown, with an image preview. For each there’s the option to preview what the site will look like with the chosen the theme. And alongside a button to apply the chosen theme.

Below the container list are two buttons to Parse Theme Package and Restore Default Theme.

Take care choosing to parse the theme package. Its looking at the original configuration. The results may be helpful if things aren’t working but can revert changes.

Containers

Like the themes, the available containers are shown as images, with buttons for preview and apply.

Edit Theme Attributes

I’ve never used the attributes editing option, preferring to edit the relevant files directly. However, its does present a convenient way to make changes to the appropriate components of a theme or container.

For example if the breadcrumb is in use then the separator can be easily changed simply by selecting the file, the Breadcrumb token the separator setting and adding a new value. An example might be changing from the pipe symbol “|” to a greater than sign “>”.

Update and Replace Field Value with New Value

We can use SQL to replace the value in field with a new value.

There’s no need to search for those rows affecting, downloading each in turn, making the amendment and finally making the update.

For the update of the given field in the table we can use one SQL statement, changing all matching entries.

Here’s the general format of the search and replace:

UPDATE dbo.TableName
SET Field = REPLACE(Field, CurrentString, NewString)

So considering a spelling error, or perhaps a change of product name, we wish to update the product details table:

UPDATE dbo.product
SET details = REPLACE(details, 'appls', 'apples')

Note, the searched for string doesn’t have percentage characters. The search is a true search, not an SQL like.

An SQL like would be used as

SELECT * FROM details like ‘%apple%’

DotNetNuke Admin Device Preview Management

On the Admin Device Preview Management page there are a number of pre-defined mobile devices, tablets and phones.

Above the list of mobile devices there are:

  • A combo box (to add a new name, or select an existing device)
  • 3 text boxes to specify the browser size and agent details.

Create and review the mobile device options.

The mobile devices which have been added are used in the mobile preview.

To view the mobile version of a page, click on edit page, in the top right corner, and from the drop down list select Mobile Preview. A pop-up will then show with the devices listed and their orientation details. Make your selection from the configured list.

Alternatively – rather than configure individual devices, why not configure the typical responsive device sizing and orientations?

Admin Advanced Pages

Further pages in the admin common settings section are given in the table below:

Advanced Configuration SettingsDevice Preview ManagementExtensionsGoogle Analytics
LanguagesListsNewslettersSearch Engine Site Map
Site LogSite Redirection ManagementSite wizardSkins
TaxonomyVendors  

Unused Domain Name and IP Addresses for Documentation

When writing documentation or blog posts it would be nice to include domain references which don’t link to real websites.

Fortunately the people who organised the domain DNS references set aside some domains specifically for this.

The domains won’t be made available and are to be kept purely for documentation.

There’s a document detailing Reserved Top Level DNS Names.

Of particular interest is the use of the following in documentation

  • example.com
  • example.net
  • example.org
  • .example

Well that’s the domain names sorted. What about IP addresses?

Yes, these have been thought about too.

There’s 3 series of the older ipv4 address blocks kept aside for this. Details are given in the document IPv4 Address Blocks Reserved for Documentation.

The address blocks available are:

  • 192.0.2.0/24 (TEST-NET-1)
  • 198.51.100.0/24 (TEST-NET-2)
  • 203.0.113.0/24 (TEST-NET-3)

And there’s the one for ipv6, covered by the document IPv6 Address Prefix Reserved for Documentation.

For ipv6 there’s a reserved prefix, given as 2001:DB8::/32

DotNetNuke Admin Search Admin

The DotNetNuke Search Admin page is for the management of the internal search indexing, not for search engines such as Google, Baidu, and Bing.

I have found that over time some entries within the search index are old, having lost their prior page content reference.

The search admin page can be used to refresh the references held, ensuring that the content is relevant to searches.

You may wish to consider the items listed under the Ignore Words tab. Adding items here can reduce the number of entries retained in the search index, reducing the size of the database tables and increasing the speed of the website, both in terms of searching and general performance.

If re-indexing the content , on the General tab view, doesn’t flush the old content, or more significantly it times out, this can be an indication that the tables have become too large. You may wish to consider an alternative method for emptying the search tables.

MailChimp Modify Line Spacing

On emails sent from MailChimp the line spacing and the gap between paragraphs may be too large.

Can the spacing be easily configured?

The line spacing, the height of each line of text, can be set within the template editing. However, the option to configure the spacing between paragraphs is not given.

Login to your MailChimp account and click on Templates in the menu at the top left of the screen.

The view changes to show your list of templates which have been created.

Its assumed that you wish to modify an existing email template. To avoid making uncorrectable changes to one of your templates – take a copy. From the list of templates click on the Edit drop down list at the right hand side. Select Replicate.

Rename the template appropriately.

Now click on Edit at the right hand end of the line.

Shown on the page on the right hand side are content features to be included (these can be dragged into the template and used). The second tab Design provides a number of options affecting the look of your Mailchimp email.

The image below shows the expanded Body Design section, with the line height set to 1 1/2 spacing.

MailChimp modify line spacing: body design

Your selection is reflected in the template view, on the left of the page.

Similarly the spacing for the headings can be set within the Page section.

For individual content blocks added to thetemplate further customisation of the spacing may be included. The text block includes a Line Height setting under the Style tab.

If the spacing options given above are not enough and you wish to edit your template to a finer degree the option is to edit the themes HTML.

Further Options

If you wish to modify other aspects of the email styling, for example the spacing after a paragraph, a different approach is required.

Paragraph Margins – Individual Approach

As an example, to modify the spacing after the paragraphs in a text block

Click on the text block in the template view to show its Content; Style; and Settings on the right hand pane.

Select the Content view.

MailChimp modify line spacing: text block

Within the editor click on the icon highlighted above, to show the HTML code view.

<h1>Designing Your Email</h1>

<h3>Creating an elegant email is simple</h3>

<p>Now that you’ve selected a template to work with, drag in content blocks to define the structure of your message. Don’t worry, you can always delete or rearrange blocks as needed. Then click “Design” to define fonts, colors, and styles.</p>

<p>Need inspiration for your design? <a class="mc-template-link" href="http://inspiration.mailchimp.com">Here’s what other MailChimp users are doing.</a></p>

Note in the updated code, below, I’ve modified the second paragraph to add a setting (style) for the bottom margin:

<p style=”margin-bottom:10px”>

<h1>Designing Your Email</h1>

<h3>Creating an elegant email is simple</h3>

<p style="margin-bottom:10px">Now that you’ve selected a template to work with, drag in content blocks to define the structure of your message. Don’t worry, you can always delete or rearrange blocks as needed. Then click “Design” to define fonts, colors, and styles.</p>

<p>Need inspiration for your design? <a class="mc-template-link" href="http://inspiration.mailchimp.com">Here’s what other MailChimp users are doing.</a></p>

Change the number of pixels set to suit your presentation.

A Global Approach

MailChimp doesn’t offer the global paragraph and line spacing settings as global settings

To make the changes globally will require editing of the HTML code of the template.

To edit the template’s HTML the theme is first exported, edited, and then once more imported for use.

On the list view of the templates this is offered as an entry in the dropdown list along with edit at the right hand side.

Select Export as HTML.

MailChimp presents this as an option with a warning that the imported template doesn’t allow visual blocks to be added, edited or moved.

Save the template.

You may find that copying the HTML view of the email template locally and making the edits a better way.

Open the file with an HTML editor such as Geany.

MailChimp modify line: HTML export

Within the MailChimp template there is styling at the top. This is used to set the appearance of the email. Covering elements such as the font colour; page background colour; and the font size.

Its within this styling section <style type=”text/css”> that the line-height and the margins will be edited.

As shown above its the section, below which is the base configuration for paragraphs.

p{
  margin:1em 0;
  padding:0;
}

In the above margin:1em 0; sets the margin above and below the paragraph to the default value. If you wish to make it greater or smaller modify this value to, for example,

p{
  margin:1em 0;
  padding:0;
  margin-bottom:20px;
}

The line-height for the content body is configured in the section:

.bodyContainer .mcnTextContent,.bodyContainer .mcnTextContent p

observe the content below:

/*
@tab Body
@section body text
@tip Set the styling for your email's body text. Choose a size and color that is easy to read.
*/
.bodyContainer .mcnTextContent,.bodyContainer .mcnTextContent p{
  /*@editable*/color:#606060;
  /*@editable*/font-family:Helvetica;
  /*@editable*/font-size:15px;
  /*@editable*/line-height:200%;
  /*@editable*/text-align:left;
}

Within the above modify line-height to a smaller percentage to bring the liens of text closer together. You may also add the paragraph top and bottom margins here.

Once the edits are completed theHTML cotnent can be added back as a template.

On the MailChimp Templates view click on the button Create Template, top right corner.

The new template will be created using code, click on the tab Code your own. within this tab click on Import HTML. Follow the instructions to upload your saved template HTML file.

Don’t forget to click on Save.

Unfortunately as already highlighted when exporting the HTML the visual block editing is now missing on the right hand side of the page.

References

MailChimp templates HTML email basics

W3Schools: HTML paragraphs

W3Schools: CSS line-height property

W3Schools: CSS margin property

Using htaccess to Restrict File Access by IP Address

Every so often there’s a new exploit targeted. This shows as an increase in the rate against a particular file.

For example some time ago there were lots of attempts trying to access to the file upload.php in either themes or plug-ins.

This reflects a vulnerability in an inclusion within a number of themes.

With the aim that only authorised users and IP address shall be looking to upload content I looked towards using the .htaccess file to add the restriction.

The .htaccess file is located in the root of the website. It allows local configuration overrides of the Apache web server.

Blocking access by IP Address

Access is restricted using the old favourite of deny and allow.

For example to only allow access from the IP address of 192.0.2.52.

Order Deny, Allow
Deny from all
Allow from 192.0.2.52

Here we first set the access rule order to be deny, then allow.

Where the order defines the sequence in which the deny and allow rules are processed.

The actual order in which the rules are presented within the .htaccess file doesn’t matter. Based upon the order either the deny rules will be processed first or the allow ones.

Beware – if the order in the above were set to Order Allow, Deny, the result would be to prevent access to all. The single address would be allowed, followed by all attempts at access being denied.

The restriction can be further adapted to incorporate the files structure. Either individual files or directories.

<Files /index.php>
Order Deny,Allow
Deny from all
Allow from 192.0.2.52
</Files>

In the above example a specific file is entered. The index.php file in the root of the website.

An alternative is a match, without the directory structure, with the simple name of the file.

This is the form which we will use, replacing /index.php with upload.php. It will then be restricted in whatever directory it is found, accounting for the potential themes and plug-ins.

<Files upload.php>
Order Deny,Allow
Deny from all
Allow from 192.0.2.52
</Files>

Pattern matching, which follows the regular expressions may be used. For example to prevent access to certain file types:

<Files ~ “.(inc|zip|rar)$”>

Here I’ve prevented access to compressed files and includes.

When matching multiple files FilesMatch is used in preference to Files. Although either may be used, its easy to read and gather the implication of the code within the .htaccess file where FilesMatch is showing an expectation of multiple matches, as opposed to the single file.

CustomValidator with Client JavaScript

I had crafted a custom validator for an DNN asp.net web page with a function to validate form elements.

Using the DNN pop-up calendar, with appropriate date formatting according to the browser, had issues with visitors not setting the language within the browser correctly. It was also decided that using 3 dropdownlists would provide a better control of the selection, and less issue with date selection on mobile devices using the pop up calendar.

I added 3 drop down lists to a web page to facilitate date selection.

To ensure that the date was valid I created a custom control to be referenced on the page with validateDate()

Initially I found that the function was firing, but that the status wasn’t being returned.

The JavaScript function was amended, requiring both sender and args parameters, like so:

<script type="text/javascript">
function validateDate(sender,args) {
    var ddlDay = $("#<% = ddlTheDay.clientid %>");
    var ddlMonth = $("#<% = ddlTheMonth.clientid %>");
    var ddlYear = $("#<% = ddlTheYear.clientid %>");

    document.getElementById('<% = cvTheDay.clientid %>').style.display = 'none';
    document.getElementById('<% = cvTheMonth.clientid %>').style.display = 'none';
    document.getElementById('<% = cvTheYear.clientid %>').style.display = 'none';

    // check date was selected
    if (ddlDay.val() < 0 ||
        ddlMonth.val() < 0 ||
        ddlYear.val() < 0) { // if ($('.validateDate').hasClass('validDate')){ // $('.validateDate').toggleClass('inValidDate validDate'); //} args.IsValid = false; return false; } // ensure days value correct if (ddlDay.val() > daysInMonth(ddlMonth.val(), ddlYear.val())) {
        args.IsValid = false;
        return false;
    }


    // check date is valid
    var dobDate = new Date(ddlYear.val(), ddlMonth.val() - 1, ddlDay.val());

    if (Object.prototype.toString.call(dobDate) === "[object Date]") {
        if (isNaN(dobDate.getTime())) {
            // date is not valid
            args.IsValid = false;
            return false;
        }
        else {
            // date is valid
            args.IsValid = true;
            return true;
        }
    }
    else {
        // not a date
        args.IsValid = false;
        return false;
    }
}

function daysInMonth(month, year) {
    return new Date(year, month, 0).getDate();
}
</script>

Shown below are the dropdownlists, together with their custom validators.

<asp:dropdownlist id="ddlTheDay" visible="true" runat="server" name="ddlTheDay" class="ddlTheDay" />
<asp:dropdownlist id="ddlTheMonth" visible="true" runat="server" name="ddlTheMonth" class="ddlTheMonth" />
<asp:dropdownlist id="ddlTheYear" visible="true" runat="server" name="ddlTheYear" class="ddlTheYear" />
<asp:customvalidator id="cvTheDay" runat="server" SetFocusOnError="True"
Display="Dynamic" ErrorMessage="The date is invalid!" ControlToValidate="ddlTheDay" ClientValidationFunction="validateDate" />
<asp:customvalidator id="cvTheMonth" runat="server" SetFocusOnError="True"
Display="Dynamic" ErrorMessage="The date is invalid!" ControlToValidate="ddlTheMonth" ClientValidationFunction="validateDate" />
<asp:customvalidator id="cvTheYear" runat="server" SetFocusOnError="True"
Display="Dynamic" ErrorMessage="The date is invalid!" ControlToValidate="ddlTheYear" ClientValidationFunction="validateDate" />
<div class="validateDate validDate">The date is invalid!</div>

As can be seen above I am using just the one div with the error announcement. Its default setting is within the module’s CSS file module.css, details are below:

.validateDate{color:#d00;font-weight:bold;}
.validDate{display:none;}
.invalidDate{display:block;}