Skip to content

Commit

Permalink
feat: password generator
Browse files Browse the repository at this point in the history
  • Loading branch information
allape committed Dec 5, 2024
1 parent e3d9b91 commit e7f7c00
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cc.allape.caddyfile.editor.action

import cc.allape.caddyfile.ElementFactory
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import kotlin.random.Random

const val CharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"

class GenerateRandomPasswordIntentionAction : IntentionAction {
override fun startInWriteAction(): Boolean {
return true
}

override fun getFamilyName(): String {
return "Caddyfile password generation"
}

override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean {
return getPasswordArg(editor, file) != null
}

override fun getText(): String {
return "Create a URL-safe random password"
}

override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
if (editor == null || file == null) {
return
}

val ele = getPasswordArg(editor, file) ?: return
val password = ele.text.trim()

val randomPassword =
(1..password.length).map { Random.nextInt(CharSet.length) }.map(CharSet::get).joinToString("")

ele.replace(ElementFactory.createArg(project, randomPassword))
}

override fun generatePreview(project: Project, editor: Editor, file: PsiFile): IntentionPreviewInfo {
return IntentionPreviewInfo.EMPTY
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package cc.allape.caddyfile.editor.action

import cc.allape.caddyfile.language.psi.CaddyfileTypes
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.TokenType
import com.intellij.psi.util.elementType

fun getPasswordArg(editor: Editor?, file: PsiFile?): PsiElement? {
if (editor == null || file == null) {
return null
}

var ele = file.findElementAt(editor.caretModel.offset)

if (ele?.elementType == TokenType.WHITE_SPACE) {
val prevProperty = ele?.prevSibling
if (prevProperty?.elementType == CaddyfileTypes.PROPERTY) {
ele = prevProperty?.lastChild
}
}

if (ele == null) {
return null
}

// property:
// basic_auth
// matcher?
// hash_algorithm?
// block:
// property:
// username
// password

val property = ele.parent
val block = property?.parent
val topProperty = block?.parent

if (
ele.elementType != CaddyfileTypes.ARG ||
property?.elementType != CaddyfileTypes.PROPERTY ||
topProperty?.firstChild?.text != "basic_auth"
) {
return null
}

return ele
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,10 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.TokenType
import com.intellij.psi.util.elementType
import kotlin.random.Random

class HashPasswordIntentionAction : IntentionAction {
private fun getArgElementOrNull(editor: Editor?, file: PsiFile?): PsiElement? {
if (editor == null || file == null) {
return null
}

var ele = file.findElementAt(editor.caretModel.offset)

if (ele?.elementType == TokenType.WHITE_SPACE) {
val prevProperty = ele?.prevSibling
if (prevProperty?.elementType == CaddyfileTypes.PROPERTY) {
ele = prevProperty?.lastChild
}
}

if (ele == null) {
return null
}

// property:
// basic_auth
// matcher?
// hash_algorithm?
// block:
// property:
// username
// password

val property = ele.parent
val block = property?.parent
val topProperty = block?.parent

if (
ele.elementType != CaddyfileTypes.ARG ||
property?.elementType != CaddyfileTypes.PROPERTY ||
topProperty?.firstChild?.text != "basic_auth"
) {
return null
}

return ele
}

override fun startInWriteAction(): Boolean {
return true
}
Expand All @@ -67,7 +22,7 @@ class HashPasswordIntentionAction : IntentionAction {
}

override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean {
return getArgElementOrNull(editor, file) != null
return getPasswordArg(editor, file) != null
}

override fun getText(): String {
Expand All @@ -79,7 +34,7 @@ class HashPasswordIntentionAction : IntentionAction {
return
}

val ele = getArgElementOrNull(editor, file) ?: return
val ele = getPasswordArg(editor, file) ?: return
val property = ele.parent
val block = property?.parent
val topProperty = block?.parent
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,13 @@
<editorFactoryDocumentListener implementation="cc.allape.caddyfile.editor.CaddyfileDocumentListener"/>
<intentionAction>
<language>Caddyfile</language>
<category>Caddyfile/password/hashing</category>
<category>Caddyfile/password/hash</category>
<className>cc.allape.caddyfile.editor.action.HashPasswordIntentionAction</className>
</intentionAction>
<intentionAction>
<language>Caddyfile</language>
<category>Caddyfile/password/generate</category>
<className>cc.allape.caddyfile.editor.action.GenerateRandomPasswordIntentionAction</className>
</intentionAction>
</extensions>
</idea-plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html lang="en">
<body>
Create a URL-safe random password base on the same length of current password.
<pre><code lang="kotlin">
(1..password.length).map { Random.nextInt(CharSet.length) }.map(CharSet::get).joinToString("")
</code></pre>
<!-- tooltip end -->
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
for more information.
<hr>
Tools: <a href="https://github.com/patrickfav/bcrypt">https://github.com/patrickfav/bcrypt</a>
<pre><code>
// language=kotlin
<pre><code lang="kotlin">
BCrypt.withDefaults().hashToString(Random.nextInt(8, 15), password.toCharArray())
</code></pre>
<!-- tooltip end -->
Expand Down
2 changes: 1 addition & 1 deletion src/test/testData/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ a {
abc
}
basic_auth {
bob 12345678
bob O5wTeDsRNyreumNXGEHzQ6QW
}
}

Expand Down

0 comments on commit e7f7c00

Please sign in to comment.