@@ -3,7 +3,7 @@ package org.codeoverflow.chatoverflow.ui.web.rest.connector
33import org .codeoverflow .chatoverflow .configuration .{Credentials , CryptoUtil }
44import org .codeoverflow .chatoverflow .connector .ConnectorRegistry
55import org .codeoverflow .chatoverflow .ui .web .JsonServlet
6- import org .codeoverflow .chatoverflow .ui .web .rest .DTOs .{ ConnectorDetails , ConnectorRef , CredentialsDetails , ResultMessage }
6+ import org .codeoverflow .chatoverflow .ui .web .rest .DTOs ._
77import org .scalatra .swagger .Swagger
88
99import scala .collection .mutable
@@ -102,20 +102,135 @@ class ConnectorController(implicit val swagger: Swagger) extends JsonServlet wit
102102 }
103103 }
104104
105+ get(" /:sourceIdentifier/:qualifiedConnectorType/credentials/:key" , operation(getCredentialsEntry)) {
106+ val key = params(" key" )
107+
108+ if (! chatOverflow.isLoaded) {
109+ CredentialsEntry (found = false )
110+ } else {
111+ val connector = ConnectorRegistry .getConnector(params(" sourceIdentifier" ), params(" qualifiedConnectorType" ))
112+
113+ if (connector.isEmpty) {
114+ CredentialsEntry (found = false )
115+
116+ } else if (! connector.get.areCredentialsSet) {
117+ CredentialsEntry (found = false )
118+
119+ } else if (! connector.get.getCredentials.get.exists(key)) {
120+ CredentialsEntry (found = false )
121+
122+ } else {
123+ val plainValue = connector.get.getCredentials.get.getValue(key).get
124+ val encryptedValue = encryptCredentialsValue(plainValue)
125+
126+ CredentialsEntry (found = true , key, encryptedValue)
127+ }
128+ }
129+ }
130+
131+ post(" /:sourceIdentifier/:qualifiedConnectorType/credentials/" , operation(postCredentialsEntry)) {
132+ parsedAs[EncryptedKeyValuePair ] {
133+ case EncryptedKeyValuePair (key, value) =>
134+ if (! chatOverflow.isLoaded) {
135+ ResultMessage (success = false , " Chat Overflow is not loaded." )
136+
137+ } else {
138+ val connector = ConnectorRegistry .getConnector(params(" sourceIdentifier" ), params(" qualifiedConnectorType" ))
139+
140+ if (connector.isEmpty) {
141+ ResultMessage (success = false , " Connector not found." )
142+
143+ } else if (! connector.get.areCredentialsSet) {
144+ ResultMessage (success = false , " No credentials subobject found." )
145+
146+ } else if (connector.get.isRunning) {
147+ // Should hot swapping be a thing?
148+ ResultMessage (success = false , " Connector is running." )
149+
150+ } else if (! connector.get.getRequiredCredentialKeys.contains(key) &&
151+ ! connector.get.getOptionalCredentialKeys.contains(key)) {
152+ // Note that its only possible to add values to required and optional keys
153+ // Let's not dumb everything into the credentials object please
154+ ResultMessage (success = false , " Key is not required/optional for this connector." )
155+
156+ } else {
157+
158+ val decryptedValue = decryptCredentialsValue(value)
159+
160+ if (decryptedValue.isEmpty) {
161+ ResultMessage (success = false , " Value encrypted with wrong auth key." )
162+
163+ } else if (! connector.get.setCredentialsValue(key, decryptedValue.get)) {
164+ ResultMessage (success = false , " Unable to set credentials value." )
165+
166+ } else {
167+ chatOverflow.save()
168+ ResultMessage (success = true )
169+ }
170+ }
171+ }
172+ }
173+ }
174+
175+ delete(" /:sourceIdentifier/:qualifiedConnectorType/credentials/:key" , operation(deleteCredentialsEntry)) {
176+ parsedAs[AuthKey ] {
177+ case AuthKey (authKey) =>
178+ val key = params(" key" )
179+ val frameworkAuthKey = chatOverflow.credentialsService.generateAuthKey()
180+
181+ if (authKey != frameworkAuthKey) {
182+ ResultMessage (success = false , " Wrong auth key supplied." )
183+ } else {
184+
185+ if (! chatOverflow.isLoaded) {
186+ ResultMessage (success = false , " Chat Overflow is not loaded." )
187+ } else {
188+ val connector = ConnectorRegistry .getConnector(params(" sourceIdentifier" ), params(" qualifiedConnectorType" ))
189+
190+ if (connector.isEmpty) {
191+ ResultMessage (success = false , " Connector not found." )
192+
193+ } else if (! connector.get.areCredentialsSet) {
194+ ResultMessage (success = false , " No credentials subobject found." )
195+
196+ } else if (connector.get.isRunning) {
197+ ResultMessage (success = false , " Connector is running." )
198+
199+ } else if (! connector.get.getCredentials.get.exists(key)) {
200+ ResultMessage (success = false , " Credentials key not found." )
201+
202+ } else {
203+ connector.get.getCredentials.get.removeValue(key)
204+ chatOverflow.save()
205+
206+ ResultMessage (success = true )
207+ }
208+ }
209+ }
210+ }
211+ }
212+
105213 protected def getCredentialsMap (keys : List [String ], credentials : Credentials ): Map [String , String ] = {
106- val authKey = chatOverflow.credentialsService.generateAuthKey()
107214 val credentialsMap = mutable.Map [String , String ]()
108215
109216 for (key <- keys) {
110217 if (credentials.exists(key)) {
111218 val plainValue = credentials.getValue(key).get
112- val encryptedValue = CryptoUtil .encryptSSLcompliant(authKey, plainValue)
113-
114- credentialsMap += key -> encryptedValue
219+ credentialsMap += key -> encryptCredentialsValue(plainValue)
115220 }
116221 }
117222
118223 credentialsMap.toMap
119224 }
120225
226+ protected def encryptCredentialsValue (plainValue : String ): String = {
227+ val authKey = chatOverflow.credentialsService.generateAuthKey()
228+ CryptoUtil .encryptSSLcompliant(authKey, plainValue)
229+ }
230+
231+ protected def decryptCredentialsValue (cipherValue : String ): Option [String ] = {
232+ val authKey = chatOverflow.credentialsService.generateAuthKey()
233+ CryptoUtil .decryptSSLcompliant(authKey, cipherValue)
234+ }
235+
121236}
0 commit comments