Skip to content

Commit 5905f61

Browse files
committed
added services/caches/edit for log passwords; resolves #488
1 parent 84cd266 commit 5905f61

File tree

6 files changed

+184
-1
lines changed

6 files changed

+184
-1
lines changed

okapi/core/Db.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,4 +284,16 @@ public static function field_exists($table, $field)
284284
}
285285
return false;
286286
}
287+
288+
public static function field_length($table, $field)
289+
{
290+
return self::select_value("
291+
select character_maximum_length
292+
from information_schema.columns
293+
where
294+
table_schema='".self::escape_string(Settings::get('DB_NAME'))."'
295+
and table_name='".self::escape_string($table)."'
296+
and column_name='".self::escape_string($field)."'
297+
");
298+
}
287299
}

okapi/core/OkapiServiceRunner.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class OkapiServiceRunner
3333
'services/caches/search/by_urls',
3434
'services/caches/search/save',
3535
'services/caches/shortcuts/search_and_retrieve',
36+
'services/caches/edit',
3637
'services/caches/geocache',
3738
'services/caches/geocaches',
3839
'services/caches/mark',

okapi/services/apisrv/installation/WebService.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use okapi\core\Okapi;
66
use okapi\core\Request\OkapiRequest;
7+
use okapi\core\Db;
78
use okapi\Settings;
89

910
class WebService
@@ -29,6 +30,8 @@ public static function call(OkapiRequest $request)
2930
$result['mobile_registration_url'] = Settings::get('MOBILE_REGISTRATION_URL');
3031
$result['image_max_upload_size'] = Settings::get('IMAGE_MAX_UPLOAD_SIZE');
3132
$result['image_rcmd_max_pixels'] = Settings::get('IMAGE_MAX_PIXEL_COUNT');
33+
$result['geocache_passwd_max_length'] = Db::field_length('caches', 'logpw');
34+
3235
return Okapi::formatted_response($request, $result);
3336
}
3437
}

