Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package sss.openstar.tools
import scorex.crypto.signatures.PublicKey
import sss.ancillary.ByteArrayEncodedStrOps._
import sss.ancillary.Logging
import sss.openstar.MessageKeys
import sss.openstar.account.NodeIdentityManager.PasswordCredentials
import sss.openstar.account.NodeSigner.KeyType
import sss.openstar.account.Ops.MakeTxSigArys
import sss.openstar.account._
import sss.openstar.account.impl.EncryptedKeyFileAccountSignerCreator
import sss.openstar.chains.TxWriterActor.{InternalCommit, InternalTempNack}
import sss.openstar.controller.Utils
import sss.openstar.identityledger.GenericAttributeCategory.PublicKeyIdCategory
import sss.openstar.identityledger.IdentityService.defaultTag
import sss.openstar.identityledger.{Claim, Claim0, GenericAttributeCategory, IdentityLedgerTx, IdentityRoleAttribute, IdentityService, LedgerAttribute, LinkRescuer, SignerVerifierDetails, defaultPaywallCategory}
import sss.openstar.ledger.{LedgerItem, SeqLedgerItem, SignedTxEntry}
import sss.openstar.tools.SendTxSupport.SendTx
import us.monoid.web.Resty
import sss.openstar.identityledger.GenericAttribute
import java.nio.charset.StandardCharsets
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Try}
/**
* Created by alan on 6/7/16.
*/
object ClaimIdentity extends Logging {
case class DeleteKeyFileException(msg: String) extends RuntimeException(msg)
def makeDefaultTagSignerVerifierDetails(
identity: String,
pubKey: PublicKey,
keyType: KeyType): SignerVerifierDetails = {
SignerVerifierDetails(
NodeIdTag(identity), None, TypedPublicKey(pubKey, keyType),
EncryptedKeyFileAccountSignerCreator.SecurityLevel,
EncryptedKeyFileAccountSignerCreator.SignerType,
EncryptedKeyFileAccountSignerCreator.InteractionType
)
}
def claimRemote(
numRetries: Int,
claimUrl: String,
signerVerifierDetails: SignerVerifierDetails): Try[String] = Retry.retry(numRetries, 3.seconds) {
val pkey = signerVerifierDetails.typedPublicKey.publicKey.toBase64Str
val identity = signerVerifierDetails.nodeIdTag.nodeId
require(signerVerifierDetails.nodeIdTag.tag == NodeIdTag.defaultTag, s"Cannot claim using tag ${signerVerifierDetails.nodeIdTag.tag}, must use default tag")
val keyType = signerVerifierDetails.typedPublicKey.keyType
val securityLevel = signerVerifierDetails.securityLevel.toString
val signerType = signerVerifierDetails.signerType
val interactionType = signerVerifierDetails.interactionType
val resty = new Resty(Resty.Option.timeout(2000))
val resultResource = resty.text(s"${claimUrl}console/command?1=claim&2=$identity&3=${pkey}&4=${keyType}&5=${securityLevel}&6=${signerType}&7=${interactionType}")
val result = resultResource.toString
if (result.contains("ok")) {
println(s"Identity $identity is now locked to public key $pkey")
println(s"The public key is identified by tag $defaultTag")
println(s"The private key corresponding to the public key is unlocked by the password you just typed in.")
println(signerVerifierDetails)
} else if (result.contains("fail")) {
println(s"Couldn't register identity $identity - $result")
} else {
println(s"Failed to reach remote claim service ($identity - $result)")
throw new RuntimeException(result)
}
result
}
def claimAndSetupUsingLocalKeyFile(
identity: String,
phrase: String,
rescuers: Set[String], // will be linked as rescuers for the created user
toIdentityLedgerOwner: NodeIdentity => Option[NodeIdentity],
hostingNodeIdentity: NodeIdentity,
keyPersister: KeyPersister,
keyGenerator: AccountKeysFactory,
claimUrl: String,
identityTransactions: List[IdentityLedgerTx] = Nil,
ownedTransactions: List[IdentityLedgerTx] = Nil
)(implicit
nodeIdentityManager: NodeIdentityManager,
sendTx: SendTx,
ec: ExecutionContext
): Future[NodeIdentity] = {
val newNodeIdentity = () => nodeIdentityManager(identity, IdentityService.defaultTag,
Seq(PasswordCredentials(NodeIdTag(identity, IdentityService.defaultTag), phrase)))
keyPersister.keyExists(identity, IdentityService.defaultTag) flatMap {
case true =>
Future.failed(new RuntimeException(s"Identifier=`$identity` is already taken"))
case false =>
val kpGen = () => keyGenerator.createKeyPair()
//creating it here if necessary means it will exist later.
keyPersister.findOrCreate(
identity,
IdentityService.defaultTag,
phrase,
kpGen
).flatMap { keyPair =>
toIdentityLedgerOwner(hostingNodeIdentity) match {
case Some(identityLedgerOwner) =>
val idTag = NodeIdTag(identity, IdentityService.defaultTag)
val priv = keyPair.priv
val pub = keyPair.pub
val claimTx = Claim0(identityLedgerOwner.id, identity, pub)
Utils.simplySignedIdentityLedgerItem(identityLedgerOwner, claimTx) flatMap { claimLedgerItem =>
val newGuySigner = keyGenerator.accountKeysImp.signer(priv)
val identityLedgerItems = (rescuers.toList.map(LinkRescuer(_, identity)) ::: identityTransactions)
.map { item =>
val sig = newGuySigner(item.txId)
val sigs = Seq(idTag.nodeIdBytes, idTag.tagBytes, sig)
val ste = SignedTxEntry(item.toBytes, Seq(sigs).txSig)
LedgerItem(MessageKeys.IdentityLedger, item.txId, ste.toBytes)
}
val ownedLedgerItemsF = Future.sequence(ownedTransactions.map(
Utils.simplySignedIdentityLedgerItem(identityLedgerOwner, _)
))
ownedLedgerItemsF map { ownedLedgerItems =>
Left(claimLedgerItem :: (identityLedgerItems ::: ownedLedgerItems))
}
}
case None =>
val signerVerifierDetails: SignerVerifierDetails =
makeDefaultTagSignerVerifierDetails(identity, keyPair.pub, keyGenerator.keysType)
Future.fromTry(
ClaimIdentity.claimRemote(1, claimUrl, signerVerifierDetails).map(Right(_))
)
}
} flatMap {
case Left(claimAndRest) =>
sendTx(SeqLedgerItem(claimAndRest.head)).whenAvailableLocally.map(_.commitTxResult.internalCommit).flatMap {
case _: InternalCommit if claimAndRest.size > 1 =>
sendTx(SeqLedgerItem(claimAndRest.tail)).whenAvailableLocally.map(_.commitTxResult.internalCommit).flatMap {
case _: InternalCommit =>
newNodeIdentity()
case nack =>
println(s"Failed to fully claim identity=`$identity`, $nack")
newNodeIdentity()
}
case _: InternalCommit =>
newNodeIdentity()
// case nack: InternalTempNack =>
// println(s"Failed to claim identity=`$identity`, temp_nack=$nack")
// Future.failed(DeleteKeyFileException("System temporarily busy, try again."))
case res =>
println(s"Failed to claim identity=`$identity`, result=$res")
//it is possible the someone else will attempt to claim the same identity
//at the same time. If they interleave with this attempt it is possible
//they succeed to get the identity registered on the ledger
//this exception will then cause the keyfile to be deleted locking the
//identity out forever. TODO TODO
Future.failed(DeleteKeyFileException(s"Failed to claim identity=`$identity`"))
}
case Right(res) if !res.contains("fail") =>
Future {
Thread.sleep(5000)
} flatMap (_ => newNodeIdentity())
case x =>
Future.failed(DeleteKeyFileException(s"Failed to claim identity=`$identity` ${x.toString}"))
} andThen {
case Failure(e: DeleteKeyFileException) =>
println(s"Deleting the new keyfile on failure: ${e.getMessage}")
keyPersister.deleteKey(identity, NodeIdTag.defaultTag)
}
}
}
def claim(
claimUrl:String,
details: SignerVerifierDetails,
toIdentityLedgerOwner: NodeIdentity => Option[NodeIdentity],
hostingNodeIdentity: NodeIdentity,
)(implicit
nodeIdentityManager: NodeIdentityManager,
sendTx: SendTx,
ec: ExecutionContext
): Future[NodeIdentity] = {
val identity = details.nodeIdTag.nodeId
require(details.nodeIdTag.tag == NodeIdTag.defaultTag, "Must use default tag to claim")
Future {
toIdentityLedgerOwner(hostingNodeIdentity) match {
case Some(identityLedgerOwner) =>
val claimTx = Claim(identityLedgerOwner.id, identity, details, Seq(IdentityRoleAttribute()))
Utils.simplySignedIdentityLedgerItem(identityLedgerOwner, claimTx) map { claimLedgerItem =>
Left(SeqLedgerItem(claimLedgerItem))
}
case None =>
log.warn("181:CLAIMING REMOTE using only public key, all other signerverifier details will use defaults ")
Future.fromTry(claimRemote(1, claimUrl, details).map(Right(_)))
}
}
.flatten
.flatMap {
case Left(le) =>
sendTx(le).whenAvailableLocally.map(_.commitTxResult.internalCommit).flatMap {
case _: InternalCommit =>
nodeIdentityManager(identity, details.nodeIdTag.tag, Seq.empty)
// case nack: InternalTempNack =>
// println(s"Failed to claim identity=`$identity`, temp_nack=$nack")
// Future.failed(new RuntimeException("System temporarily busy, try again."))
case res =>
println(s"Failed to claim identity=`$identity`, result=$res")
//it is possible the someone else will attempt to claim the same identity
//at the same time. If they interleave with this attempt it is possible
//they succeed to get the identity registered on the ledger
//this exception will then cause the keyfile to be deleted locking the
//identity out forever. TODO TODO
Future.failed(new RuntimeException(s"Failed to claim identity=`$identity`"))
}
case Right(ok) if ok.contains("ok") =>
//It might take some time for the remote txs' to sync to the local.
Future {Thread.sleep(5000L) } flatMap { _ =>
nodeIdentityManager(identity, details.nodeIdTag.tag, Seq.empty)
}
case x =>
Future.failed(new RuntimeException(s"Failed to claim identity=`$identity` ${x.toString}"))
}
}
}