Index: trunk/extensions/OpenStackManager/OpenStackNovaUser.php |
— | — | @@ -29,9 +29,29 @@ |
30 | 30 | return array( 'accessKey' => $accessKey, 'secretKey' => $secretKey ); |
31 | 31 | } |
32 | 32 | |
| 33 | + function getKeypairs() { |
| 34 | + if ( isset( $this->userInfo[0]['sshpublickey'] ) ) { |
| 35 | + $keys = $this->userInfo[0]['sshpublickey']; |
| 36 | + $keypairs = array(); |
| 37 | + if ( is_array( $keys ) ) { |
| 38 | + array_shift( $keys ); |
| 39 | + foreach ( $keys as $key ) { |
| 40 | + $hash = md5( $key ); |
| 41 | + $keypairs["$hash"] = $key; |
| 42 | + } |
| 43 | + } else { |
| 44 | + $hash = md5( $keys ); |
| 45 | + $keypairs["$hash"] = $keys; |
| 46 | + } |
| 47 | + return $keypairs; |
| 48 | + } else { |
| 49 | + return array(); |
| 50 | + } |
| 51 | + } |
| 52 | + |
33 | 53 | function isAdmin() { |
34 | 54 | if ( isset( $this->userInfo[0]['isadmin'] ) ) { |
35 | | - $isAdmin = $this->userInfo[0]['isadmin']; |
| 55 | + $isAdmin = $this->userInfo[0]['isadmin'][0]; |
36 | 56 | if ( strtolower( $isAdmin ) == "true" ) { |
37 | 57 | return true; |
38 | 58 | } |
— | — | @@ -119,12 +139,16 @@ |
120 | 140 | |
121 | 141 | function importKeypair( $key ) { |
122 | 142 | global $wgAuth; |
123 | | - global $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword; |
124 | 143 | |
125 | | - $wgAuth->connect(); |
126 | | - $wgAuth->bindAs( $wgOpenStackManagerLDAPUser, $wgOpenStackManagerLDAPUserPassword ); |
| 144 | + $this->connect(); |
127 | 145 | |
128 | | - $values['sshpublickey'] = $key; |
| 146 | + $keypairs = array(); |
| 147 | + if ( isset( $this->userInfo[0]['sshpublickey'] ) ) { |
| 148 | + $keypairs = $this->userInfo[0]['sshpublickey']; |
| 149 | + array_shift( $keypairs ); |
| 150 | + } |
| 151 | + $keypairs[] = $key; |
| 152 | + $values['sshpublickey'] = $keypairs; |
129 | 153 | $success = @ldap_modify( $wgAuth->ldapconn, $this->userDN, $values ); |
130 | 154 | if ( $success ) { |
131 | 155 | $wgAuth->printDebug( "Successfully imported the user's sshpublickey", NONSENSITIVE ); |
— | — | @@ -135,6 +159,40 @@ |
136 | 160 | } |
137 | 161 | } |
138 | 162 | |
| 163 | + function deleteKeypair( $key ) { |
| 164 | + global $wgAuth; |
| 165 | + |
| 166 | + if ( isset( $this->userInfo[0]['sshpublickey'] ) ) { |
| 167 | + $keypairs = $this->userInfo[0]['sshpublickey']; |
| 168 | + array_shift( $keypairs ); |
| 169 | + $index = array_search( $key, $keypairs ); |
| 170 | + if ( $index === false ) { |
| 171 | + $wgAuth->printDebug( "Unable to find the sshpublickey to be deleted", NONSENSITIVE ); |
| 172 | + return false; |
| 173 | + } else { |
| 174 | + unset( $keypairs[$index] ); |
| 175 | + } |
| 176 | + if ( sizeof( $keypairs ) == 1 ) { |
| 177 | + $values['sshpublickey'] = $keypairs[0]; |
| 178 | + } else { |
| 179 | + $values['sshpublickey'] = $keypairs; |
| 180 | + } |
| 181 | + $success = @ldap_modify( $wgAuth->ldapconn, $this->userDN, $values ); |
| 182 | + if ( $success ) { |
| 183 | + $wgAuth->printDebug( "Successfully deleted the user's sshpublickey", NONSENSITIVE ); |
| 184 | + return true; |
| 185 | + } else { |
| 186 | + $wgAuth->printDebug( "Failed to delete the user's sshpublickey", NONSENSITIVE ); |
| 187 | + $wgAuth->printDebug( "KEY: $key", NONSENSITIVE ); |
| 188 | + $wgAuth->printDebug( "sshpublickey: ", NONSENSITIVE, $values['sshpublickey'] ); |
| 189 | + return false; |
| 190 | + } |
| 191 | + } else { |
| 192 | + $wgAuth->printDebug( "User does not have a sshpublickey attribute", NONSENSITIVE ); |
| 193 | + return false; |
| 194 | + } |
| 195 | + } |
| 196 | + |
139 | 197 | static function uuid4() { |
140 | 198 | uuid_create( &$uuid ); |
141 | 199 | uuid_make( $uuid, UUID_MAKE_V4 ); |
Index: trunk/extensions/OpenStackManager/SpecialNovaKey.php |
— | — | @@ -2,6 +2,7 @@ |
3 | 3 | class SpecialNovaKey extends SpecialPage { |
4 | 4 | |
5 | 5 | var $userNova, $userLDAP; |
| 6 | + var $keypairs; |
6 | 7 | |
7 | 8 | function __construct() { |
8 | 9 | parent::__construct( 'NovaKey' ); |
— | — | @@ -17,15 +18,10 @@ |
18 | 19 | return true; |
19 | 20 | } |
20 | 21 | |
21 | | - $project = $wgRequest->getVal('project'); |
22 | 22 | $action = $wgRequest->getVal('action'); |
23 | 23 | if ( $action == "import" ) { |
24 | 24 | $this->importKey(); |
25 | 25 | } else if ( $action == "delete" ) { |
26 | | - if ( ! $this->userLDAP->inProject( $project ) ) { |
27 | | - $this->notInProject(); |
28 | | - return true; |
29 | | - } |
30 | 26 | $this->deleteKey(); |
31 | 27 | } else { |
32 | 28 | $this->listKeys(); |
— | — | @@ -50,28 +46,32 @@ |
51 | 47 | |
52 | 48 | function importKey() { |
53 | 49 | global $wgRequest, $wgOut; |
| 50 | + global $wgOpenStackManagerNovaKeypairStorage; |
54 | 51 | |
55 | | - $project = $wgRequest->getVal('project'); |
56 | | - if ( $project && ! $this->userLDAP->inProject( $project ) ) { |
57 | | - $this->notInProject(); |
58 | | - return true; |
| 52 | + if ( $wgOpenStackManagerNovaKeypairStorage == 'nova' ) { |
| 53 | + $project = $wgRequest->getVal('project'); |
| 54 | + if ( $project && ! $this->userLDAP->inProject( $project ) ) { |
| 55 | + $this->notInProject(); |
| 56 | + return true; |
| 57 | + } |
| 58 | + $userCredentials = $this->userLDAP->getCredentials( $project ); |
| 59 | + $this->userNova = new OpenStackNovaController( $userCredentials ); |
59 | 60 | } |
60 | | - $userCredentials = $this->userLDAP->getCredentials( $project ); |
61 | | - $this->userNova = new OpenStackNovaController( $userCredentials ); |
62 | 61 | |
63 | 62 | $this->setHeaders(); |
64 | 63 | $wgOut->setPagetitle("Import Key"); |
65 | 64 | |
66 | | - # TODO: Add project name field |
67 | | - |
68 | 65 | $keyInfo = Array(); |
69 | | - $keyInfo['keyName'] = array( |
70 | | - 'type' => 'text', |
71 | | - 'label-message' => 'keyname', |
72 | | - 'default' => '', |
73 | | - 'section' => 'key/info', |
74 | | - ); |
75 | 66 | |
| 67 | + if ( $wgOpenStackManagerNovaKeypairStorage == 'nova' ) { |
| 68 | + $keyInfo['keyName'] = array( |
| 69 | + 'type' => 'text', |
| 70 | + 'label-message' => 'keyname', |
| 71 | + 'default' => '', |
| 72 | + 'section' => 'key/info', |
| 73 | + ); |
| 74 | + } |
| 75 | + |
76 | 76 | $keyInfo['key'] = array( |
77 | 77 | 'type' => 'textarea', |
78 | 78 | 'section' => 'key/info', |
— | — | @@ -89,8 +89,6 @@ |
90 | 90 | 'default' => htmlentities( $project ), |
91 | 91 | ); |
92 | 92 | |
93 | | - #TODO: Add availablity zone field |
94 | | - |
95 | 93 | $keyForm = new SpecialNovaKeyForm( $keyInfo, 'novakey-form' ); |
96 | 94 | $keyForm->setTitle( SpecialPage::getTitleFor( 'NovaKey' )); |
97 | 95 | $keyForm->setSubmitID( 'novakey-form-createkeysubmit' ); |
— | — | @@ -100,42 +98,90 @@ |
101 | 99 | } |
102 | 100 | |
103 | 101 | function deleteKey() { |
104 | | - global $wgOut; |
| 102 | + global $wgOut, $wgRequest; |
| 103 | + global $wgOpenStackManagerNovaKeypairStorage; |
105 | 104 | |
106 | | - $project = $wgRequest->getVal('project'); |
107 | | - if ( $project && ! $this->userLDAP->inProject( $project ) ) { |
108 | | - $this->notInProject(); |
109 | | - return true; |
| 105 | + $this->setHeaders(); |
| 106 | + $wgOut->setPagetitle("Delete key"); |
| 107 | + if ( $wgOpenStackManagerNovaKeypairStorage == 'nova' ) { |
| 108 | + $project = $wgRequest->getVal('project'); |
| 109 | + if ( $project && ! $this->userLDAP->inProject( $project ) ) { |
| 110 | + $this->notInProject(); |
| 111 | + return true; |
| 112 | + } |
| 113 | + } else if ( $wgOpenStackManagerNovaKeypairStorage == 'ldap' ) { |
| 114 | + $hash = $wgRequest->getVal( 'hash' ); |
| 115 | + $keypairs = $this->userLDAP->getKeypairs(); |
| 116 | + if ( ! $wgRequest->wasPosted() ) { |
| 117 | + $out = Html::element( 'pre', array(), $keypairs[$hash] ); |
| 118 | + $out .= Html::element( 'p', array(), 'Are you sure you wish to delete the above key?' ); |
| 119 | + $wgOut->addHTML( $out ); |
| 120 | + } |
| 121 | + |
| 122 | + $keyInfo = Array(); |
| 123 | + |
| 124 | + $keyInfo['hash'] = array( |
| 125 | + 'type' => 'hidden', |
| 126 | + 'default' => $hash, |
| 127 | + ); |
| 128 | + $keyInfo['key'] = array( |
| 129 | + 'type' => 'hidden', |
| 130 | + 'default' => $keypairs[$hash], |
| 131 | + ); |
| 132 | + $keyInfo['action'] = array( |
| 133 | + 'type' => 'hidden', |
| 134 | + 'default' => 'delete', |
| 135 | + ); |
| 136 | + $keyForm = new SpecialNovaKeyForm( $keyInfo, 'novakey-form' ); |
| 137 | + $keyForm->setTitle( SpecialPage::getTitleFor( 'NovaKey' )); |
| 138 | + $keyForm->setSubmitID( 'novakey-form-deletekeysubmit' ); |
| 139 | + $keyForm->setSubmitCallback( array( $this, 'tryDeleteSubmit' ) ); |
| 140 | + $keyForm->setSubmitText( 'confirm' ); |
| 141 | + $keyForm->show(); |
110 | 142 | } |
111 | | - $this->setHeaders(); |
112 | | - $wgOut->setPagetitle("Confirm key deletion"); |
113 | 143 | return true; |
114 | 144 | } |
115 | 145 | |
116 | 146 | function listKeys() { |
117 | | - global $wgOut; |
| 147 | + global $wgOut, $wgUser; |
| 148 | + global $wgOpenStackManagerNovaKeypairStorage; |
118 | 149 | |
119 | 150 | $this->setHeaders(); |
120 | 151 | $wgOut->setPagetitle("Key list"); |
121 | 152 | |
122 | 153 | $out = ''; |
123 | | - $projects = $this->userLDAP->getProjects(); |
124 | | - foreach( $projects as $project ) { |
125 | | - $userCredentials = $this->userLDAP->getCredentials( $project ); |
126 | | - $this->userNova = new OpenStackNovaController( $userCredentials ); |
127 | | - $keypairs = $this->userNova->getKeypairs(); |
128 | | - if ( ! $keypairs ) { |
129 | | - continue; |
| 154 | + if ( $wgOpenStackManagerNovaKeypairStorage == 'nova' ) { |
| 155 | + $projects = $this->userLDAP->getProjects(); |
| 156 | + foreach( $projects as $project ) { |
| 157 | + $userCredentials = $this->userLDAP->getCredentials( $project ); |
| 158 | + $this->userNova = new OpenStackNovaController( $userCredentials ); |
| 159 | + $keypairs = $this->userNova->getKeypairs(); |
| 160 | + if ( ! $keypairs ) { |
| 161 | + continue; |
| 162 | + } |
| 163 | + $out .= Html::element( 'h2', array(), $project ); |
| 164 | + $projectOut = Html::element( 'th', array(), 'Name' ); |
| 165 | + $projectOut .= Html::element( 'th', array(), 'Fingerprint' ); |
| 166 | + foreach ( $keypairs as $keypair ) { |
| 167 | + $keyOut = Html::element( 'td', array(), $keypair->getKeyName() ); |
| 168 | + $keyOut .= Html::element( 'td', array(), $keypair->getKeyFingerprint() ); |
| 169 | + $projectOut .= Html::rawElement( 'tr', array(), $keyOut ); |
| 170 | + } |
| 171 | + $out .= Html::rawElement( 'table', array( 'id' => 'novakeylist', 'class' => 'wikitable' ), $projectOut ); |
130 | 172 | } |
131 | | - $out .= Html::element( 'h2', array(), $project ); |
132 | | - $projectOut = Html::element( 'th', array(), 'Name' ); |
133 | | - $projectOut .= Html::element( 'th', array(), 'Fingerprint' ); |
134 | | - foreach ( $keypairs as $keypair ) { |
135 | | - $keyOut = Html::element( 'td', array(), $keypair->getKeyName() ); |
136 | | - $keyOut .= Html::element( 'td', array(), $keypair->getKeyFingerprint() ); |
137 | | - $projectOut .= Html::rawElement( 'tr', array(), $keyOut ); |
| 173 | + } else if ( $wgOpenStackManagerNovaKeypairStorage == 'ldap' ) { |
| 174 | + $keypairs = $this->userLDAP->getKeypairs(); |
| 175 | + $keysOut = ''; |
| 176 | + foreach ( $keypairs as $hash => $key ) { |
| 177 | + $keyOut = Html::element( 'td', array(), $key ); |
| 178 | + $sk = $wgUser->getSkin(); |
| 179 | + $link = $sk->link( $this->getTitle(), 'delete', array(), array( 'action' => 'delete', 'hash' => $hash ), array() ); |
| 180 | + $keyOut .= Html::rawElement( 'td', array(), $link ); |
| 181 | + $keysOut .= Html::rawElement( 'tr', array(), $keyOut ); |
138 | 182 | } |
139 | | - $out .= Html::rawElement( 'table', array( 'id' => 'novainstancelist', 'class' => 'wikitable' ), $projectOut ); |
| 183 | + $out .= Html::rawElement( 'table', array(), $keysOut ); |
| 184 | + } else { |
| 185 | + $out = Html::element( 'p', array(), 'Invalid keypair location configured' ); |
140 | 186 | } |
141 | 187 | |
142 | 188 | $wgOut->addHTML( $out ); |
— | — | @@ -143,21 +189,42 @@ |
144 | 190 | |
145 | 191 | function tryImportSubmit( $formData, $entryPoint = 'internal' ) { |
146 | 192 | global $wgOut; |
| 193 | + global $wgOpenStackManagerNovaKeypairStorage; |
147 | 194 | |
148 | | - $success = $this->userLDAP->importKeypair( $formData['key'] ); |
149 | | - if ( ! $success ) { |
150 | | - $out = Html::element( 'p', array(), 'Failed to import keypair' ); |
151 | | - return false; |
| 195 | + if ( $wgOpenStackManagerNovaKeypairStorage == 'ldap' ) { |
| 196 | + $success = $this->userLDAP->importKeypair( $formData['key'] ); |
| 197 | + if ( ! $success ) { |
| 198 | + $out = Html::element( 'p', array(), 'Failed to import keypair' ); |
| 199 | + return false; |
| 200 | + } |
| 201 | + $out = Html::element( 'p', array(), 'Imported keypair' ); |
| 202 | + } else if ( $wgOpenStackManagerNovaKeypairStorage == 'nova' ) { |
| 203 | + #wgOpenStackManagerNovaKeypairStorage == 'nova' |
| 204 | + # OpenStack's EC2 API doesn't yet support importing keys, use |
| 205 | + # of this option isn't currently recommended |
| 206 | + $keypair = $this->userNova->importKeypair( $formData['keyname'], $formData['key'] ); |
| 207 | + |
| 208 | + $out = Html::element( 'p', array(), 'Imported keypair ' . $keypair->getKeyName() . ' with fingerprint ' . $keypair->getKeyFingerprint() ); |
| 209 | + } else { |
| 210 | + $out = Html::element( 'p', array(), 'Invalid keypair location configured' ); |
152 | 211 | } |
153 | | - # OpenStack's EC2 API doesn't yet support importing keys |
154 | | - //$keypair = $this->userNova->importKeypair( $formData['keyname'], $formData['key'] ); |
155 | 212 | |
156 | | - #$out = Html::element( 'p', array(), 'Imported keypair ' . $keypair->getKeyName() . ' with fingerprint ' . $keypair->getKeyFingerprint() ); |
157 | | - $out = Html::element( 'p', array(), 'Imported keypair' ); |
158 | | - |
159 | 213 | $wgOut->addHTML( $out ); |
160 | 214 | return true; |
161 | 215 | } |
| 216 | + |
| 217 | + function tryDeleteSubmit( $formData, $entryPoint = 'internal' ) { |
| 218 | + global $wgOut; |
| 219 | + global $wgOpenStackManagerNovaKeypairStorage; |
| 220 | + |
| 221 | + $success = $this->userLDAP->deleteKeypair( $formData['key'] ); |
| 222 | + if ( $success ) { |
| 223 | + $out = Html::element( 'p', array(), 'Successfully deleted key' ); |
| 224 | + } else { |
| 225 | + $out = Html::element( 'p', array(), 'Failed to delete key' ); |
| 226 | + } |
| 227 | + $wgOut->addHTML( $out ); |
| 228 | + } |
162 | 229 | } |
163 | 230 | |
164 | 231 | class SpecialNovaKeyForm extends HTMLForm { |