okapi/services/apisrv/installation/docs.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@
9393
site to fit this restriction. Larger images may have been
9494
uploaded in the past, or by other means than OKAPI.</p>
9595
</li>
96+
<li>
97+
<p><b>geocache_passwd_max_length</b> - the maximum length of
98+
a password that will be accepted by
99+
<a href='%OKAPI:methodargref:services/caches/edit%'>services/caches/edit</a>.</p>
100+
</li>
96101
</ul>
97102
</returns>
98-
</xml>
103+
</xml>
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
namespace okapi\services\caches\edit;
4+
5+
use okapi\core\Okapi;
6+
use okapi\core\Db;
7+
use okapi\core\Exception\BadRequest;
8+
use okapi\core\Exception\InvalidParam;
9+
use okapi\core\Exception\ParamMissing;
10+
use okapi\core\Request\OkapiRequest;
11+
use okapi\core\Request\OkapiInternalRequest;
12+
use okapi\core\OkapiServiceRunner;
13+
use okapi\Settings;
14+
15+
16+
class WebService
17+
{
18+
public static function options()
19+
{
20+
return array(
21+
'min_auth_level' => 3,
22+
);
23+
}
24+
25+
public static function call(OkapiRequest $request)
26+
{
27+
$cache_code = $request->get_parameter('cache_code');
28+
if ($cache_code == null)
29+
throw new ParamMissing('cache_code');
30+
$geocache = OkapiServiceRunner::call(
31+
'services/caches/geocache',
32+
new OkapiInternalRequest(
33+
$request->consumer,
34+
$request->token,
35+
array('cache_code' => $cache_code, 'fields' => 'internal_id|type|date_created')
36+
)
37+
);
38+
$internal_id_escaped = Db::escape_string($geocache['internal_id']);
39+
$owner_id = Db::select_value(
40+
"select user_id from caches where cache_id = '".$internal_id_escaped."'"
41+
);
42+
if ($owner_id != $request->token->user_id)
43+
throw new BadRequest("Only own caches may be edited.");
44+
45+
$problems = [];
46+
$change_sqls_escaped = [];
47+
48+
$langpref = $request->get_parameter('langpref');
49+
if (!$langpref) $langpref = "en";
50+
$langprefs = explode("|", $langpref);
51+
52+
Okapi::gettext_domain_init($langprefs);
53+
try
54+
{
55+
# passwd
56+
$newpw = $request->get_parameter('passwd');
57+
if ($newpw !== null)
58+
{
59+
$installation = OkapiServiceRunner::call(
60+
'services/apisrv/installation',
61+
new OkapiInternalRequest($request->consumer, $request->token, [])
62+
);
63+
if (strlen($newpw) > $installation['geocache_passwd_max_length']) {
64+
$problems['passwd'] = sprintf(
65+
_('The password must not be longer than %d characters.'),
66+
$installation['geocache_passwd_max_length']
67+
);
68+
} elseif (
69+
Settings::get('OC_BRANCH') == 'oc.pl' &&
70+
$geocache['type'] == 'Traditional' &&
71+
$geocache['date_created'] > '2010-06-18 20:03:18'
72+
) {
73+
# We won't bother the user with the creation date thing here.
74+
# The *current* rule is that OCPL sites do not allow tradi passwords.
75+
# For older caches, the user won't see this message.
76+
77+
$problems['passwd'] = sprintf(
78+
_('%s does not allow log passwords for traditional caches.'),
79+
Okapi::get_normalized_site_name()
80+
);
81+
} else {
82+
$oldpw = Db::select_value("select logpw from caches where cache_id='".$internal_id_escaped."'");
83+
if ($newpw != $oldpw)
84+
$change_sqls_escaped[] = "logpw = '".Db::escape_string($newpw)."'";
85+
unset($oldpw);
86+
}
87+
}
88+
unset($newpw);
89+
90+
Okapi::gettext_domain_restore();
91+
}
92+
catch (Exception $e)
93+
{
94+
Okapi::gettext_domain_restore();
95+
throw $e;
96+
}
97+
98+
# save changes
99+
if (count($problems) == 0 && count($change_sqls_escaped) > 0) {
100+
Db::execute("
101+
update caches
102+
set " . implode(', ', $change_sqls_escaped) . ", last_modified=NOW()
103+
where cache_id = '".$internal_id_escaped."'
104+
");
105+
}
106+
107+
$result = ['success' => count($problems) == 0, 'messages' => $problems];
108+
109+
Okapi::update_user_activity($request);
110+
return Okapi::formatted_response($request, $result);
111+
}
112+
}

okapi/services/caches/edit/docs.xml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<xml>
2+
<brief>Change the properties of a geocache</brief>
3+
<issue-id>TODO</issue-id>
4+
<desc>
5+
<p>This method allows your users to change properties of an owned
6+
geocache. Currently, only the log password can be changed.
7+
Let us know if you need to edit other geocache properties.</p>
8+
</desc>
9+
<req name='cache_code'>
10+
<p>Code of the geocache.</p>
11+
</req>
12+
<opt name='passwd'>
13+
<p>String - the new password for 'Found it' or 'Attended' log entries.
14+
If you supply an empty string, the password will be cleared, i.e.
15+
the geocache will not require a log password.</p>
16+
<p>You may query the maximum accepted password length for the OC site by
17+
<a href='%OKAPI:methodargref:services/apisrv/installation%'>services/apsrv/installation</a>.
18+
There may also be installation-dependent restrictions on which
19+
geocaches may have passwords. <b>success</b> will be <b>false</b> and
20+
an explanation message will be returned if a password is rejected.</p>
21+
</opt>
22+
<opt name='langpref' default='en'>
23+
<p>Pipe-separated list of ISO 639-1 language codes. This indicates the
24+
order of preference in which language will be chosen for the
25+
<b>messages</b> return value.</p>
26+
</opt>
27+
<common-format-params/>
28+
<returns>
29+
<p>A dictionary of the following structure:</p>
30+
<ul>
31+
<li>
32+
<p><b>success</b> - boolean,</p>
33+
<ul>
34+
<li><b>true</b> if all of the supplied geocache properties
35+
were saved successfully or if no property to be changed was
36+
supplied. The geocache's <b>last_modified</b> date has been
37+
updated if any property was changed,</li>
38+
<li><b>false</b> if nothing was saved, which means that at
39+
least one of the supplied parameters was not acceptable.</li>
40+
</ul>
41+
</li>
42+
<li>
43+
<p><b>messages</b> - a dictionary of the supplied parameters
44+
that were not acceptable, each entry giving a plain-text string
45+
that explains the reason of rejection. The dictionary is empty
46+
in case of success.</p>
47+
</li>
48+
</ul>
49+
</returns>
50+
</xml>

0 commit comments

Comments
 (0)