3
3
4
4
package software.aws.toolkits.jetbrains.core.credentials
5
5
6
+ import com.intellij.openapi.application.ApplicationManager
7
+ import com.intellij.openapi.fileEditor.FileDocumentManager
6
8
import software.amazon.awssdk.profiles.Profile
7
9
import software.amazon.awssdk.profiles.ProfileFile
8
10
import software.amazon.awssdk.profiles.ProfileFileLocation
@@ -15,6 +17,8 @@ import software.aws.toolkits.core.utils.touch
15
17
import software.aws.toolkits.core.utils.tryDirOp
16
18
import software.aws.toolkits.core.utils.tryFileOp
17
19
import software.aws.toolkits.core.utils.writeText
20
+ import software.aws.toolkits.jetbrains.core.credentials.profiles.ProfileWatcher
21
+ import software.aws.toolkits.jetbrains.core.credentials.profiles.SsoSessionConstants
18
22
import software.aws.toolkits.jetbrains.core.credentials.profiles.ssoSessions
19
23
import java.nio.file.Path
20
24
@@ -35,6 +39,8 @@ interface ConfigFilesFacade {
35
39
fun appendProfileToCredentials (profile : Profile )
36
40
fun appendSectionToConfig (sectionName : String , profile : Profile )
37
41
fun updateSectionInConfig (sectionName : String , profile : Profile )
42
+
43
+ fun deleteSsoConnectionFromConfig (sessionName : String )
38
44
}
39
45
40
46
class DefaultConfigFilesFacade (
@@ -173,6 +179,86 @@ class DefaultConfigFilesFacade(
173
179
}
174
180
}
175
181
182
+ override fun deleteSsoConnectionFromConfig (sessionName : String ) {
183
+ val filePath = configPath
184
+ val lines = filePath.inputStreamIfExists()?.reader()?.readLines().orEmpty()
185
+ val ssoHeaderLine = lines.indexOfFirst { it.startsWith(" [${SsoSessionConstants .SSO_SESSION_SECTION_NAME } $sessionName ]" ) }
186
+ if (ssoHeaderLine == - 1 ) return
187
+ val nextHeaderLine = lines.subList(ssoHeaderLine + 1 , lines.size).indexOfFirst { it.startsWith(" [" ) }
188
+ val endIndex = if (nextHeaderLine == - 1 ) lines.size else ssoHeaderLine + nextHeaderLine + 1
189
+ val updatedArray = lines.subList(0 , ssoHeaderLine) + lines.subList(endIndex, lines.size)
190
+ val profileHeaderLine = getCorrespondingSsoSessionProfilePosition(updatedArray, sessionName)
191
+ filePath.writeText(profileHeaderLine.joinToString(" \n " ))
192
+
193
+ val applicationManager = ApplicationManager .getApplication()
194
+ if (applicationManager != null && ! applicationManager.isUnitTestMode) {
195
+ FileDocumentManager .getInstance().saveAllDocuments()
196
+ ProfileWatcher .getInstance().forceRefresh()
197
+ }
198
+ }
199
+
200
+ private fun getCorrespondingSsoSessionProfilePosition (updatedArray : List <String >, sessionName : String ): List <String > {
201
+ var content = updatedArray
202
+ val finalContent = mutableListOf<String >()
203
+ while (content.size > 0 ) {
204
+ val sessionProfile = checkIfProfileIsPartOfSession(content, sessionName)
205
+ if (sessionProfile != null ) { // There is atleast one profile with the prefix matching the session name
206
+ if (sessionProfile.shouldBeWrittenToConfig) {
207
+ finalContent.addAll(content.subList(0 , sessionProfile.endIndex))
208
+ } else {
209
+ finalContent.addAll(content.subList(0 , sessionProfile.startIndex))
210
+ }
211
+ content = content.subList(sessionProfile.endIndex, content.size)
212
+ } else {
213
+ finalContent.addAll(content)
214
+ break
215
+ }
216
+ }
217
+ return finalContent
218
+ }
219
+
220
+ private fun checkIfProfileIsPartOfSession (content : List <String >, sessionName : String ): ProfileLimitsInConfig ? {
221
+ val pos = content.indexOfFirst { it.startsWith(" [profile" ) }
222
+ // if no matching profile section found
223
+ if (pos == - 1 ) return null
224
+
225
+ // if matching profile section found which is an sso-profile
226
+ val contentAfterProfileHeader = content.subList(pos + 1 , content.size)
227
+ val checkIfProfileIsValid = isProfileSso(contentAfterProfileHeader, sessionName)
228
+
229
+ return ProfileLimitsInConfig (pos, pos + checkIfProfileIsValid.endIndex + 1 , shouldBeWrittenToConfig = ! checkIfProfileIsValid.isProfileSso)
230
+ }
231
+
232
+ private fun isProfileSso (configContent : List <String >, sessionName : String ): CurrentProfileLimitsInConfig {
233
+ val nextSectionHeaderIndex = configContent.indexOfFirst { it.startsWith(" [" ) }
234
+ val endIndex = if (nextSectionHeaderIndex == - 1 ) configContent.size else nextSectionHeaderIndex
235
+ val currentProfile = configContent.subList(0 , endIndex)
236
+ currentProfile.forEach {
237
+ if (it.startsWith(" sso_session" )) {
238
+ return if (it.substringAfter(" =" ).trim() == sessionName) {
239
+ CurrentProfileLimitsInConfig (isProfileSso = true , endIndex)
240
+ } else {
241
+ CurrentProfileLimitsInConfig (
242
+ isProfileSso = false ,
243
+ endIndex
244
+ )
245
+ }
246
+ }
247
+ }
248
+ return CurrentProfileLimitsInConfig (isProfileSso = false , endIndex)
249
+ }
250
+
251
+ data class ProfileLimitsInConfig (
252
+ val startIndex : Int ,
253
+ val endIndex : Int ,
254
+ val shouldBeWrittenToConfig : Boolean = true
255
+ )
256
+
257
+ data class CurrentProfileLimitsInConfig (
258
+ val isProfileSso : Boolean ,
259
+ val endIndex : Int = 0
260
+ )
261
+
176
262
private fun appendSection (path : Path , sectionName : String , profile : Profile ) {
177
263
val isConfigFile = path.fileName.toString() != " credentials"
178
264
if (sectionName == " sso-session" && ! isConfigFile) {
0 commit comments