Subversion Repositories oidplus

Rev

Rev 147 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 Daniel Marschall, ViaThinkSoft
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
112 daniel-mar 20
if (!defined('IN_OIDPLUS')) die();
21
 
2 daniel-mar 22
class OIDplusOid extends OIDplusObject {
23
        private $oid;
24
 
25
        public function __construct($oid) {
12 daniel-mar 26
                $bak_oid = $oid;
27
 
28
                $oid = sanitizeOID($oid, 'auto');
29
                if ($oid === false) {
30
                        throw new Exception("Invalid OID '$bak_oid'");
31
                }
32
 
33
                if (($oid != '') && (!oid_valid_dotnotation($oid, false, true, 0))) {
34
                        // avoid OIDs like 3.0
35
                        throw new Exception("Invalid OID '$bak_oid'");
36
                }
37
 
2 daniel-mar 38
                $this->oid = $oid;
39
        }
40
 
41
        public static function parse($node_id) {
42
                @list($namespace, $oid) = explode(':', $node_id, 2);
43
                if ($namespace !== 'oid') return false;
44
                return new self($oid);
45
        }
46
 
47
        public static function objectTypeTitle() {
48
                return "Object Identifier (OID)";
49
        }
50
 
51
        public static function objectTypeTitleShort() {
52
                return "OID";
53
        }
54
 
55
        public static function ns() {
56
                return 'oid';
57
        }
58
 
59
        public static function root() {
60
                return 'oid:';
61
        }
62
 
63
        public function isRoot() {
64
                return $this->oid == '';
65
        }
66
 
67
        public function nodeId() {
68
                return 'oid:'.$this->oid;
69
        }
70
 
71
        public function addString($str) {
72
                if (!$this->isRoot()) {
73
                        if (strpos($str,'.') !== false) die("Please only submit one arc (not an absolute OID or multiple arcs).");
74
                }
75
                return $this->appendArcs($str)->nodeId();
76
        }
77
 
78
        public function crudShowId(OIDplusObject $parent) {
79
                return $this->deltaDotNotation($parent);
80
        }
81
 
82
        public function crudInsertPrefix() {
83
                return '';
84
        }
85
 
86
        public function jsTreeNodeName(OIDplusObject $parent = null) {
87
                if ($parent == null) return $this->objectTypeTitle();
88
                return $this->viewGetArcAsn1s($parent);
89
        }
90
 
91
        public function defaultTitle() {
92
                return 'OID ' . $this->oid;
93
        }
94
 
16 daniel-mar 95
        public function isLeafNode() {
96
                return false;
97
        }
98
 
34 daniel-mar 99
        public function getContentPage(&$title, &$content, &$icon) {
55 daniel-mar 100
                $icon = file_exists(__DIR__.'/icon_big.png') ? 'plugins/objectTypes/'.basename(__DIR__).'/icon_big.png' : '';
101
 
2 daniel-mar 102
                if ($this->isRoot()) {
103
                        $title = OIDplusOid::objectTypeTitle();
104
 
150 daniel-mar 105
                        $res = OIDplus::db()->query("select id from ".OIDPLUS_TABLENAME_PREFIX."objects where parent = ?", array(self::root()));
2 daniel-mar 106
                        if (OIDplus::db()->num_rows($res) > 0) {
107
                                $content = 'Please select an OID in the tree view at the left to show its contents.';
108
                        } else {
109
                                $content = 'Currently, no OID is registered in the system.';
110
                        }
111
 
16 daniel-mar 112
                        if (!$this->isLeafNode()) {
113
                                if (OIDplus::authUtils()::isAdminLoggedIn()) {
114
                                        $content .= '<h2>Manage your root OIDs</h2>';
115
                                } else {
116
                                        $content .= '<h2>Root OIDs</h2>';
117
                                }
118
                                $content .= '%%CRUD%%';
2 daniel-mar 119
                        }
120
                } else {
103 daniel-mar 121
                        $content = "<h2>Technical information</h2>".$this->oidInformation().
11 daniel-mar 122
                                   "<h2>Description</h2>%%DESC%%".
6 daniel-mar 123
                                   "<h2>Registration Authority</h2>%%RA_INFO%%";
2 daniel-mar 124
 
16 daniel-mar 125
                        if (!$this->isLeafNode()) {
126
                                if ($this->userHasWriteRights()) {
127
                                        $content .= '<h2>Create or change subsequent objects</h2>';
128
                                } else {
129
                                        $content .= '<h2>Subsequent objects</h2>';
130
                                }
131
                                $content .= '%%CRUD%%';
2 daniel-mar 132
                        }
133
                }
134
        }
135
 
136
        # ---
137
 
138
        private function oidInformation() {
61 daniel-mar 139
                $weid = WeidOidConverter::oid2weid($this->getDotNotation());
140
                $weid = ($weid === false) ? "" : "<br>WEID notation: <code>" . htmlentities($weid) . "</code>";
141
                return "<p>Dot notation: <code>" . $this->getDotNotation() . "</code><br>" .
142
                       "ASN.1 notation: <code>{ " . $this->getAsn1Notation() . " }</code><br>" .
67 daniel-mar 143
                       "OID-IRI notation: <code>" . $this->getIriNotation() . "</code><br>" .
144
                       "SHA1 namebased UUID: <code>".gen_uuid_sha1_namespace(UUID_NAMEBASED_NS_OID, $this->getDotNotation())."</code><br>" .
145
                       "MD5 namebased UUID: <code>".gen_uuid_md5_namespace(UUID_NAMEBASED_NS_OID, $this->getDotNotation())."</code>$weid</p>";
2 daniel-mar 146
        }
147
 
148
        public function __clone() {
149
                return new self($this->oid);
150
        }
151
 
152
        public function appendArcs(String $arcs) {
153
                $out = clone $this;
5 daniel-mar 154
 
2 daniel-mar 155
                if ($out->isRoot()) {
156
                        $out->oid .= $arcs;
157
                } else {
158
                        $out->oid .= '.' . $arcs;
159
                }
5 daniel-mar 160
 
13 daniel-mar 161
                $bak_oid = $out->oid;
5 daniel-mar 162
                $out->oid = sanitizeOID($out->oid);
13 daniel-mar 163
                if ($out->oid === false) throw new Exception("$bak_oid is not a valid OID!");
5 daniel-mar 164
 
2 daniel-mar 165
                return $out;
166
        }
167
 
168
        public function deltaDotNotation(OIDplusOid $parent) {
169
                if (!$parent->isRoot()) {
170
                        if (substr($this->oid, 0, strlen($parent->oid)+1) == $parent->oid.'.') {
171
                                return substr($this->oid, strlen($parent->oid)+1);
172
                        } else {
173
                                return false;
174
                        }
175
                } else {
176
                        return $this->oid;
177
                }
178
        }
179
 
180
        public function viewGetArcAsn1s(OIDplusOid $parent=null, $separator = ' | ') {
181
                $asn_ids = array();
182
 
183
                if (is_null($parent)) $parent = OIDplusOid::parse('oid:');
184
 
185
                $part = $this->deltaDotNotation($parent);
186
 
187
                if (strpos($part, '.') === false) {
150 daniel-mar 188
                        $res2 = OIDplus::db()->query("select name from ".OIDPLUS_TABLENAME_PREFIX."asn1id where oid = ? order by lfd", array("oid:".$this->oid));
2 daniel-mar 189
                        while ($row2 = OIDplus::db()->fetch_array($res2)) {
190
                                $asn_ids[] = $row2['name'].'('.$part.')';
191
                        }
192
                }
193
 
194
                if (count($asn_ids) == 0) $asn_ids = array($part);
195
                return implode($asn_ids, $separator);
196
        }
197
 
198
        public function getAsn1Notation($withAbbr=true) {
199
                $asn1_notation = '';
200
                $arcs = explode('.', $this->oid);
201
 
202
                foreach ($arcs as $arc) {
150 daniel-mar 203
                        $res = OIDplus::db()->query("select name, standardized from ".OIDPLUS_TABLENAME_PREFIX."asn1id where oid = ? order by lfd", array('oid:'.implode('.',$arcs)));
2 daniel-mar 204
 
205
                        $names = array();
206
                        while ($row = OIDplus::db()->fetch_array($res)) {
51 daniel-mar 207
                                $names[] = $row['name']."(".end($arcs).")";
208
                                if ($row['standardized']) {
209
                                        $names[] = $row['name'];
210
                                }
2 daniel-mar 211
                        }
212
 
52 daniel-mar 213
                        $numeric = array_pop($arcs);
2 daniel-mar 214
                        if (count($names) > 1) {
215
                                $first_name = array_shift($names);
52 daniel-mar 216
                                $abbr = 'Other identifiers:&#10;      '.implode('&#10;      ',$names);
2 daniel-mar 217
                                if ($withAbbr) {
51 daniel-mar 218
                                        $asn1_notation = '<abbr title="'.$abbr.'">'.$first_name.'</abbr> '.$asn1_notation;
2 daniel-mar 219
                                } else {
51 daniel-mar 220
                                        $asn1_notation = $first_name.' '.$asn1_notation;
2 daniel-mar 221
                                }
222
                        } else if (count($names) == 1) {
51 daniel-mar 223
                                $asn1_notation = array_shift($names).' '.$asn1_notation;
2 daniel-mar 224
                        } else {
52 daniel-mar 225
                                $asn1_notation = $numeric.' '.$asn1_notation;
2 daniel-mar 226
                        }
227
                }
228
 
229
                return $asn1_notation;
230
        }
231
 
232
        public function getIriNotation($withAbbr=true) {
233
                $iri_notation = '';
234
                $arcs = explode('.', $this->oid);
235
 
236
                foreach ($arcs as $arc) {
150 daniel-mar 237
                        $res = OIDplus::db()->query("select name, longarc from ".OIDPLUS_TABLENAME_PREFIX."iri where oid = ? order by lfd", array('oid:'.implode('.',$arcs)));
2 daniel-mar 238
 
239
                        $is_longarc = false;
240
                        $names = array();
241
                        while ($row = OIDplus::db()->fetch_array($res)) {
242
                                $is_longarc = $row['longarc'];
243
                                $names[] = $row['name'];
51 daniel-mar 244
 
245
                                if ($is_longarc) {
246
                                        $names[] = 'Joint-ISO-ITU-T/'.$row['name']; // Long arcs can only be inside root OID 2
247
                                }
2 daniel-mar 248
                        }
249
 
250
                        $names[] = array_pop($arcs);
251
                        if (count($names) > 2) {
252
                                $first_name = array_shift($names);
52 daniel-mar 253
                                $numeric = array_pop($names);
254
                                $abbr = 'Other identifiers:&#10;      '.implode('&#10;      ',$names).'&#10;Numeric value: '.$numeric;
2 daniel-mar 255
                                $iri_notation = $withAbbr ? '<abbr title="'.$abbr.'">'.$first_name.'</abbr>/'.$iri_notation : $first_name.'/'.$iri_notation;
256
                        } else if (count($names) > 1) {
257
                                $first_name = array_shift($names);
258
                                $abbr = 'Numeric value: '.array_shift($names);
259
                                $iri_notation = $withAbbr ? '<abbr title="'.$abbr.'">'.$first_name.'</abbr>/'.$iri_notation : $first_name.'/'.$iri_notation;
260
                        } else if (count($names) == 1) {
261
                                $iri_notation = array_shift($names) . '/' . $iri_notation;
262
                        }
263
 
51 daniel-mar 264
                        if ($is_longarc) break; // we don't write /ITU-T/ at the beginning, when /ITU-T/xxx is a long arc
2 daniel-mar 265
                }
266
                $iri_notation = '/' . substr($iri_notation, 0, strlen($iri_notation)-1);
267
 
268
                return $iri_notation;
269
        }
270
 
271
        public function getDotNotation() {
272
                return $this->oid;
273
        }
274
 
13 daniel-mar 275
        public function isWellKnown() {
150 daniel-mar 276
                $res = OIDplus::db()->query("select oid from ".OIDPLUS_TABLENAME_PREFIX."asn1id where oid = ? and well_known = 1", array("oid:".$this->oid));
13 daniel-mar 277
                if (OIDplus::db()->num_rows($res) > 0) return true;
278
 
150 daniel-mar 279
                $res = OIDplus::db()->query("select oid from ".OIDPLUS_TABLENAME_PREFIX."iri where oid = ? and well_known = 1", array("oid:".$this->oid));
13 daniel-mar 280
                if (OIDplus::db()->num_rows($res) > 0) return true;
281
 
282
                return false;
283
        }
284
 
147 daniel-mar 285
        public function replaceAsn1Ids($demandedASN1s=array(), $simulate=false) {
13 daniel-mar 286
                if ($this->isWellKnown()) {
287
                        throw new Exception("OID ".$this->oid." is a 'well-known' OID. Its identifiers cannot be changed.");
288
                }
289
 
2 daniel-mar 290
                // First do a few checks
291
                foreach ($demandedASN1s as &$asn1) {
292
                        $asn1 = trim($asn1);
293
 
13 daniel-mar 294
                        // Validate identifier
295
                        if (!oid_id_is_valid($asn1)) throw new Exception("'$asn1' is not a valid ASN.1 identifier!");
296
 
2 daniel-mar 297
                        // Check if the (real) parent has any conflict
150 daniel-mar 298
                        $res = OIDplus::db()->query("select oid from ".OIDPLUS_TABLENAME_PREFIX."asn1id where name = ?", array($asn1));
2 daniel-mar 299
                        while ($row = OIDplus::db()->fetch_array($res)) {
300
                                $check_oid = OIDplusOid::parse($row['oid'])->oid;
301
                                if ((oid_up($check_oid) === oid_up($this->oid)) && // same parent
302
                                   ($check_oid !== $this->oid))                    // different OID
303
                                {
304
                                        throw new Exception("ASN.1 identifier '$asn1' is already used by another OID ($check_oid)");
305
                                }
306
                        }
307
                }
308
 
309
                // Now do the real replacement
147 daniel-mar 310
                if (!$simulate) {
150 daniel-mar 311
                        OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."asn1id where oid = ?", array("oid:".$this->oid));
147 daniel-mar 312
                        foreach ($demandedASN1s as &$asn1) {
150 daniel-mar 313
                                if (!OIDplus::db()->query("insert into ".OIDPLUS_TABLENAME_PREFIX."asn1id (oid, name) values (?, ?)", array("oid:".$this->oid, $asn1))) {
147 daniel-mar 314
                                        throw new Exception("Insertion of ASN.1 ID $asn1 to OID ".$this->oid." failed!");
315
                                }
2 daniel-mar 316
                        }
317
                }
318
        }
