1: <?php
2: /**
3: * Chippyash Digest Authentication Manager
4: *
5: * @copyright Ashley Kitson, UK, 2014
6: * @license GPL 3.0+
7: */
8: namespace Chippyash\Authentication\Manager;
9:
10: use Chippyash\Authentication\Manager\ManagerInterface;
11: use Chippyash\Authentication\Manager\Exceptions\AuthManagerException;
12: use Chippyash\Authentication\Manager\Digest\DigestCollectionInterface;
13: use Chippyash\Type\String\StringType;
14:
15: /**
16: * Manage a Digest file
17: *
18: * @link http://framework.zend.com/manual/current/en/modules/zend.authentication.adapter.digest.html
19: * @link http://en.wikipedia.org/wiki/Digest_access_authentication
20: * @link http://httpd.apache.org/docs/2.2/programs/htdigest.html
21: */
22: class DigestManager implements ManagerInterface
23: {
24: const ERR_UID_EXISTS_TPL = 'Uid: %s already exists';
25: const ERR_UID_NOTEXISTS_TPL = 'Uid: %s does not exist';
26: const ERR_CANNOT_DEL_DIGEST_TPL = 'Cannot delete digest identified by: %s';
27:
28: /**
29: * Digest collection
30: * @var Chippyash\Authentication\Manager\Digest\DigestCollectionInterface
31: */
32: protected $collection;
33:
34: /**
35: * Shall we write file after a delete?
36: * Set to false on an update()
37: * @var boolean
38: */
39: protected $doDeleteWrite = true;
40:
41: /**
42: * Constructor
43: *
44: * @param DigestCollectionInterface $collection
45: */
46: public function __construct(DigestCollectionInterface $collection)
47: {
48: $this->collection = $collection;
49: $this->init();
50: }
51:
52: /**
53: * Add new entry to digest
54: *
55: * @param StringType $uid
56: * @param StringType $pwd
57: * @return Bool True on success else false
58: * @throws Chippyash\Authentication\Manager\Exceptions\AuthManagerException
59: */
60: public function create(StringType $uid, StringType $pwd)
61: {
62: if ($this->collection->findByUid($uid)->get() !== false) {
63: throw new AuthManagerException(sprintf(self::ERR_UID_EXISTS_TPL, $uid));
64: }
65:
66: return ($this->collection->add($uid, $pwd)->get() && $this->collection->write()->get());
67: }
68:
69: /**
70: * Return raw record from target system
71: *
72: * @param StringType $uid
73: *
74: * @return String Digest line
75: *
76: * @throws Chippyash\Authentication\Manager\Exceptions\AuthManagerException
77: */
78: public function read(StringType $uid)
79: {
80: $index = $this->collection->findByUid($uid);
81: if ($index() === false) {
82: throw new AuthManagerException(sprintf(self::ERR_UID_NOTEXISTS_TPL, $uid));
83: }
84:
85: return $this->collection->asString($index)->get();
86: }
87:
88: /**
89: * Change password for user in digest
90: *
91: * @param StringType $uid
92: * @param StringType $pwd
93: *
94: * @return Bool
95: *
96: * @throws Chippyash\Authentication\Manager\Exceptions\AuthManagerException
97: */
98: public function update(StringType $uid, StringType $pwd)
99: {
100: $this->doDeleteWrite = false;
101: if (!$this->delete($uid)) {
102: throw new AuthManagerException(sprintf(self::ERR_CANNOT_DEL_DIGEST_TPL, $uid));
103: }
104:
105: return $this->create($uid, $pwd);
106: }
107:
108: /**
109: * Delete user from digest
110: *
111: * @param StringType $uid
112: *
113: * @return Bool true on success else false
114: *
115: * @throws Chippyash\Authentication\Manager\Exceptions\AuthManagerException
116: */
117: public function delete(StringType $uid)
118: {
119: $index = $this->collection->findByUid($uid);
120: if ($index() === false) {
121: throw new AuthManagerException(sprintf(self::ERR_UID_NOTEXISTS_TPL, $uid));
122: }
123: $this->collection->del($index);
124:
125: if ($this->doDeleteWrite) {
126: $ret = $this->collection->write()->get();
127: } else {
128: $this->doDeleteWrite = true;
129: $ret = true;
130: }
131:
132: return $ret;
133: }
134:
135: /**
136: * Does digest have identity specified by uid
137: *
138: * @param StringType $uid
139: *
140: * @return Bool True if entry exists else false
141: */
142: public function has(StringType $uid)
143: {
144: $index = $this->collection->findByUid($uid);
145: if ($index() === false) {
146: return false;
147: }
148:
149: return true;
150: }
151:
152: /**
153: * Initialise the manager from source
154: * @return \Chippyash\Authentication\Manager\DigestManager
155: */
156: public function init()
157: {
158: $this->collection->read();
159: return $this;
160: }
161: }
162: