1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
43:
44: require_once(dirname(__FILE__) . '/classes.php');
45:
46: class Zenphoto_Authority {
47:
48: var $admin_users = NULL;
49: var $admin_groups = NULL;
50: var $admin_other = NULL;
51: var $admin_all = NULL;
52: var $rightsset = NULL;
53: protected $master_user = NULL;
54: static $preferred_version = 4;
55: static $supports_version = 4;
56: static $hashList = array('pbkdf2' => 3, 'pbkdf2*' => 2, 'sha1' => 1, 'md5' => 0);
57:
58: 59: 60: 61: 62:
63: function __construct() {
64: $this->admin_all = $this->admin_groups = $this->admin_users = $this->admin_other = array();
65: $sql = 'SELECT * FROM ' . prefix('administrators') . ' ORDER BY `rights` DESC, `id`';
66: $admins = query($sql, false);
67: if ($admins) {
68: while ($user = db_fetch_assoc($admins)) {
69: $this->admin_all[$user['id']] = $user;
70: switch ($user['valid']) {
71: case 1:
72: $this->admin_users[$user['id']] = $user;
73: if (empty($this->master_user))
74: $this->master_user = $user['user'];
75: break;
76: case 0:
77: $this->admin_groups[$user['id']] = $user;
78: break;
79: default:
80: $this->admin_other[$user['id']] = $user;
81: break;
82: }
83: }
84: db_free_result($admins);
85: }
86: }
87:
88: function getMasterUser() {
89: return new Zenphoto_Administrator($this->master_user, 1);
90: }
91:
92: function isMasterUser($user) {
93: return $user == $this->master_user;
94: }
95:
96: 97: 98: 99: 100:
101: function getOptionsSupported() {
102: $encodings = self::$hashList;
103: unset($encodings['pbkdf2*']);
104: if (!function_exists('hash')) {
105: unset($encodings['pbkdf2']);
106: }
107: return array(gettext('Primary album edit') => array('key' => 'user_album_edit_default', 'type' => OPTION_TYPE_CHECKBOX,
108: 'desc' => gettext('Check if you want <em>edit rights</em> automatically assigned when a user <em>primary album</em> is created.')),
109: gettext('Minimum password strength') => array('key' => 'password_strength', 'type' => OPTION_TYPE_CUSTOM,
110: 'desc' => sprintf(gettext('Users must provide passwords a strength of at least %s. The repeat password field will be disabled until this floor is met.'), '<span id="password_strength_display">' . getOption('password_strength') . '</span>')),
111: gettext('Password hash algorithm') => array('key' => 'strong_hash', 'type' => OPTION_TYPE_SELECTOR,
112: 'selections' => $encodings,
113: 'desc' => sprintf(gettext('The hashing algorithm used by Zenphoto. In order of robustness the choices are %s'), '<code>' . implode('</code> > <code>', array_flip($encodings)) . '</code>'))
114: );
115: }
116:
117: 118: 119:
120: function handleOption($option, $currentValue) {
121: global $_zp_current_admin_obj;
122: switch ($option) {
123: case 'password_strength':
124: ?>
125: <input type="hidden" size="3" id="password_strength" name="password_strength" value="<?php echo getOption('password_strength'); ?>" />
126: <script type="text/javascript">
127:
128: function sliderColor(strength) {
129: var url = 'url(<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/strengths/strength' + strength + '.png)';
130: $('#slider-password_strength').css('background-image', url);
131: }
132: $(function() {
133: $("#slider-password_strength").slider({
134: <?php $v = getOption('password_strength'); ?>
135: startValue: <?php echo $v; ?>,
136: value: <?php echo $v; ?>,
137: min: 1,
138: max: 30,
139: slide: function(event, ui) {
140: $("#password_strength").val(ui.value);
141: $('#password_strength_display').html(ui.value);
142: sliderColor(ui.value);
143: }
144: });
145: var strength = $("#slider-password_strength").slider("value");
146: $("#password_strength").val(strength);
147: $('#password_strength_display').html(strength);
148: sliderColor(strength);
149: });
150:
151: </script>
152: <div id="slider-password_strength"></div>
153: <?php
154: break;
155: }
156: }
157:
158: static function getVersion() {
159: $v = getOption('libauth_version');
160: if (empty($v)) {
161: return self::$preferred_version;
162: } else {
163: return $v;
164: }
165: }
166:
167: 168: 169: 170: 171: 172: 173:
174: static function passwordHash($user, $pass, $hash_type = NULL) {
175: if (is_null($hash_type)) {
176: $hash_type = getOption('strong_hash');
177: }
178: switch ($hash_type) {
179: case 1:
180: $hash = sha1($user . $pass . HASH_SEED);
181: break;
182: case 2:
183:
184: $hash = base64_encode(self::pbkdf2($pass, $user . HASH_SEED));
185: break;
186: case 3:
187: $hash = str_replace('+', '-', base64_encode(self::pbkdf2($pass, $user . HASH_SEED)));
188: break;
189: default:
190: $hash = md5($user . $pass . HASH_SEED);
191: break;
192: }
193: if (DEBUG_LOGIN) {
194: debugLog("passwordHash($user, $pass, $hash_type)[ " . HASH_SEED . " ]:$hash");
195: }
196: return $hash;
197: }
198:
199: 200: 201: 202: 203: 204: 205: 206:
207: function getAdministrators($what = 'users') {
208: switch ($what) {
209: case 'users':
210: return $this->admin_users;
211: case 'groups':
212: return $this->admin_groups;
213: case 'allusers':
214: return array_merge($this->admin_users, $this->admin_other);
215: default:
216: return $this->admin_all;
217: }
218: }
219:
220: 221: 222: 223: 224:
225: static function getAnAdmin($criteria) {
226: $selector = array();
227: foreach ($criteria as $match => $value) {
228: if (is_numeric($value)) {
229: $selector[] = $match . $value;
230: } else {
231: $selector[] = $match . db_quote($value);
232: }
233: }
234: $sql = 'SELECT * FROM ' . prefix('administrators') . ' WHERE ' . implode(' AND ', $selector) . ' LIMIT 1';
235: $admin = query_single_row($sql, false);
236: if ($admin) {
237: return self::newAdministrator($admin['user'], $admin['valid']);
238: } else {
239: return NULL;
240: }
241: }
242:
243: 244: 245: 246: 247: 248: 249: 250: 251:
252: function checkAuthorization($authCode, $id) {
253: global $_zp_current_admin_obj;
254: if (DEBUG_LOGIN) {
255: debugLogBacktrace("checkAuthorization($authCode, $id)");
256: }
257:
258:
259: $admins = $this->getAdministrators();
260: if (count($admins) == 0) {
261: if (DEBUG_LOGIN) {
262: debugLog("checkAuthorization: no admins");
263: }
264: $_zp_current_admin_obj = new Zenphoto_Administrator('', 1);
265: $_zp_current_admin_obj->set('id', 0);
266: $_zp_current_admin_obj->reset = true;
267: return ADMIN_RIGHTS;
268: }
269: if (is_object($_zp_current_admin_obj) && $_zp_current_admin_obj->reset) {
270: if (DEBUG_LOGIN) {
271: debugLog("checkAuthorization: reset request");
272: }
273: return $_zp_current_admin_obj->getRights();
274: }
275:
276:
277: $_zp_current_admin_obj = NULL;
278: if (empty($authCode))
279: return 0;
280: if (DEBUG_LOGIN) {
281: debugLogVar("checkAuthorization: admins", $admins);
282: }
283: $rights = 0;
284: $criteria = array('`pass`=' => $authCode, '`valid`=' => 1);
285: if (!empty($id)) {
286: $criteria['`id`='] = $id;
287: }
288: $user = self::getAnAdmin($criteria);
289: if (is_object($user)) {
290: $_zp_current_admin_obj = $user;
291: $rights = $user->getRights();
292: if (DEBUG_LOGIN) {
293: debugLog(sprintf('checkAuthorization: from %1$s->%2$X', $authCode, $rights));
294: }
295: return $rights;
296: }
297: $_zp_current_admin_obj = NULL;
298: if (DEBUG_LOGIN) {
299: debugLog("checkAuthorization: no match");
300: }
301: return 0;
302: }
303:
304: 305: 306: 307: 308: 309: 310: 311: 312:
313: function checkLogon($user, $pass) {
314: $userobj = self::getAnAdmin(array('`user`=' => $user, '`valid`=' => 1));
315: if ($userobj) {
316: $hash = self::passwordHash($user, $pass, $userobj->get('passhash'));
317: if ($hash != $userobj->getPass()) {
318:
319: foreach (self::$hashList as $hashv) {
320: $hash = self::passwordHash($user, $pass, $hashv);
321: if ($hash == $userobj->getPass()) {
322: break;
323: } else {
324: $hash = -1;
325: }
326: }
327: if ($hash === -1) {
328: $userobj = NULL;
329: }
330: }
331: } else {
332: $hash = -1;
333: }
334:
335: if (DEBUG_LOGIN) {
336: if ($userobj) {
337: $rights = sprintf('%X', $userobj->getRights());
338: } else {
339: $rights = false;
340: }
341: debugLog(sprintf('checkLogon(%1$s, %2$s)->%3$s', $user, $hash, $rights));
342: }
343: return $userobj;
344: }
345:
346: 347: 348: 349: 350: 351:
352: function getAdminEmail($rights = NULL) {
353: if (is_null($rights)) {
354: $rights = ADMIN_RIGHTS;
355: }
356: $emails = array();
357: $admins = $this->getAdministrators();
358: foreach ($admins as $user) {
359: if (($user['rights'] & $rights) && is_valid_email_zp($user['email'])) {
360: $name = $user['name'];
361: if (empty($name)) {
362: $name = $user['user'];
363: }
364: $emails[$name] = $user['email'];
365: }
366: }
367: return $emails;
368: }
369:
370: 371: 372: 373: 374:
375: function migrateAuth($to) {
376: if ($to > self::$supports_version || $to < self::$preferred_version - 1) {
377: trigger_error(sprintf(gettext('Cannot migrate rights to version %1$s (Zenphoto_Authority supports only %2$s and %3$s.)'), $to, self::$supports_version, self::$preferred_version), E_USER_NOTICE);
378: return false;
379: }
380: $success = true;
381: $oldversion = self::getVersion();
382: setOption('libauth_version', $to);
383: $this->admin_users = array();
384: $sql = "SELECT * FROM " . prefix('administrators') . "ORDER BY `rights` DESC, `id`";
385: $admins = query($sql, false);
386: if ($admins) {
387: $oldrights = array();
388: foreach (self::getRights($oldversion) as $key => $right) {
389: $oldrights[$key] = $right['value'];
390: }
391: $currentrights = self::getRights($to);
392: while ($user = db_fetch_assoc($admins)) {
393: $update = false;
394: $rights = $user['rights'];
395: $newrights = $currentrights['NO_RIGHTS']['value'];
396: foreach ($currentrights as $key => $right) {
397: if ($right['display']) {
398: if (array_key_exists($key, $oldrights) && $rights & $oldrights[$key]) {
399: $newrights = $newrights | $right['value'];
400: }
401: }
402: }
403: if ($oldversion < 4) {
404: $newrights = $newrights | $currentrights['USER_RIGHTS']['value'];
405: }
406: if ($to >= 3 && $oldversion < 3) {
407: if ($rights & $oldrights['VIEW_ALL_RIGHTS']) {
408: $updaterights = $currentrights['ALL_ALBUMS_RIGHTS']['value'] | $currentrights['ALL_PAGES_RIGHTS']['value'] |
409: $currentrights['ALL_NEWS_RIGHTS']['value'] | $currentrights['VIEW_SEARCH_RIGHTS']['value'] |
410: $currentrights['VIEW_GALLERY_RIGHTS']['value'] | $currentrights['VIEW_FULLIMAGE_RIGHTS']['value'];
411: $newrights = $newrights | $updaterights;
412: }
413: }
414: if ($oldversion >= 3 && $to < 3) {
415: if ($oldrights['ALL_ALBUMS_RIGHTS'] || $oldrights['ALL_PAGES_RIGHTS'] || $oldrights['ALL_NEWS_RIGHTS']) {
416: $newrights = $newrights | $currentrights['VIEW_ALL_RIGHTS']['value'];
417: }
418: }
419: if ($oldversion == 1) {
420: if ($rights & $oldrights['ZENPAGE_RIGHTS']) {
421: $newrights = $newrights | $currentrights['ZENPAGE_PAGES_RIGHTS'] | $currentrights['ZENPAGE_NEWS_RIGHTS'] | $currentrights['FILES_RIGHTS'];
422: }
423: }
424: if ($to >= 3) {
425: if ($newrights & $currentrights['ADMIN_RIGHTS']['value']) {
426: $newrights = $currentrights['ALL_RIGHTS']['value'];
427: } else {
428: if ($newrights & $currentrights['MANAGE_ALL_ALBUM_RIGHTS']['value']) {
429:
430: $newrights = $newrights | $currentrights['ALBUM_RIGHTS']['value'];
431: }
432: if ($newrights & $currentrights['MANAGE_ALL_NEWS_RIGHTS']['value']) {
433:
434: $newrights = $newrights | $currentrights['ZENPAGE_NEWS_RIGHTS']['value'];
435: }
436: if ($newrights & $currentrights['MANAGE_ALL_PAGES_RIGHTS']['value']) {
437:
438: $newrights = $newrights | $currentrights['ZENPAGE_PAGES_RIGHTS']['value'];
439: }
440: }
441: }
442:
443: $sql = 'UPDATE ' . prefix('administrators') . ' SET `rights`=' . $newrights . ' WHERE `id`=' . $user['id'];
444: $success = $success && query($sql);
445: }
446: db_free_result($admins);
447: }
448: return $success;
449: }
450:
451: 452: 453: 454: 455: 456: 457: 458:
459: static function updateAdminField($update, $value, $constraints) {
460: $where = '';
461: foreach ($constraints as $field => $clause) {
462: if (!empty($where))
463: $where .= ' AND ';
464: if (is_numeric($clause)) {
465: $where .= $field . $clause;
466: } else {
467: $where .= $field . db_quote($clause);
468: }
469: }
470: if (is_null($value)) {
471: $value = 'NULL';
472: } else {
473: $value = db_quote($value);
474: }
475: $sql = 'UPDATE ' . prefix('administrators') . ' SET `' . $update . '`=' . $value . ' WHERE ' . $where;
476: $result = query($sql);
477: return $result;
478: }
479:
480: 481: 482: 483: 484: 485:
486: static function newAdministrator($name, $valid = 1) {
487: $user = new Zenphoto_Administrator($name, $valid);
488: return $user;
489: }
490:
491: 492: 493: 494: 495:
496: static function getRights($version = NULL) {
497: if (empty($version)) {
498: $v = self::getVersion();
499: } else {
500: $v = $version;
501: }
502: switch ($v) {
503: case 1:
504: $rightsset = array('NO_RIGHTS' => array('value' => 2, 'name' => gettext('No rights'), 'set' => '', 'display' => false, 'hint' => ''),
505: 'OVERVIEW_RIGHTS' => array('value' => 4, 'name' => gettext('Overview'), 'set' => '', 'display' => true, 'hint' => ''),
506: 'VIEW_ALL_RIGHTS' => array('value' => 8, 'name' => gettext('View all'), 'set' => '', 'display' => true, 'hint' => ''),
507: 'UPLOAD_RIGHTS' => array('value' => 16, 'name' => gettext('Upload'), 'set' => '', 'display' => true, 'hint' => ''),
508: 'POST_COMMENT_RIGHTS' => array('value' => 32, 'name' => gettext('Post comments'), 'set' => '', 'display' => true, 'hint' => ''),
509: 'COMMENT_RIGHTS' => array('value' => 64, 'name' => gettext('Comments'), 'set' => '', 'display' => true, 'hint' => ''),
510: 'ALBUM_RIGHTS' => array('value' => 256, 'name' => gettext('Album'), 'set' => '', 'display' => true, 'hint' => ''),
511: 'MANAGE_ALL_ALBUM_RIGHTS' => array('value' => 512, 'name' => gettext('Manage all albums'), 'set' => '', 'display' => true, 'hint' => ''),
512: 'THEMES_RIGHTS' => array('value' => 1024, 'name' => gettext('Themes'), 'set' => '', 'display' => true, 'hint' => ''),
513: 'ZENPAGE_RIGHTS' => array('value' => 2049, 'name' => gettext('Zenpage'), 'set' => '', 'display' => true, 'hint' => ''),
514: 'TAGS_RIGHTS' => array('value' => 4096, 'name' => gettext('Tags'), 'set' => '', 'display' => true, 'hint' => ''),
515: 'OPTIONS_RIGHTS' => array('value' => 8192, 'name' => gettext('Options'), 'set' => '', 'display' => true, 'hint' => ''),
516: 'ADMIN_RIGHTS' => array('value' => 65536, 'name' => gettext('Admin'), 'set' => '', 'display' => true, 'hint' => ''));
517: break;
518: case 2:
519: $rightsset = array('NO_RIGHTS' => array('value' => 1, 'name' => gettext('No rights'), 'set' => '', 'display' => false, 'hint' => ''),
520: 'OVERVIEW_RIGHTS' => array('value' => pow(2, 2), 'name' => gettext('Overview'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view the admin overview page.')),
521: 'VIEW_ALL_RIGHTS' => array('value' => pow(2, 4), 'name' => gettext('View all'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view all of the gallery regardless of protection of the page. Without this right, the user can view only public ones and those checked in his managed object lists or as granted by View Search or View Gallery.')),
522: 'UPLOAD_RIGHTS' => array('value' => pow(2, 6), 'name' => gettext('Upload'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may upload to the albums for which they have management rights.')),
523: 'POST_COMMENT_RIGHTS' => array('value' => pow(2, 8), 'name' => gettext('Post comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('When the comment_form plugin is used for comments and its "Only members can comment" option is set, only users with this right may post comments.')),
524: 'COMMENT_RIGHTS' => array('value' => pow(2, 10), 'name' => gettext('Comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make comments tab changes.')),
525: 'ALBUM_RIGHTS' => array('value' => pow(2, 12), 'name' => gettext('Albums'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may access the “albums” tab to make changes.')),
526: 'ZENPAGE_PAGES_RIGHTS' => array('value' => pow(2, 14), 'name' => gettext('Pages'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users with this right may edit and manage Zenpage pages.')),
527: 'ZENPAGE_NEWS_RIGHTS' => array('value' => pow(2, 16), 'name' => gettext('News'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users with this right may edit and manage Zenpage articles and categories.')),
528: 'FILES_RIGHTS' => array('value' => pow(2, 18), 'name' => gettext('Files'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Allows the user access to the “filemanager” located on the upload: files sub-tab.')),
529: 'MANAGE_ALL_PAGES_RIGHTS' => array('value' => pow(2, 20), 'name' => gettext('Manage all pages'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage page.')),
530: 'MANAGE_ALL_NEWS_RIGHTS' => array('value' => pow(2, 22), 'name' => gettext('Manage all news'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage news article or category.')),
531: 'MANAGE_ALL_ALBUM_RIGHTS' => array('value' => pow(2, 24), 'name' => gettext('Manage all albums'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any album in the gallery.')),
532: 'THEMES_RIGHTS' => array('value' => pow(2, 26), 'name' => gettext('Themes'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make themes related changes. These are limited to the themes associated with albums checked in their managed albums list.')),
533: 'TAGS_RIGHTS' => array('value' => pow(2, 28), 'name' => gettext('Tags'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may make additions and changes to the set of tags.')),
534: 'OPTIONS_RIGHTS' => array('value' => pow(2, 29), 'name' => gettext('Options'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may make changes on the options tabs.')),
535: 'ADMIN_RIGHTS' => array('value' => pow(2, 30), 'name' => gettext('Admin'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('The master privilege. A user with "Admin" can do anything. (No matter what his other rights might indicate!)')));
536: break;
537: case 3:
538: $rightsset = array('NO_RIGHTS' => array('value' => 1, 'name' => gettext('No rights'), 'set' => '', 'display' => false, 'hint' => ''),
539: 'OVERVIEW_RIGHTS' => array('value' => pow(2, 2), 'name' => gettext('Overview'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may view the admin overview page.')),
540: 'VIEW_GALLERY_RIGHTS' => array('value' => pow(2, 4), 'name' => gettext('View gallery'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view otherwise protected generic gallery pages.')),
541: 'VIEW_SEARCH_RIGHTS' => array('value' => pow(2, 5), 'name' => gettext('View search'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view search pages even if password protected.')),
542: 'VIEW_FULLIMAGE_RIGHTS' => array('value' => pow(2, 6), 'name' => gettext('View fullimage'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may view all full sized (raw) images.')),
543: 'ALL_NEWS_RIGHTS' => array('value' => pow(2, 7), 'name' => gettext('Access all'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users with this right have access to all zenpage news articles.')),
544: 'ALL_PAGES_RIGHTS' => array('value' => pow(2, 8), 'name' => gettext('Access all'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users with this right have access to all zenpage pages.')),
545: 'ALL_ALBUMS_RIGHTS' => array('value' => pow(2, 9), 'name' => gettext('Access all'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right have access to all albums.')),
546: 'VIEW_UNPUBLISHED_RIGHTS' => array('value' => pow(2, 10), 'name' => gettext('View unpublished'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right will see all unpublished items.')),
547: 'POST_COMMENT_RIGHTS' => array('value' => pow(2, 11), 'name' => gettext('Post comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('When the comment_form plugin is used for comments and its "Only members can comment" option is set, only users with this right may post comments.')),
548: 'COMMENT_RIGHTS' => array('value' => pow(2, 12), 'name' => gettext('Comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make comments tab changes.')),
549: 'UPLOAD_RIGHTS' => array('value' => pow(2, 13), 'name' => gettext('Upload'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may upload to the albums for which they have management rights.')),
550: 'ZENPAGE_NEWS_RIGHTS' => array('value' => pow(2, 15), 'name' => gettext('News'), 'set' => gettext('News'), 'display' => false, 'hint' => gettext('Users with this right may edit and manage Zenpage articles and categories.')),
551: 'ZENPAGE_PAGES_RIGHTS' => array('value' => pow(2, 16), 'name' => gettext('Pages'), 'set' => gettext('Pages'), 'display' => false, 'hint' => gettext('Users with this right may edit and manage Zenpage pages.')),
552: 'FILES_RIGHTS' => array('value' => pow(2, 17), 'name' => gettext('Files'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Allows the user access to the “filemanager” located on the upload: files sub-tab.')),
553: 'ALBUM_RIGHTS' => array('value' => pow(2, 18), 'name' => gettext('Albums'), 'set' => gettext('Albums'), 'display' => false, 'hint' => gettext('Users with this right may access the “albums” tab to make changes.')),
554: 'MANAGE_ALL_NEWS_RIGHTS' => array('value' => pow(2, 21), 'name' => gettext('Manage all'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage news article or category.')),
555: 'MANAGE_ALL_PAGES_RIGHTS' => array('value' => pow(2, 22), 'name' => gettext('Manage all'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage page.')),
556: 'MANAGE_ALL_ALBUM_RIGHTS' => array('value' => pow(2, 23), 'name' => gettext('Manage all'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any album in the gallery.')),
557: 'THEMES_RIGHTS' => array('value' => pow(2, 26), 'name' => gettext('Themes'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make themes related changes. These are limited to the themes associated with albums checked in their managed albums list.')),
558: 'TAGS_RIGHTS' => array('value' => pow(2, 28), 'name' => gettext('Tags'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make additions and changes to the set of tags.')),
559: 'OPTIONS_RIGHTS' => array('value' => pow(2, 29), 'name' => gettext('Options'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may make changes on the options tabs.')),
560: 'ADMIN_RIGHTS' => array('value' => pow(2, 30), 'name' => gettext('Admin'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('The master privilege. A user with "Admin" can do anything. (No matter what his other rights might indicate!)')));
561: break;
562: case 4:
563: $rightsset = array('NO_RIGHTS' => array('value' => 1, 'name' => gettext('No rights'), 'set' => '', 'display' => false, 'hint' => ''),
564: 'OVERVIEW_RIGHTS' => array('value' => pow(2, 2), 'name' => gettext('Overview'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may view the admin overview page.')),
565: 'USER_RIGHTS' => array('value' => pow(2, 3), 'name' => gettext('User'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users must have this right to change their credentials.')),
566: 'VIEW_GALLERY_RIGHTS' => array('value' => pow(2, 5), 'name' => gettext('View gallery'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view otherwise protected generic gallery pages.')),
567: 'VIEW_SEARCH_RIGHTS' => array('value' => pow(2, 6), 'name' => gettext('View search'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may view search pages even if password protected.')),
568: 'VIEW_FULLIMAGE_RIGHTS' => array('value' => pow(2, 7), 'name' => gettext('View fullimage'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may view all full sized (raw) images.')),
569: 'ALL_NEWS_RIGHTS' => array('value' => pow(2, 8), 'name' => gettext('Access all'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users with this right have access to all zenpage news articles.')),
570: 'ALL_PAGES_RIGHTS' => array('value' => pow(2, 9), 'name' => gettext('Access all'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users with this right have access to all zenpage pages.')),
571: 'ALL_ALBUMS_RIGHTS' => array('value' => pow(2, 10), 'name' => gettext('Access all'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right have access to all albums.')),
572: 'VIEW_UNPUBLISHED_RIGHTS' => array('value' => pow(2, 11), 'name' => gettext('View unpublished'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right will see all unpublished items.')),
573: 'POST_COMMENT_RIGHTS' => array('value' => pow(2, 13), 'name' => gettext('Post comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('When the comment_form plugin is used for comments and its "Only members can comment" option is set, only users with this right may post comments.')),
574: 'COMMENT_RIGHTS' => array('value' => pow(2, 14), 'name' => gettext('Comments'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make comments tab changes.')),
575: 'UPLOAD_RIGHTS' => array('value' => pow(2, 15), 'name' => gettext('Upload'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users with this right may upload to the albums for which they have management rights.')),
576: 'ZENPAGE_NEWS_RIGHTS' => array('value' => pow(2, 17), 'name' => gettext('News'), 'set' => gettext('News'), 'display' => false, 'hint' => gettext('Users with this right may edit and manage Zenpage articles and categories.')),
577: 'ZENPAGE_PAGES_RIGHTS' => array('value' => pow(2, 18), 'name' => gettext('Pages'), 'set' => gettext('Pages'), 'display' => false, 'hint' => gettext('Users with this right may edit and manage Zenpage pages.')),
578: 'FILES_RIGHTS' => array('value' => pow(2, 19), 'name' => gettext('Files'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Allows the user access to the “filemanager” located on the upload: files sub-tab.')),
579: 'ALBUM_RIGHTS' => array('value' => pow(2, 20), 'name' => gettext('Albums'), 'set' => gettext('Albums'), 'display' => false, 'hint' => gettext('Users with this right may access the “albums” tab to make changes.')),
580: 'MANAGE_ALL_NEWS_RIGHTS' => array('value' => pow(2, 21), 'name' => gettext('Manage all'), 'set' => gettext('News'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage news article or category.')),
581: 'MANAGE_ALL_PAGES_RIGHTS' => array('value' => pow(2, 22), 'name' => gettext('Manage all'), 'set' => gettext('Pages'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any Zenpage page.')),
582: 'MANAGE_ALL_ALBUM_RIGHTS' => array('value' => pow(2, 23), 'name' => gettext('Manage all'), 'set' => gettext('Albums'), 'display' => true, 'hint' => gettext('Users who do not have “Admin” rights normally are restricted to manage only objects to which they have been assigned. This right allows them to manage any album in the gallery.')),
583: 'CODEBLOCK_RIGHTS' => array('value' => pow(2, 25), 'name' => gettext('Codeblock'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may edit Codeblocks.')),
584: 'THEMES_RIGHTS' => array('value' => pow(2, 26), 'name' => gettext('Themes'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make themes related changes. These are limited to the themes associated with albums checked in their managed albums list.')),
585: 'TAGS_RIGHTS' => array('value' => pow(2, 28), 'name' => gettext('Tags'), 'set' => gettext('Gallery'), 'display' => true, 'hint' => gettext('Users with this right may make additions and changes to the set of tags.')),
586: 'OPTIONS_RIGHTS' => array('value' => pow(2, 29), 'name' => gettext('Options'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('Users with this right may make changes on the options tabs.')),
587: 'ADMIN_RIGHTS' => array('value' => pow(2, 30), 'name' => gettext('Admin'), 'set' => gettext('General'), 'display' => true, 'hint' => gettext('The master privilege. A user with "Admin" can do anything. (No matter what his other rights might indicate!)')));
588: break;
589: }
590: $allrights = 0;
591: foreach ($rightsset as $key => $right) {
592: $allrights = $allrights | $right['value'];
593: }
594: $rightsset['ALL_RIGHTS'] = array('value' => $allrights, 'name' => gettext('All rights'), 'display' => false);
595: $rightsset['DEFAULT_RIGHTS'] = array('value' => $rightsset['OVERVIEW_RIGHTS']['value'] + $rightsset['POST_COMMENT_RIGHTS']['value'], 'name' => gettext('Default rights'), 'display' => false);
596: if (isset($rightsset['VIEW_ALL_RIGHTS']['value'])) {
597: $rightsset['DEFAULT_RIGHTS']['value'] = $rightsset['DEFAULT_RIGHTS']['value'] | $rightsset['VIEW_ALL_RIGHTS']['value'];
598: } else {
599: $rightsset['DEFAULT_RIGHTS']['value'] = $rightsset['DEFAULT_RIGHTS'] | $rightsset['ALL_ALBUMS_RIGHTS']['value'] |
600: $rightsset['ALL_PAGES_RIGHTS']['value'] | $rightsset['ALL_NEWS_RIGHTS']['value'] |
601: $rightsset['VIEW_SEARCH_RIGHTS']['value'] | $rightsset['VIEW_GALLERY_RIGHTS']['value'];
602: }
603: $rightsset = sortMultiArray($rightsset, 'value', true, false, false);
604: return $rightsset;
605: }
606:
607: static function getResetTicket($user, $pass) {
608: $req = time();
609: $ref = sha1($req . $user . $pass);
610: $time = bin2hex(rc4('ticket' . HASH_SEED, $req));
611: return $time . $ref;
612: }
613:
614: function validateTicket($ticket, $user) {
615: global $_zp_current_admin_obj;
616: $admins = $this->getAdministrators();
617: foreach ($admins as $tuser) {
618: if ($tuser['user'] == $user) {
619: if ($tuser['rights'] & USER_RIGHTS) {
620: $request_date = rc4('ticket' . HASH_SEED, pack("H*", $time = substr($ticket, 0, 20)));
621: $ticket = substr($ticket, 20);
622: $ref = sha1($request_date . $user . $tuser['pass']);
623: if ($ref === $ticket) {
624: if (time() <= ($request_date + (3 * 24 * 60 * 60))) {
625:
626: $_zp_current_admin_obj = new Zenphoto_Administrator($user, 1);
627: $_zp_current_admin_obj->reset = true;
628: }
629: }
630: break;
631: }
632: }
633: }
634: }
635:
636: 637: 638: 639:
640: static function logUser($user) {
641: $user->set('lastloggedin', $user->get('loggedin'));
642: $user->set('loggedin', date('Y-m-d H:i:s'));
643: $user->save();
644: zp_setCookie("zp_user_auth", $user->getPass() . '.' . $user->getID(), NULL, NULL, secureServer());
645: }
646:
647: 648: 649:
650: function handleLogon() {
651: global $_zp_current_admin_obj, $_zp_login_error, $_zp_captcha, $_zp_loggedin;
652: if (isset($_POST['login'])) {
653: $post_user = sanitize(@$_POST['user']);
654: $post_pass = sanitize(@$_POST['pass'], 0);
655: $_zp_loggedin = false;
656:
657: switch (@$_POST['password']) {
658: default:
659: $user = self::checkLogon($post_user, $post_pass);
660: if ($user) {
661: $_zp_loggedin = $user->getRights();
662: }
663: $_zp_loggedin = zp_apply_filter('admin_login_attempt', $_zp_loggedin, $post_user, $post_pass);
664: if ($_zp_loggedin) {
665: self::logUser($user);
666: $_zp_current_admin_obj = $user;
667: } else {
668: zp_clearCookie("zp_user_auth");
669: $_zp_login_error = 1;
670: }
671: break;
672: case 'challenge':
673: $user = self::getAnAdmin(array('`user`=' => $post_user, '`valid`=' => 1));
674: if (is_object($user)) {
675: $info = $user->getChallengePhraseInfo();
676: if ($post_pass && $info['response'] == $post_pass) {
677: $ref = self::getResetTicket($post_user, $user->getPass());
678: header('location:' . WEBPATH . '/' . ZENFOLDER . '/admin-users.php?ticket=' . $ref . '&user=' . $post_user);
679: exitZP();
680: }
681: }
682: if ( !empty($info['challenge']) && !empty($_POST['pass'])) { $_zp_login_error = gettext('Sorry, that is not the answer.'); }
683: $_REQUEST['logon_step'] = 'challenge';
684: break;
685: case 'captcha':
686: if ($_zp_captcha->checkCaptcha(trim(@$_POST['code']), sanitize(@$_POST['code_h'], 3))) {
687: require_once(dirname(__FILE__) . '/load_objectClasses.php');
688: if (empty($post_user)) {
689: $requestor = gettext('You are receiving this e-mail because of a password reset request on your Zenphoto gallery.');
690: } else {
691: $requestor = sprintf(gettext("You are receiving this e-mail because of a password reset request on your Zenphoto gallery from a user who tried to log in as %s."), $post_user);
692: }
693: $admins = $this->getAdministrators();
694: $mails = array();
695: $user = NULL;
696: foreach ($admins as $key => $tuser) {
697: if (!empty($tuser['email'])) {
698: if (!empty($post_user) && ($tuser['user'] == $post_user || $tuser['email'] == $post_user)) {
699: $name = $tuser['name'];
700: if (empty($name)) {
701: $name = $tuser['user'];
702: }
703: $mails[$name] = $tuser['email'];
704: $user = $tuser;
705: unset($admins[$key]);
706: } else {
707: if (!($tuser['rights'] & ADMIN_RIGHTS)) {
708: unset($admins[$key]);
709: }
710: }
711: } else {
712: unset($admins[$key]);
713: }
714: }
715:
716: $cclist = array();
717: foreach ($admins as $tuser) {
718: $name = $tuser['name'];
719: if (empty($name)) {
720: $name = $tuser['user'];
721: }
722: if (is_null($user)) {
723: $user = $tuser;
724: $mails[$name] = $tuser['email'];
725: } else {
726: $cclist[$name] = $tuser['email'];
727: }
728: }
729: if (is_null($user)) {
730: $_zp_login_error = gettext('There was no one to which to send the reset request.');
731: } else {
732: $ref = self::getResetTicket($user['user'], $user['pass']);
733: $msg = "\n" . $requestor .
734: "\n" . sprintf(gettext("To reset your Zenphoto Admin passwords visit: %s"), FULLWEBPATH . "/" . ZENFOLDER . "/admin-users.php?ticket=$ref&user=" . $user['user']) .
735: "\n" . gettext("If you do not wish to reset your passwords just ignore this message. This ticket will automatically expire in 3 days.");
736: $err_msg = zp_mail(gettext("The Zenphoto information you requested"), $msg, $mails, $cclist);
737: if (empty($err_msg)) {
738: $_zp_login_error = 2;
739: } else {
740: $_zp_login_error = $err_msg;
741: }
742: }
743: } else {
744: $_zp_login_error = gettext('Your input did not match the captcha');
745: $_REQUEST['logon_step'] = 'captcha';
746: }
747: break;
748: }
749: }
750: return $_zp_loggedin;
751: }
752:
753: 754: 755: 756: 757: 758: 759: 760: 761:
762: static function getAuthCookies() {
763: $candidates = array();
764: if (isset($_COOKIE)) {
765: $candidates = $_COOKIE;
766: }
767: if (isset($_SESSION)) {
768: $candidates = array_merge($candidates, $_SESSION);
769: }
770: foreach ($candidates as $key => $candidate) {
771: if (strpos($key, '_auth') === false) {
772: unset($candidates[$key]);
773: }
774: }
775: return $candidates;
776: }
777:
778: 779: 780: 781:
782: static function handleLogout() {
783: global $_zp_loggedin, $_zp_pre_authorization, $_zp_current_admin_obj;
784: foreach (self::getAuthCookies() as $cookie => $value) {
785: zp_clearCookie($cookie);
786: }
787: $_zp_loggedin = false;
788: $_zp_pre_authorization = array();
789: return zp_apply_filter('zp_logout', NULL, $_zp_current_admin_obj);
790: }
791:
792: 793: 794:
795: function checkCookieCredentials() {
796: list($auth, $id) = explode('.', zp_getCookie('zp_user_auth') . '.');
797: $loggedin = $this->checkAuthorization($auth, $id);
798: $loggedin = zp_apply_filter('authorization_cookie', $loggedin, $auth, $id);
799: if ($loggedin) {
800: return $loggedin;
801: } else {
802: zp_clearCookie("zp_user_auth");
803: return NULL;
804: }
805: }
806:
807: 808: 809: 810: 811: 812: 813: 814: 815: 816:
817: function printLoginForm($redirect = null, $logo = true, $showUserField = true, $showCaptcha = true, $hint = '') {
818: global $_zp_login_error, $_zp_captcha, $_zp_gallery;
819: if (is_null($redirect)) {
820: $redirect = getRequestURI();
821: }
822:
823: if (isset($_POST['user'])) {
824: $requestor = sanitize($_POST['user'], 3);
825: } else {
826: $requestor = '';
827: }
828: if (empty($requestor)) {
829: if (isset($_GET['ref'])) {
830: $requestor = sanitize($_GET['ref']);
831: }
832: }
833: $alt_handlers = zp_apply_filter('alt_login_handler', array());
834: $star = false;
835: $mails = array();
836: $info = array('challenge' => '', 'response' => '');
837: if (!empty($requestor)) {
838: $admin = self::getAnAdmin(array('`user`=' => $requestor, '`valid`=' => 1));
839: if (is_object($admin)) {
840: if ($admin->getEmail()) {
841: $star = $showCaptcha;
842: }
843: $info = $admin->getChallengePhraseInfo();
844: }
845: }
846: if (!$star) {
847: $admins = $this->getAdministrators();
848: while (count($admins) > 0) {
849: $user = array_shift($admins);
850: if ($user['email']) {
851: $star = $showCaptcha;
852: }
853: }
854: }
855: $whichForm = sanitize(@$_REQUEST['logon_step']);
856: ?>
857: <div id="loginform">
858: <?php
859: if ($logo) {
860: ?>
861: <p>
862: <img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/zen-logo.png" title="ZenPhoto" alt="ZenPhoto" />
863: </p>
864: <?php
865: }
866: switch ($_zp_login_error) {
867: case 1:
868: ?>
869: <div class="errorbox" id="message"><h2><?php echo gettext("There was an error logging in."); ?></h2>
870: <?php
871: if ($showUserField) {
872: echo gettext("Check your username and password and try again.");
873: } else {
874: echo gettext("Check password and try again.");
875: }
876: ?>
877: </div>
878: <?php
879: break;
880: case 2:
881: ?>
882: <div class="messagebox fade-message">
883: <h2><?php echo gettext("A reset request has been sent."); ?></h2>
884: </div>
885: <?php
886: break;
887: default:
888: if (!empty($_zp_login_error)) {
889: ?>
890: <div class="errorbox fade-message">
891: <h2><?php echo $_zp_login_error; ?></h2>
892: </div>
893: <?php
894: }
895: break;
896: }
897: switch ($whichForm) {
898: case 'challenge':
899: ?>
900: <form name="login" action="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php" method="post">
901: <fieldset id="logon_box">
902: <input type="hidden" name="login" value="1" />
903: <input type="hidden" name="password" value="challenge" />
904: <input type="hidden" name="redirect" value="<?php echo html_encode(pathurlencode($redirect)); ?>" />
905: <fieldset>
906: <legend><?php echo gettext('User') ?></legend>
907: <input class="textfield" name="user" id="user" type="text" size="35" value="<?php echo html_encode($requestor); ?>" />
908: </fieldset>
909: <?php
910: if ($requestor && $admin) {
911: if (!empty($info['challenge'])) {
912: ?>
913: <p class="logon_form_text"><?php echo gettext('Supply the correct response to the question below and you will be directed to a page where you can change your password.'); ?>
914: <?php if ( $admin->getEmail() ) { echo gettext('<br />You may also use the link below to request a reset by e-mail.'); } ?>
915: </p>
916: <fieldset><legend><?php echo gettext('Challenge question:') ?></legend>
917: <?php
918: echo html_encode($info['challenge']);
919: ?>
920: </fieldset>
921: <fieldset><legend><?php echo gettext('Your response') ?></legend>
922: <input class="textfield" name="pass" id="pass" type="text" size="35" />
923: </fieldset>
924: <br />
925: <?php } else {
926: if ( !$admin->getEmail() ) { ?>
927: <fieldset><p class="logon_form_text errorbox"><?php echo gettext('A password reset is not possible.'); ?></p></fieldset>
928: <?php } else { ?>
929: <p class="logon_form_text"><?php echo gettext('Please request a reset by e-mail by clicking the link below.'); ?></p>
930: <?php
931: }
932: }
933: } else {
934: ?>
935: <p class="logon_form_text">
936: <?php
937: echo gettext('Enter your User ID and press <code>Refresh</code> to get your challenge question and/or get a link to request a reset by e-mail.');
938: ?>
939: </p>
940: <?php
941: }
942: ?>
943: <div class="buttons">
944: <button type="submit" value="<?php echo gettext("Submit"); ?>"<?php if (!$info['challenge']) echo ' disabled="disabled"'; ?> ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/pass.png" alt="" /><?php echo gettext("Submit"); ?></button>
945: <button type="button" value="<?php echo gettext("Refresh"); ?>" id="challenge_refresh" onclick="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php', ['logon_step=challenge', 'ref=' + $('#user').val()]);" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/refresh.png" alt="" /><?php echo gettext("Refresh"); ?></button>
946: <button type="button" value="<?php echo gettext("Return"); ?>" onclick="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php', ['logon_step=', 'ref=' + $('#user').val()]);" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/refresh.png" alt="" /><?php echo gettext("Return"); ?></button>
947: </div>
948: <br class="clearall" />
949: </fieldset>
950: <br />
951: <?php
952: if ( $star && (!empty($requestor) && $admin->getEmail()) ) {
953: ?>
954: <p class="logon_link">
955: <a href="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php',['logon_step=captcha', 'ref='+$('#user').val()]);" >
956: <?php echo gettext('Request reset by e-mail'); ?>
957: </a>
958: </p>
959: <?php
960: }
961: ?>
962: </form>
963: <?php
964: break;
965: default:
966: Zenphoto_Authority::printPasswordFormJS();
967: if (empty($alt_handlers)) {
968: $legend = gettext('Login');
969: } else {
970: ?>
971: <script type="text/javascript">
972:
973: var handlers = [];
974: <?php
975: $list = '<select id="logon_choices" onchange="changeHandler(handlers[$(this).val()]);">' .
976: '<option value="0">' . html_encode(get_language_string($_zp_gallery->getTitle())) . '</option>';
977: $c = 0;
978: foreach ($alt_handlers as $handler => $details) {
979: $c++;
980: $details['params'][] = 'redirect=' . $redirect;
981: if (!empty($requestor)) {
982: $details['params'][] = 'requestor=' . $requestor;
983: }
984: echo "handlers[" . $c . "]=['" . $details['script'] . "','" . implode("','", $details['params']) . "'];";
985:
986: $list .= '<option value="' . $c . '">' . $handler . '</option>';
987: }
988: $list .= '</select>';
989: $legend = sprintf(gettext('Logon using:%s'), $list);
990: ?>
991: function changeHandler(handler) {
992: handler.push('user=' + $('#user').val());
993: var script = handler.shift();
994: launchScript(script, handler);
995: }
996:
997: </script>
998: <?php
999: }
1000: $redirect = zp_apply_filter('login_redirect_link', $redirect);
1001: ?>
1002: <form name="login" action="<?php echo html_encode(pathurlencode($redirect)); ?>" method="post">
1003: <input type="hidden" name="login" value="1" />
1004: <input type="hidden" name="password" value="1" />
1005: <input type="hidden" name="redirect" value="<?php echo html_encode(pathurlencode($redirect)); ?>" />
1006: <fieldset id="logon_box"><legend><?php echo $legend; ?></legend>
1007: <?php
1008: if ($showUserField) {
1009: ?>
1010: <fieldset><legend><?php echo gettext("User"); ?></legend>
1011: <input class="textfield" name="user" id="user" type="text" size="35" value="<?php echo html_encode($requestor); ?>" />
1012: </fieldset>
1013: <?php
1014: }
1015: ?>
1016: <fieldset><legend><?php echo gettext("Password"); ?></legend>
1017: <input class="textfield" name="pass" id="pass" type="password" size="35" /><br />
1018: <label><input type="checkbox" name="disclose_password" id="disclose_password" onclick="togglePassword('');" /><?php echo gettext('Show password') ?></label>
1019: </fieldset>
1020: <br />
1021: <div class="buttons">
1022: <button type="submit" value="<?php echo gettext("Log in"); ?>" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/pass.png" alt="" /><?php echo gettext("Log in"); ?></button>
1023: <button type="reset" value="<?php echo gettext("Reset"); ?>" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/reset.png" alt="" /><?php echo gettext("Reset"); ?></button>
1024: </div>
1025: <br class="clearall" />
1026: </fieldset>
1027: </form>
1028: <?php
1029: if ($hint) {
1030: echo '<p>' . $hint . '</p>';
1031: }
1032: if ($showUserField && OFFSET_PATH != 2) {
1033: ?>
1034: <p class="logon_link">
1035: <a href="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php',['logon_step=challenge', 'ref='+$('#user').val()]);" >
1036: <?php echo gettext('I forgot my <strong>User ID</strong>/<strong>Password</strong>'); ?>
1037: </a>
1038: </p>
1039: <?php
1040: }
1041: break;
1042: case 'captcha':
1043: $captcha = $_zp_captcha->getCaptcha(NULL);
1044: ?>
1045: <form name="login" action="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php" method="post">
1046: <?php if (isset($captcha['hidden'])) echo $captcha['hidden']; ?>
1047: <input type="hidden" name="login" value="1" />
1048: <input type="hidden" name="password" value="captcha" />
1049: <input type="hidden" name="redirect" value="<?php echo html_encode(pathurlencode($redirect)); ?>" />
1050: <fieldset id="logon_box">
1051: <fieldset><legend><?php echo gettext('User'); ?></legend>
1052: <input class="textfield" name="user" id="user" type="text" value="<?php echo html_encode($requestor); ?>" />
1053: </fieldset>
1054: <?php if (isset($captcha['html'])) echo $captcha['html']; ?>
1055: <?php
1056: if (isset($captcha['input'])) {
1057: ?>
1058: <fieldset><legend><?php echo gettext("Enter CAPTCHA"); ?></legend>
1059: <?php echo $captcha['input']; ?>
1060: </fieldset>
1061: <?php
1062: }
1063: ?>
1064: <br />
1065: <div class="buttons">
1066: <button type="submit" value="<?php echo gettext("Request"); ?>" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/pass.png" alt="" /><?php echo gettext("Request password reset"); ?></button>
1067: <button type="button" value="<?php echo gettext("Return"); ?>" onclick="javascript:launchScript('<?php echo WEBPATH . '/' . ZENFOLDER; ?>/admin.php', ['logon_step=', 'ref=' + $('#user').val()]);" ><img src="<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/refresh.png" alt="" /><?php echo gettext("Return"); ?></button>
1068: </div>
1069: <br class="clearall" />
1070: </fieldset>
1071: </form>
1072: <?php
1073: break;
1074: }
1075: ?>
1076: </div>
1077: <?php
1078: }
1079:
1080: 1081: 1082: 1083:
1084: static function printPasswordFormJS() {
1085: ?>
1086: <script type="text/javascript">
1087:
1088: function passwordStrength(id) {
1089: var inputa = '#pass' + id;
1090: var inputb = '#pass_r' + id;
1091: var displaym = '#match' + id;
1092: var displays = '#strength' + id;
1093: var numeric = 0;
1094: var special = 0;
1095: var upper = 0;
1096: var lower = 0;
1097: var str = $(inputa).val();
1098: var len = str.length;
1099: var strength = 0;
1100: for (c = 0; c < len; c++) {
1101: if (str[c].match(/[0-9]/)) {
1102: numeric++;
1103: } else if (str[c].match(/[^A-Za-z0-9]/)) {
1104: special++;
1105: } else if (str[c].toUpperCase() == str[c]) {
1106: upper++;
1107: } else {
1108: lower++;
1109: }
1110: }
1111: if (upper != len) {
1112: upper = upper * 2;
1113: }
1114: if (lower == len) {
1115: lower = lower * 0.75;
1116: }
1117: if (numeric != len) {
1118: numeric = numeric * 4;
1119: }
1120: if (special != len) {
1121: special = special * 5;
1122: }
1123: len = Math.max(0, (len - 6) * .35);
1124: strength = Math.min(30, Math.round(upper + lower + numeric + special + len));
1125: if (str.length == 0) {
1126: $(displays).css('color', 'black');
1127: $(displays).html('<?php echo gettext('Password'); ?>');
1128: $(inputa).css('background-image', 'none');
1129: } else {
1130: if (strength < 15) {
1131: $(displays).css('color', '#ff0000');
1132: $(displays).html('<?php echo gettext('password strength weak'); ?>');
1133: } else if (strength < 25) {
1134: $(displays).css('color', '#ff0000');
1135: $(displays).html('<?php echo gettext('password strength good'); ?>');
1136: } else {
1137: $(displays).css('color', '#008000');
1138: $(displays).html('<?php echo gettext('password strength strong'); ?>');
1139: }
1140: if (strength < <?php echo (int) getOption('password_strength'); ?>) {
1141: $(inputb).prop('disabled',true);
1142: $(displays).css('color', '#ff0000');
1143: $(displays).html('<?php echo gettext('password strength too weak'); ?>');
1144: } else {
1145: $(inputb).parent().removeClass('ui-state-disabled');
1146: $(inputb).prop('disabled',false);
1147: passwordMatch(id);
1148: }
1149: var url = 'url(<?php echo WEBPATH . '/' . ZENFOLDER; ?>/images/strengths/strength' + strength + '.png)';
1150: $(inputa).css('background-image', url);
1151: $(inputa).css('background-size', '100%');
1152: }
1153: }
1154:
1155: function passwordMatch(id) {
1156: var inputa = '#pass' + id;
1157: var inputb = '#pass_r' + id;
1158: var display = '#match' + id;
1159: if ($('#disclose_password' + id).prop('checked')) {
1160: if ($(inputa).val() === $(inputb).val()) {
1161: if ($(inputa).val().trim() !== '') {
1162: $(display).css('color', '#008000');
1163: $(display).html('<?php echo gettext('passwords match'); ?>');
1164: }
1165: } else {
1166: $(display).css('color', '#ff0000');
1167: $(display).html('<?php echo gettext('passwords do not match'); ?>');
1168: }
1169: }
1170: }
1171:
1172: function passwordClear(id) {
1173: var inputa = '#pass' + id;
1174: var inputb = '#pass_r' + id;
1175: if ($(inputa).val().trim() === '') {
1176: $(inputa).val('');
1177: }
1178: if ($(inputb).val().trim() === '') {
1179: $(inputb).val('');
1180: }
1181: }
1182: function togglePassword(id) {
1183: if ($('#pass' + id).attr('type') == 'password') {
1184: var oldp = $('#pass' + id);
1185: var newp = oldp.clone();
1186: newp.attr('type', 'text');
1187: newp.insertAfter(oldp);
1188: oldp.remove();
1189: $('.password_field_' + id).hide();
1190: } else {
1191: var oldp = $('#pass' + id);
1192: var newp = oldp.clone();
1193: newp.attr('type', 'password');
1194: newp.insertAfter(oldp);
1195: oldp.remove();
1196: $('.password_field_' + id).show();
1197: }
1198: }
1199:
1200: </script>
1201: <?php
1202: }
1203:
1204: static function printPasswordForm($id = '', $pad = false, $disable = NULL, $required = false, $flag = '') {
1205: if ($pad) {
1206: $x = ' ';
1207: } else {
1208: $x = '';
1209: }
1210: ?>
1211: <input type="hidden" name="passrequired<?php echo $id; ?>" id="passrequired-<?php echo $id; ?>" value="<?php echo (int) $required; ?>" />
1212: <p>
1213: <label for="pass<?php echo $id; ?>" id="strength<?php echo $id; ?>"><?php echo gettext("Password") . $flag; ?></label>
1214: <input type="password" size="<?php echo TEXT_INPUT_SIZE; ?>"
1215: name="pass<?php echo $id ?>" value="<?php echo $x; ?>"
1216: id="pass<?php echo $id; ?>"
1217: onchange="$('#passrequired-<?php echo $id; ?>').val(1);"
1218: onclick="passwordClear('<?php echo $id; ?>');"
1219: onkeyup="passwordStrength('<?php echo $id; ?>');"
1220: <?php echo $disable; ?> />
1221: </p>
1222: <p>
1223: <label for="disclose_password<?php echo $id; ?>"><?php echo gettext('Show password'); ?></label>
1224: <input type="checkbox" name="disclose_password<?php echo $id; ?>" id="disclose_password<?php echo $id; ?>" onclick="passwordClear('<?php echo $id; ?>');
1225: togglePassword('<?php echo $id; ?>');">
1226: </p>
1227: <p class="password_field_<?php echo $id; ?>">
1228: <label for="pass_r<?php echo $id; ?>" id="match<?php echo $id; ?>"><?php echo gettext("Repeat password") . $flag; ?></label>
1229: <input type="password" size="<?php echo TEXT_INPUT_SIZE; ?>"
1230: name="pass_r<?php echo $id ?>" value="<?php echo $x; ?>"
1231: id="pass_r<?php echo $id; ?>" disabled="disabled"
1232: onchange="$('#passrequired-<?php echo $id; ?>').val(1);"
1233: onkeydown="passwordClear('<?php echo $id; ?>');"
1234: onkeyup="passwordMatch('<?php echo $id; ?>');" />
1235: </p>
1236: <?php
1237: }
1238:
1239: 1240: 1241: 1242: 1243: 1244: 1245: 1246: 1247: 1248:
1249: static function pbkdf2($p, $s, $c = 1000, $kl = 32, $a = 'sha256') {
1250: $hl = strlen(hash($a, null, true));
1251: $kb = ceil($kl / $hl);
1252: $dk = '';
1253:
1254: for ($block = 1; $block <= $kb; $block++) {
1255:
1256: $ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true);
1257:
1258: for ($i = 1; $i < $c; $i++)
1259:
1260: $ib ^= ($b = hash_hmac($a, $b, $p, true));
1261: $dk .= $ib;
1262: }
1263:
1264: return substr($dk, 0, $kl);
1265: }
1266:
1267: 1268: 1269: 1270: 1271: 1272: 1273:
1274: function checkUniqueMailaddress($email_to_check, $current_user) {
1275: $all_users = $this->getAdministrators('users');
1276: foreach ($all_users as $user) {
1277: if ($user['user'] != $current_user && $user['email'] == $email_to_check) {
1278: return true;
1279: }
1280: }
1281: return false;
1282: }
1283:
1284: }
1285:
1286: class Zenphoto_Administrator extends PersistentObject {
1287:
1288: 1289: 1290: 1291: 1292: 1293: 1294:
1295: var $objects = NULL;
1296: var $master = false;
1297: var $msg = NULL;
1298: var $logout_link = true;
1299: var $reset = false;
1300: var $passhash;
1301:
1302: 1303: 1304: 1305: 1306: 1307: 1308:
1309:
1310: function __construct($user, $valid) {
1311: global $_zp_authority;
1312: $this->passhash = (int) getOption('strong_hash');
1313: $this->instantiate('administrators', array('user' => $user, 'valid' => $valid), NULL, false, empty($user));
1314: if (empty($user)) {
1315: $this->set('id', -1);
1316: }
1317: if ($valid) {
1318: $rights = $this->getRights();
1319: $new_rights = 0;
1320: if ($_zp_authority->isMasterUser($user)) {
1321: $new_rights = ALL_RIGHTS;
1322: $this->master = true;
1323: } else {
1324:
1325: if ($rights & MANAGE_ALL_ALBUM_RIGHTS) {
1326: $new_rights = $new_rights | ALBUM_RIGHTS;
1327: }
1328: if ($rights & MANAGE_ALL_NEWS_RIGHTS) {
1329: $new_rights = $new_rights | ZENPAGE_PAGES_RIGHTS;
1330: }
1331: if ($rights & MANAGE_ALL_PAGES_RIGHTS) {
1332: $new_rights = $new_rights | ZENPAGE_NEWS_RIGHTS;
1333: }
1334: $this->getObjects();
1335: foreach ($this->objects as $object) {
1336: switch ($object['type']) {
1337: case 'album':
1338: if ($object['edit'] && MANAGED_OBJECT_RIGHTS_EDIT) {
1339: $new_rights = $new_rights | ALBUM_RIGHTS;
1340: }
1341: break;
1342: case 'pages':
1343: $new_rights = $new_rights | ZENPAGE_PAGES_RIGHTS;
1344: break;
1345: case 'news':
1346: $new_rights = $new_rights | ZENPAGE_NEWS_RIGHTS;
1347: break;
1348: }
1349: }
1350: }
1351: if($this->getGroup()) {
1352: $this->preservePrimeAlbum();
1353: }
1354: if ($new_rights) {
1355: $this->setRights($rights | $new_rights);
1356: }
1357: }
1358: }
1359:
1360: 1361: 1362: 1363: 1364:
1365: function getDateTime() {
1366: return $this->get('date');
1367: }
1368:
1369: 1370: 1371: 1372: 1373:
1374: function setDateTime($datetime) {
1375: $this->set('date', $datetime);
1376: }
1377:
1378: function getID() {
1379: return $this->get('id');
1380: }
1381:
1382: 1383: 1384: 1385:
1386: function setPass($pwd) {
1387: $hash_type = getOption('strong_hash');
1388: $pwd = Zenphoto_Authority::passwordHash($this->getUser(), $pwd, $hash_type);
1389: $this->set('pass', $pwd);
1390: $this->set('passupdate', date('Y-m-d H:i:s'));
1391: $this->set('passhash', $hash_type);
1392: return $this->get('pass');
1393: }
1394:
1395: 1396: 1397:
1398: function getPass() {
1399: return $this->get('pass');
1400: }
1401:
1402: 1403: 1404:
1405: function setName($admin_n) {
1406: $this->set('name', $admin_n);
1407: }
1408:
1409: 1410: 1411:
1412: function getName() {
1413: return $this->get('name');
1414: }
1415:
1416: 1417: 1418:
1419: function setEmail($admin_e) {
1420: $this->set('email', $admin_e);
1421: }
1422:
1423: 1424: 1425:
1426: function getEmail() {
1427: return $this->get('email');
1428: }
1429:
1430: 1431: 1432:
1433: function setRights($rights) {
1434: $this->set('rights', $rights);
1435: }
1436:
1437: 1438: 1439:
1440: function getRights() {
1441: return $this->get('rights');
1442: }
1443:
1444: 1445: 1446:
1447: function setObjects($objects) {
1448: $this->objects = $objects;
1449: }
1450:
1451: 1452: 1453: 1454: 1455:
1456: function getObjects($what = NULL) {
1457: if (is_null($this->objects)) {
1458: if ($this->transient) {
1459: $this->objects = array();
1460: } else {
1461: $this->objects = populateManagedObjectsList(NULL, $this->getID());
1462: }
1463: }
1464: if (empty($what)) {
1465: return $this->objects;
1466: }
1467: $result = array();
1468: foreach ($this->objects as $object) {
1469: if ($object['type'] == $what) {
1470: $result[get_language_string($object['name'])] = $object['data'];
1471: }
1472: }
1473: return $result;
1474: }
1475:
1476: 1477: 1478:
1479: function setCustomData($custom_data) {
1480: $this->set('custom_data', $custom_data);
1481: }
1482:
1483: 1484: 1485:
1486: function getCustomData() {
1487: return $this->get('custom_data');
1488: }
1489:
1490: 1491: 1492:
1493: function setValid($valid) {
1494: $this->set('valid', $valid);
1495: }
1496:
1497: 1498: 1499:
1500: function getValid() {
1501: return $this->get('valid');
1502: }
1503:
1504: 1505: 1506: 1507:
1508: function setGroup($group) {
1509: $this->set('group', $group);
1510: }
1511:
1512: 1513: 1514:
1515: function getGroup() {
1516: return $this->get('group');
1517: }
1518:
1519: 1520: 1521:
1522: function setUser($user) {
1523: $this->set('user', $user);
1524: }
1525:
1526: 1527: 1528:
1529: function getUser() {
1530: return $this->get('user');
1531: }
1532:
1533: 1534: 1535:
1536: function setQuota($v) {
1537: $this->set('quota', $v);
1538: }
1539:
1540: 1541: 1542:
1543: function getQuota() {
1544: return $this->get('quota');
1545: }
1546:
1547: 1548: 1549:
1550: function getLanguage() {
1551: return $this->get('language');
1552: }
1553:
1554: 1555: 1556:
1557: function setLanguage($locale) {
1558: $this->set('language', $locale);
1559: }
1560:
1561: 1562: 1563:
1564: function save() {
1565: global $_zp_gallery;
1566: if (DEBUG_LOGIN) {
1567: debugLogVar("Zenphoto_Administrator->save()", $this);
1568: }
1569: $objects = $this->getObjects();
1570: if (is_null($this->get('date'))) {
1571: $this->set('date', date('Y-m-d H:i:s'));
1572: }
1573: parent::save();
1574: $id = $this->getID();
1575: if (is_array($objects)) {
1576: $sql = "DELETE FROM " . prefix('admin_to_object') . ' WHERE `adminid`=' . $id;
1577: $result = query($sql, false);
1578: foreach ($objects as $object) {
1579: if (array_key_exists('edit', $object)) {
1580: $edit = $object['edit'] | 32767 & ~(MANAGED_OBJECT_RIGHTS_EDIT | MANAGED_OBJECT_RIGHTS_UPLOAD | MANAGED_OBJECT_RIGHTS_VIEW);
1581: } else {
1582: $edit = 32767;
1583: }
1584: switch ($object['type']) {
1585: case 'album':
1586: $album = newAlbum($object['data']);
1587: $albumid = $album->getID();
1588: $sql = "INSERT INTO " . prefix('admin_to_object') . " (adminid, objectid, type, edit) VALUES ($id, $albumid, 'albums', $edit)";
1589: $result = query($sql);
1590: break;
1591: case 'pages':
1592: $sql = 'SELECT * FROM ' . prefix('pages') . ' WHERE `titlelink`=' . db_quote($object['data']);
1593: $result = query_single_row($sql);
1594: if (is_array($result)) {
1595: $objectid = $result['id'];
1596: $sql = "INSERT INTO " . prefix('admin_to_object') . " (adminid, objectid, type, edit) VALUES ($id, $objectid, 'pages', $edit)";
1597: $result = query($sql);
1598: }
1599: break;
1600: case 'news':
1601: $sql = 'SELECT * FROM ' . prefix('news_categories') . ' WHERE `titlelink`=' . db_quote($object['data']);
1602: $result = query_single_row($sql);
1603: if (is_array($result)) {
1604: $objectid = $result['id'];
1605: $sql = "INSERT INTO " . prefix('admin_to_object') . " (adminid, objectid, type, edit) VALUES ($id, $objectid, 'news', $edit)";
1606: $result = query($sql);
1607: }
1608: break;
1609: }
1610: }
1611: }
1612: }
1613:
1614: 1615: 1616:
1617: function remove() {
1618: zp_apply_filter('remove_user', $this);
1619: $album = $this->getAlbum();
1620: $id = $this->getID();
1621: if (parent::remove()) {
1622: if (!empty($album)) {
1623: $album->remove();
1624: }
1625: $sql = "DELETE FROM " . prefix('admin_to_object') . " WHERE `adminid`=$id";
1626: $result = query($sql);
1627: } else {
1628: return false;
1629: }
1630: return $result;
1631: }
1632:
1633: 1634: 1635:
1636: function getAlbum() {
1637: $id = $this->get('prime_album');
1638: if (!empty($id)) {
1639: $sql = 'SELECT `folder` FROM ' . prefix('albums') . ' WHERE `id`=' . $id;
1640: $result = query_single_row($sql);
1641: if ($result) {
1642: $album = newAlbum($result['folder']);
1643: return $album;
1644: }
1645: }
1646: return false;
1647: }
1648:
1649: 1650: 1651: 1652:
1653: function setAlbum($album) {
1654: if ($album) {
1655: $this->set('prime_album', $album->getID());
1656: } else {
1657: $this->set('prime_album', NULL);
1658: }
1659: }
1660:
1661: 1662: 1663:
1664: function getCredentials() {
1665: return getSerializedArray($this->get('other_credentials'));
1666: }
1667:
1668: function setCredentials($cred) {
1669: $this->set('other_credentials', serialize($cred));
1670: }
1671:
1672: 1673: 1674:
1675: function createPrimealbum($new = true, $name = NULL) {
1676:
1677: $t = 0;
1678: $ext = '';
1679: if (is_null($name)) {
1680: $filename = internalToFilesystem(str_replace(array('<', '>', ':', '"' . '/' . '\\', '|', '?', '*'), '_', seoFriendly($this->getUser())));
1681: } else {
1682: $filename = internalToFilesystem(str_replace(array('<', '>', ':', '"' . '/' . '\\', '|', '?', '*'), '_', $name));
1683: }
1684: while ($new && file_exists(ALBUM_FOLDER_SERVERPATH . $filename . $ext)) {
1685: $t++;
1686: $ext = '-' . $t;
1687: }
1688: $path = ALBUM_FOLDER_SERVERPATH . $filename . $ext;
1689: $albumname = filesystemToInternal($filename . $ext);
1690: if (@mkdir_recursive($path, FOLDER_MOD)) {
1691: $album = newAlbum($albumname);
1692: if ($title = $this->getName()) {
1693: $album->setTitle($title);
1694: }
1695: $album->save();
1696: $this->setAlbum($album);
1697: $this->setRights($this->getRights() | ALBUM_RIGHTS);
1698: if (getOption('user_album_edit_default')) {
1699: $subrights = MANAGED_OBJECT_RIGHTS_EDIT;
1700: } else {
1701: $subrights = 0;
1702: }
1703: if ($this->getRights() & UPLOAD_RIGHTS) {
1704: $subrights = $subrights | MANAGED_OBJECT_RIGHTS_UPLOAD;
1705: }
1706: $objects = $this->getObjects();
1707: $objects[] = array('data' => $albumname, 'name' => $albumname, 'type' => 'album', 'edit' => $subrights);
1708: $this->setObjects($objects);
1709: }
1710: }
1711:
1712: function getChallengePhraseInfo() {
1713: $info = $this->get('challenge_phrase');
1714: if ($info) {
1715: return getSerializedArray($info);
1716: } else {
1717: return array('challenge' => '', 'response' => '');
1718: }
1719: }
1720:
1721: function setChallengePhraseInfo($challenge, $response) {
1722: $this->set('challenge_phrase', serialize(array('challenge' => $challenge, 'response' => $response)));
1723: }
1724:
1725: 1726: 1727: 1728:
1729: function getLastLogon() {
1730: return $this->get('lastloggedin');
1731: }
1732:
1733: 1734: 1735:
1736: function preservePrimeAlbum() {
1737: $primeAlbum = $this->getAlbum();
1738: if (is_object($primeAlbum)) {
1739: $primealbum_name = $primeAlbum->name;
1740: $objects = $this->getObjects();
1741: $primealbum_managed = false;
1742: foreach ($objects as $key => $val) {
1743: if ($val['type'] == 'album' && $val['name'] == $primealbum_name) {
1744: $primealbum_managed = true;
1745: break;
1746: }
1747: }
1748: if (!$primealbum_managed) {
1749: $objects[] = array(
1750: 'data' => $primealbum_name,
1751: 'name' => $primealbum_name,
1752: 'type' => 'album',
1753: 'edit' => 32765
1754: );
1755: }
1756: $this->setObjects($objects);
1757: }
1758: }
1759:
1760: }
1761: ?>
1762: