Skip to content

Commit

Permalink
Merge pull request #2 from danmanirl/master
Browse files Browse the repository at this point in the history
add support for gnome-keyring
  • Loading branch information
aleksandr-vin committed Mar 2, 2021
2 parents 35c98b9 + b9687a8 commit 2470b7f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 18 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
## SBT Keychain Credentials Plugin

This plugin adds `com.xvyg.keychain.Credentials` object _(of the same name as `sbt.Credentials`)_,
bringing capability of obtaining password from Mac OS X Keychain.
bringing capability of obtaining password from the system keychain, the following keychains are supported:
* Mac OS X Keychain
* GNOME's `gnome-keyring` and its companion `secret-tool`

### Use Case

Expand Down Expand Up @@ -29,7 +31,7 @@ and these lines to your _~/.sbt/1.0/global.sbt_ (with your own path to credentia

import com.xvyg.sbt.keychain.Credentials

credentials ++= Seq(Credentials(Path.userHome / ".ivy2" / ".credentials", sLog.value))
credentials ++= Seq(Credentials(Path.userHome / ".ivy2" / ".credentials", sLog.value, Credentials.MAC))

This will place credentials with password, obtained from your system's keychain, somewhere
close to the head of `credentials` list. So everywhere in your project, where you have
Expand Down
33 changes: 25 additions & 8 deletions src/main/scala-sbt-0.13/com/xvyg/sbt/keychain/Credentials.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,29 @@ package com.xvyg.sbt.keychain

import java.io.FileInputStream
import java.util.Properties

import scala.util.{Failure, Success, Try}
import sys.process.Process

object Credentials {

def apply(file: java.io.File, logger: sbt.Logger = Credentials.Logger): sbt.Credentials = {
sealed trait KeychainType {
def command(user: String, host: String): String
def createMessage(user: String, host: String, realm: String): String
def errorMessage: String
}
case object MAC extends KeychainType {
override def command(user:String, host: String) = s"security find-generic-password -a $user -s $host -w"
override def createMessage(user: String, host: String, realm: String) = s"security add-generic-password -a $user -s $host -w"
override val errorMessage = "Problem occurred while obtaining password from system's keychain"
}
case object GNOME extends KeychainType {
override def command(user:String, host: String) = s"secret-tool lookup $host $user"
override def createMessage(user: String, host: String, realm: String) = s"secret-tool store --label '$realm' $host $user"
override val errorMessage = "Problem occurred while obtaining password from system's keychain, make sure that 'secret-tool' is installed"
}

def apply(file: java.io.File, logger: sbt.Logger = Credentials.Logger, keychainType: KeychainType = MAC): sbt.Credentials = {
logger.info(s"Reading credentials from $file ...")
val (realm, host, user, password) =
try {
Expand All @@ -25,12 +43,11 @@ object Credentials {
}
if (password == null || password.trim == "") {
logger.info("Obtaining password from system's keychain ...")
val process = Process(s"security find-generic-password -a $user -s $host -w").lines_!
if (process.length == 1) {
sbt.Credentials(realm, host, user, process.head)
} else {
logger.error("Problem occurred while obtaining password from system's keychain")
sys.exit(1)
Try(Process(keychainType.command(user, host)).lineStream_!) match {
case Success(p) if p.length == 1 => sbt.Credentials(realm, host, user, p.head)
case Failure(_) | Success(_) =>
logger.error(keychainType.errorMessage)
sys.exit(1)
}
} else {
logger.warn("")
Expand All @@ -41,7 +58,7 @@ object Credentials {
logger.warn(" Consider removing it from that file and storing in system's Keychain.")
logger.warn(" You can use the command below for this:")
logger.warn("")
logger.warn(s" security add-generic-password -a $user -s $host -w")
logger.warn(s" ${keychainType.createMessage(user, host, realm)}")
logger.warn("************************************************************************")
logger.warn("")
sbt.Credentials(realm, host, user, password)
Expand Down
33 changes: 25 additions & 8 deletions src/main/scala-sbt-1.0/com/xvyg/sbt/keychain/Credentials.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,29 @@ package com.xvyg.sbt.keychain

import java.io.FileInputStream
import java.util.Properties

import scala.util.{Failure, Success, Try}
import sys.process.Process

object Credentials {

def apply(file: java.io.File, logger: sbt.Logger = Credentials.Logger): sbt.Credentials = {
sealed trait KeychainType {
def command(user: String, host: String): String
def createMessage(user: String, host: String, realm: String): String
def errorMessage: String
}
case object MAC extends KeychainType {
override def command(user:String, host: String) = s"security find-generic-password -a $user -s $host -w"
override def createMessage(user: String, host: String, realm: String) = s"security add-generic-password -a $user -s $host -w"
override val errorMessage = "Problem occurred while obtaining password from system's keychain"
}
case object GNOME extends KeychainType {
override def command(user:String, host: String) = s"secret-tool lookup $host $user"
override def createMessage(user: String, host: String, realm: String) = s"secret-tool store --label '$realm' $host $user"
override val errorMessage = "Problem occurred while obtaining password from system's keychain, make sure that 'secret-tool' is installed"
}

def apply(file: java.io.File, logger: sbt.Logger = Credentials.Logger, keychainType: KeychainType = MAC): sbt.Credentials = {
logger.info(s"Reading credentials from $file ...")
val (realm, host, user, password) =
try {
Expand All @@ -25,12 +43,11 @@ object Credentials {
}
if (password == null || password.trim == "") {
logger.info("Obtaining password from system's keychain ...")
val process = Process(s"security find-generic-password -a $user -s $host -w").lineStream_!
if (process.length == 1) {
sbt.Credentials(realm, host, user, process.head)
} else {
logger.error("Problem occurred while obtaining password from system's keychain")
sys.exit(1)
Try(Process(keychainType.command(user, host)).lineStream) match {
case Success(p) if p.length == 1 => sbt.Credentials(realm, host, user, p.head)
case Failure(_) | Success(_) =>
logger.error(keychainType.errorMessage)
sys.exit(1)
}
} else {
logger.warn("")
Expand All @@ -41,7 +58,7 @@ object Credentials {
logger.warn(" Consider removing it from that file and storing in system's Keychain.")
logger.warn(" You can use the command below for this:")
logger.warn("")
logger.warn(s" security add-generic-password -a $user -s $host -w")
logger.warn(s" ${keychainType.createMessage(user, host, realm)}")
logger.warn("************************************************************************")
logger.warn("")
sbt.Credentials(realm, host, user, password)
Expand Down

0 comments on commit 2470b7f

Please sign in to comment.