319
 
147 daniel-mar 320
        public function replaceIris($demandedIris=array(), $simulate=false) {
13 daniel-mar 321
                if ($this->isWellKnown()) {
322
                        throw new Exception("OID ".$this->oid." is a 'well-known' OID. Its identifiers cannot be changed.");
323
                }
324
 
2 daniel-mar 325
                // First do a few checks
326
                foreach ($demandedIris as &$iri) {
327
                        $iri = trim($iri);
328
 
13 daniel-mar 329
                        // Validate identifier
330
                        if (!iri_arc_valid($iri, false)) throw new Exception("'$iri' is not a valid IRI!");
331
 
2 daniel-mar 332
                        // Check if the (real) parent has any conflict
150 daniel-mar 333
                        $res = OIDplus::db()->query("select oid from ".OIDPLUS_TABLENAME_PREFIX."iri where name = ?", array($iri));
2 daniel-mar 334
                        while ($row = OIDplus::db()->fetch_array($res)) {
335
                                $check_oid = OIDplusOid::parse($row['oid'])->oid;
336
                                if ((oid_up($check_oid) === oid_up($this->oid)) && // same parent
337
                                   ($check_oid !== $this->oid))                    // different OID
338
                                {
339
                                        throw new Exception("IRI '$iri' is already used by another OID ($check_oid)");
340
                                }
341
                        }
342
                }
343
 
344
                // Now do the real replacement
147 daniel-mar 345
                if (!$simulate) {
150 daniel-mar 346
                        OIDplus::db()->query("delete from ".OIDPLUS_TABLENAME_PREFIX."iri where oid = ?", array("oid:".$this->oid));
147 daniel-mar 347
                        foreach ($demandedIris as &$iri) {
150 daniel-mar 348
                                if (!OIDplus::db()->query("insert into ".OIDPLUS_TABLENAME_PREFIX."iri (oid, name) values (?, ?)", array("oid:".$this->oid, $iri))) {
147 daniel-mar 349
                                        throw new Exception("Insertion of IRI $iri to OID ".$this->oid." failed!");
350
                                }
2 daniel-mar 351
                        }
352
                }
353
        }
12 daniel-mar 354
 
20 daniel-mar 355
        public function one_up() {
356
                return self::parse(self::ns().':'.oid_up($this->oid));
12 daniel-mar 357
        }
358
 
359
        public function distance($to) {
360
                if (!is_object($to)) $to = OIDplusObject::parse($to);
28 daniel-mar 361
                if (!($to instanceof $this)) return false;
12 daniel-mar 362
                return oid_distance($to->oid, $this->oid);
363
        }
2 daniel-mar 364
}
365
 
61 daniel-mar 366
OIDplus::registerObjectType('OIDplusOid');