Skip to content

Commit

Permalink
Added support for authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
kleiram committed Apr 13, 2013
1 parent f71ba13 commit 6359d73
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 4 deletions.
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ $files = $torrent->getFiles();
```

To find out which information is contained by the torrent, check
[Transmission\Torrent](https://github.com/kleiram/transmission-php/tree/master/lib/Transmission/Torrent.php).
[Transmission\Model\Torrent](https://github.com/kleiram/transmission-php/tree/master/lib/Transmission/Model/Torrent.php).

By default, the library will try to connect to `localhost:9091`. If you want to
connect to an other host or port you can create a new `Transmission\Client` and
Expand Down Expand Up @@ -84,6 +84,21 @@ use Transmission\Torrent;
$torrent = Torrent::add(/* base64-encoded metainfo */, null, true);
```

If the Transmission server is secured with a username and password you can
authenticate using the `Client` class:

```php
<?php
use Transmission\Client;
use Transmission\Torrent;

$client = new Client();
$client->authenticate('username', 'password');

// And you should pass the client to any static method you call!
$torrent = Torrent::get(1, $client);
```

For more examples, see the
[`examples`](https://github.com/kleiram/transmission-php/tree/master/examples)
directory.
Expand Down
38 changes: 35 additions & 3 deletions lib/Transmission/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
namespace Transmission;

use Buzz\Browser;
use Buzz\Listener\BasicAuthListener;
use Transmission\Exception\ConnectionException;
use Transmission\Exception\AuthenticationException;
use Transmission\Exception\InvalidResponseException;
use Transmission\Exception\UnexpectedResponseException;

Expand Down Expand Up @@ -43,6 +45,11 @@ class Client
*/
protected $browser;

/**
* @var string
*/
protected $authDigest;

/**
* Constructor
*
Expand All @@ -56,6 +63,17 @@ public function __construct($host = null, $port = null)
$this->setBrowser(new Browser());
}

/**
* Authenticate against the Transmission server
*
* @param string $username
* @param string $password
*/
public function authenticate($username, $password)
{
$this->authDigest = base64_encode($username .':'. $password);
}

/**
* Make an API call
*
Expand All @@ -77,12 +95,20 @@ public function call($method, array $arguments = array(), $tag = null)
$content['tag'] = (string) $tag;
}

$headers = array();

if (is_string($this->getToken())) {
$headers[] = sprintf('%s: %s', self::TOKEN_HEADER, $this->getToken());
}

if (is_string($this->authDigest)) {
$headers[] = sprintf('Authorization: Basic %s', $this->authDigest);
}

try {
$response = $this->browser->post(
$this->getUrl(),
array(sprintf(
'%s: %s', self::TOKEN_HEADER, $this->getToken()
)),
$headers,
json_encode($content)
);
} catch (\Exception $e) {
Expand All @@ -105,6 +131,12 @@ public function call($method, array $arguments = array(), $tag = null)
return $this->call($method, $arguments, $tag);
}

if ($statusCode === 401) {
throw new AuthenticationException(
'Access to the Transmission server requires authentication'
);
}

if ($statusCode !== 200) {
throw new UnexpectedResponseException(
'Unexpected response received from Transmission'
Expand Down
9 changes: 9 additions & 0 deletions lib/Transmission/Exception/AuthenticationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
namespace Transmission\Exception;

/**
* @author Ramon Kleiss <[email protected]>
*/
class AuthenticationException extends \RuntimeException
{
}
59 changes: 59 additions & 0 deletions tests/Transmission/Tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,65 @@ public function shouldMakeApiCalls()
$this->assertEquals('bar', $stdClass->foo);
}

/**
* @test
*/
public function shouldAuthenticate()
{
$response = $this->getMock('Buzz\Message\Response');
$response
->expects($this->once())
->method('getStatusCode')
->will($this->returnValue(200));

$response
->expects($this->once())
->method('getContent')
->will($this->returnValue('{"foo":"bar"}'));

$browser = $this->getMock('Buzz\Browser');
$browser
->expects($this->once())
->method('post')
->with(
'http://localhost:9091/transmission/rpc',
array(
'X-Transmission-Session-Id: foo',
'Authorization: Basic '. base64_encode('foo:bar')
)
)
->will($this->returnValue($response));

$client = new Client();
$client->setToken('foo');
$client->setBrowser($browser);
$client->authenticate('foo', 'bar');
$client->call('foo');
}

/**
* @test
* @expectedException Transmission\Exception\AuthenticationException
*/
public function shouldThrowExceptionOnAuthenticationError()
{
$response = $this->getMock('Buzz\Message\Response');
$response
->expects($this->once())
->method('getStatusCode')
->will($this->returnValue(401));

$browser = $this->getMock('Buzz\Browser');
$browser
->expects($this->once())
->method('post')
->will($this->returnValue($response));

$client = new Client();
$client->setBrowser($browser);
$client->call('foo');
}

/**
* @test
*/
Expand Down

0 comments on commit 6359d73

Please sign in to comment.