Skip to content

Commit

Permalink
Add authentication (#225)
Browse files Browse the repository at this point in the history
Fixup isset check

Test error fixes

Add logger get/set test

Test username/password

Add documentation for auth

Added some more documentation

Try to make Solr secured with BasicAuth
  • Loading branch information
Firesphere authored Oct 3, 2020
1 parent e9bdb2f commit 6e743b7
Show file tree
Hide file tree
Showing 65 changed files with 497 additions and 350 deletions.
5 changes: 5 additions & 0 deletions .circleci/TestIndexTwo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ Firesphere\SolrSearch\Services\SolrCoreService:
- Firesphere\SolrSearch\Tests\TestIndex
- Firesphere\SolrSearch\Tests\TestIndexTwo
- Firesphere\SolrSearch\Tests\TestIndexThree
config:
endpoint:
localhost:
username: solr
password: SolrRocks
14 changes: 6 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ create_index_requirements: &CircleCITestIndexReqs
core_check: &CheckSolrCore
name: Check Solr Core - CircleCITestIndex is successfully created
command: |
RESPONSE=$(echo $(curl -I http://localhost:8983/solr/CircleCITestIndex/admin/ping | head -n1 ) | grep -o '200 OK')
RESPONSE=$(echo $(curl -u solr:SolrRocks -I http://localhost:8983/solr/CircleCITestIndex/admin/ping | head -n1 ) | grep -o '200 OK')
if [[ $RESPONSE != '200 OK' ]]; then echo "Solr Core - CircleCITestIndex is not created"; exit 1; fi
echo "CircleCITestIndex is successfully created"
composer: &composerRequirements
Expand Down Expand Up @@ -89,17 +89,18 @@ jobs:
name: Run Solr Configure
command: |
service apache2 restart
service solr restart
mkdir -p /var/www/html/.solr && chmod -R 777 /var/www/html/.solr
mkdir -p /var/www/html/.solr/data && chmod -R 777 /var/www/html/.solr
cp .circleci/security.json /var/www/html/.solr/data/security.json
chown -R solr:solr /var/www/html/.solr
service solr restart
su solr vendor/bin/sake dev/tasks/SolrConfigureTask
- run: *CheckSolrCore
- run: su solr vendor/bin/sake dev/tasks/SolrIndexTask unittest=true
- run:
name: Check Solr has successfully indexed the default 3 pages
command: |
wget http://localhost:8983/solr/CircleCITestIndex/update?commit=true
RESPONSE=$(echo $(curl http://localhost:8983/solr/CircleCITestIndex/select?q=*) | grep -o '"numFound":3')
RESPONSE=$(echo $(curl -u solr:SolrRocks http://localhost:8983/solr/CircleCITestIndex/select?q=*) | grep -o '"numFound":3')
if [[ -z "$RESPONSE" ]]; then echo "No indexed documents"; exit 1; fi
echo "Solr has successfully indexed documents"
- run:
Expand Down Expand Up @@ -239,9 +240,7 @@ jobs:
- run:
name: Clear out old docs
command: |
rm -rf solr
rm -rf solr-api
rm -rf solr-docs
rm -rf solr*
- run:
name: PHP API Docs
command: |
Expand Down Expand Up @@ -274,7 +273,6 @@ jobs:
name: Markdown to HTML
command: |
yarn docs
rm -rf docs
mv _docs solr-docs
- run:
name: Commit and upload if it's master
Expand Down
23 changes: 23 additions & 0 deletions .circleci/security.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"authentication": {
"blockUnknown": true,
"class": "solr.BasicAuthPlugin",
"credentials": {
"solr": "IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="
},
"realm": "My Solr users",
"forwardCredentials": false
},
"authorization": {
"class": "solr.RuleBasedAuthorizationPlugin",
"permissions": [
{
"name": "security-edit",
"role": "admin"
}
],
"user-role": {
"solr": "admin"
}
}
}
2 changes: 1 addition & 1 deletion docs/02-Solr.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ This will install Solr 8.x as a service on your (virtual) machine

## Vagrant machines

See [Known issues](13-Help/03-Known-issues.md) for known issues with Vagrant
See [Known issues](14-Help/03-Known-issues.md) for known issues with permissions
157 changes: 16 additions & 141 deletions docs/03-Usage.md → docs/03-Set-up-and-Configuration.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Usage
# Set-up and configuration

## Getting started

Expand Down Expand Up @@ -61,6 +61,20 @@ store:
uri: 'https://mydomain.com'
```

### Authentication

Solr supports several ways of adding authentication to the instance.

The module only supports Basic Authentication, which can be added in the YML config like so:
```yaml
Firesphere\SolrSearch\Services\SolrCoreService:
config:
endpoint:
myhostname:
username: solr
password: SolrRocks
```

### Debug

You can force the debugging to false, by setting the debug flag. If you omit this tag, CLI and Dev mode
Expand Down Expand Up @@ -164,7 +178,7 @@ to create in the first step of this document.

#### Moving from init to YML

The [compatibility module](11-Submodules/01-Fulltext-Search-Compatibility.md) has an optional extension
The [compatibility module](12-Submodules/01-Fulltext-Search-Compatibility.md) has an optional extension
method that allows you to build your index and then generate the YML content for you.
See the compatibility module for more details.

Expand Down Expand Up @@ -256,146 +270,7 @@ Firesphere\SolrSearch\Services\SolrCoreService:

Looking at the `tests` folder, there is a `TestIndexFour`. This index is not loaded unless explicitly asked.

# Executing a search

To search, here's an example using all the features, and setting the resulting outcome from the search
onto the current `Controller` to be useable in templates.

More advanced filter options are available, see the [Advanced filters & excludes](04-Advanced-Options/05-Filters-excludes.md)
page for more information.

```php
class SearchController extends PageController
{
protected $ResultSet;
public function setResultSet($set)
{
$this->ResultSet = $set;
}
/**
* @param array $data Data from the submission
* @param SearchForm $form Submitted search form
* @return $this
*/
public function searchMyContent($data, $form)
{
$searchVars = $this->getRequest()->getVars();
if (!empty($searchVars)) {
// Set the query, possibly to be used to display it back to the user
$this->setQuery($searchVars);
/** @var BaseIndex $index */
$index = Injector::inst()->get(MyIndex::class);
// Start building the query, by adding the query term
$query = new BaseQuery();
$query->addTerm($searchVars['Query']);
// Set the facets
$query->setFacetsMinCount(1);
$facetedFields = $index->getFacetFields();
foreach ($facetedFields as $className => $field) {
if (!empty($data[$field['Title']])) {
$query->addFacetFilter($field['Title'], $data[$field['Title']]);
}
}
// Set the startpoint of the results
$offset = $this->getRequest()->getVar('start') ?: 0;
$query->setStart($offset);
// Assuming "Order" is your query parameter that defines the sort order
$sort = isset($data['Order']) ? strtolower($data['Order']) : 'asc';
// Set the sorting. This can be an array of multiple sorts
$params['sort'] = [MySortableClass::class . '_Created ' => $sort];
$query->setSort($params['sort']);
// Alternative:
$query->addSort(MySortableClass::class . '_Created', $sort);
// Execute the search
$result = $index->doSearch($query);
// Assuming the controller has this method and variable
$this->setResultSet($result);
}
return $this;
}
}
```

Now, in your template, you could do something like this, to display the results, based on Bootstrap:
```html
<% with $ResultSet %>
<% if $TotalItems %>
<div class="clearfix"></div>
<div class="col-xs-12"><br/>
<span class="pull-right">
Results: <span class="js-total-results">$TotalItems</span>
</span>
</div>
<% else %>
<h6 class="col-xs-12 col-md-6">No results found for your query "<i>$Up.Query.XML</i>"</h6>
<span class="hidden js-total-results">0</span>
<% end_if %>
<% if $Spellcheck.Count %>
<h6 class="col-xs-12 col-md-6">You might have a spelling error, try
<a href="{$Top.Link}search/?Query={$SpellcheckLink}">$SpellcheckTitle</a> instead?
</h6>
<% end_if %>
<div class="col-xs-12">
<% if $TotalItems %>
<p>&nbsp;</p>
<% loop $PaginatedMatches %>
<% include Match %>
<% end_loop %>
<% end_if %>
<% include Pagination %>
<p>&nbsp;</p>
</div>
<nav id="pageNav" role="navigation" class="page-sidebar-widget page-sidebar-nav">
<div class="row">
<% with $Facets %>
<!-- You can repeat the following for each of your Facet Titles -->
<div class="col-xs-6 col-md-12">
<h3 class="h4 page-sidebar-header">YourFacetName</h3>
<ul class="list-unstyled">
<% loop $YourFacetName %>
<li>
<a href="$SearchLink" title="$Name $Topic.XML">
$Name ($FacetCount)
</a>
</li>
<% end_loop %>
</ul>
</div>
<% end_with %>
</div>
</nav>
<% end_with %>
```

Example of a `$SearchLink` method, that'll return a link to the Faceted set:

```php
class FacetedObject
{
public function getSearchLink()
{
$controller = Controller::curr();
$vars = $controller->getRequest()->getVars();
$vars['MyFacetObject[]'] = $this->ID;
return $controller->Link('search?' . http_build_query($vars));
}
}
```

----------
<sup>1</sup> Although not required, it's highly recommended

Expand Down
Loading

0 comments on commit 6e743b7

Please sign in to comment.