Compare commits

..

No commits in common. "92ad1a5cff3987de6f82bf20cdf8334d8a56a09c" and "de3baedf0cfdb0abc5cdf39eec6fc29ee0911b1c" have entirely different histories.

6 changed files with 24 additions and 41 deletions

2
.gitignore vendored
View File

@ -5,5 +5,3 @@
/build/classes/kotlin/jvm/main/ /build/classes/kotlin/jvm/main/
/build/classes/kotlin/jvm/test/ /build/classes/kotlin/jvm/test/
/.idea /.idea
/.kotlin/
/.gigaide/gigaide.properties

View File

@ -1,15 +1,15 @@
plugins { plugins {
kotlin("multiplatform") version "2.1.0" kotlin("multiplatform") version "1.7.21"
kotlin("plugin.serialization") version "2.1.0" kotlin("plugin.serialization") version "1.7.21"
`maven-publish` `maven-publish`
} }
val ktor_version="2.3.12" val ktor_version="2.1.1"
val logback_version="1.2.10" val logback_version="1.2.10"
group = "net.sergeych" group = "net.sergeych"
version = "0.3.1" version = "0.2.6"
repositories { repositories {
mavenCentral() mavenCentral()
@ -51,7 +51,8 @@ kotlin {
val commonMain by getting { val commonMain by getting {
dependencies { dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3")
api("net.sergeych:parsec3:0.5.2") // api("net.sergeych:unikrypto:1.2.2-SNAPSHOT")
api("net.sergeych:parsec3:0.4.6")
api("net.sergeych:unikrypto:1.2.5") api("net.sergeych:unikrypto:1.2.5")
} }
} }

View File

@ -1,2 +1,4 @@
kotlin.code.style=official kotlin.code.style=official
kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=false
kotlin.js.generate.executable.default=false kotlin.js.generate.executable.default=false

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -15,7 +15,8 @@ import net.sergeych.mp_tools.globalLaunch
import net.sergeych.parsec3.* import net.sergeych.parsec3.*
import net.sergeych.superlogin.* import net.sergeych.superlogin.*
import net.sergeych.superlogin.server.SuperloginRestoreAccessPayload import net.sergeych.superlogin.server.SuperloginRestoreAccessPayload
import net.sergeych.unikrypto.* import net.sergeych.unikrypto.SignedRecord
import net.sergeych.unikrypto.SymmetricKey
import kotlin.reflect.KType import kotlin.reflect.KType
import kotlin.reflect.typeOf import kotlin.reflect.typeOf
@ -393,7 +394,7 @@ class SuperloginClient<D, S : WithAdapter>(
aco.payload.dataStorageKey aco.payload.dataStorageKey
) )
// new ACO with a new password key and payload (but the same secret!) // new ACO with a new password key and payload (but the same secret!)
val newAco = aco.updatePasswordKey(keys.loginAccessKey).updatePayload(newSlp) var newAco = aco.updatePasswordKey(keys.loginAccessKey).updatePayload(newSlp)
// trying to update // trying to update
val result = invoke( val result = invoke(
serverApi.slChangePasswordAndLogin, ChangePasswordArgs( serverApi.slChangePasswordAndLogin, ChangePasswordArgs(
@ -421,18 +422,14 @@ class SuperloginClient<D, S : WithAdapter>(
} }
/** /**
* Change password for a logged-in user using its known password. It is a long operation. * Change password for a logged-in user using its known password. It is a long operation
*
* @param oldPassword existing password (re-request it from a user!) * @param oldPassword existing password (re-request it from a user!)
* @param newPassword new password. we do not check it, but it should be strong - check it on your end * @param newPassword new password. we do not chek it but it should be strong - check it on your end
* for example with [net.sergeych.unikrypto.Passwords] tools * for example with [net.sergeych.unikrypto.Passwords] tools
* @param passwordDerivationParams at this point derivation parameters are always updated so it is possible * @param passwordDerivationParams at this point derivation parameters are alwaus updated so it is possible
* to set it to desired * to set it to desired
* @param loginKeyStrength login key is regenerated so its strength could be updated here * @param loginKeyStrength login key is regenerateed so its strength could be updated here
* * @return true if the password has been successfully changed
* @return true if the password has been successfully changed, false if the server didn't allow it.
*
* @throws InvalidPasswordError if the oldPassword is wrong
*/ */
suspend fun changePassword( suspend fun changePassword(
oldPassword: String, newPassword: String, oldPassword: String, newPassword: String,
@ -444,24 +441,10 @@ class SuperloginClient<D, S : WithAdapter>(
val dp = invoke(serverApi.slRequestDerivationParams, loginName) val dp = invoke(serverApi.slRequestDerivationParams, loginName)
val keys = DerivedKeys.derive(oldPassword, dp) val keys = DerivedKeys.derive(oldPassword, dp)
val data = invoke(serverApi.slRequestACOByLoginName, RequestACOByLoginNameArgs(loginName, keys.loginId)) val data = invoke(serverApi.slRequestACOByLoginName, RequestACOByLoginNameArgs(loginName, keys.loginId))
try { return AccessControlObject.unpackWithKey<SuperloginRestoreAccessPayload>(data.packedACO, keys.loginAccessKey)
return AccessControlObject.unpackWithKey<SuperloginRestoreAccessPayload>( ?.let {
data.packedACO, changePasswordWithACO(it, newPassword, passwordDerivationParams, loginKeyStrength)
keys.loginAccessKey } ?: false
)
?.let {
changePasswordWithACO(it, newPassword, passwordDerivationParams, loginKeyStrength)
} ?: false
} catch (e: Exception) {
when (e) {
is Container.StructureError,
is Container.DecryptionError,
is EncryptedBinaryStorage.DecryptionFailed ->
throw InvalidPasswordError()
else -> throw e
}
}
} }

View File

@ -218,15 +218,14 @@ internal class WsServerKtTest {
val api = TestApiServer<WithAdapter>() val api = TestApiServer<WithAdapter>()
val slc = SuperloginClient<TestData, S1>(client) val slc = SuperloginClient<TestData, S1>(client)
assertEquals(LoginState.LoggedOut, slc.state.value) assertEquals(LoginState.LoggedOut, slc.state.value)
var rt = slc.register("foo", "passwd", TestData("bar!"), 2048, 140) var rt = slc.register("foo", "passwd", TestData("bar!"))
val dk1 = slc.dataKey!! val dk1 = slc.dataKey!!
assertIs<Registration.Result.Success>(rt) assertIs<Registration.Result.Success>(rt)
val secret = rt.secret val secret = rt.secret
var token = rt.loginToken var token = rt.loginToken
assertFalse(slc.changePassword("wrong", "new")) assertFalse(slc.changePassword("wrong", "new"))
assertTrue(slc.changePassword("passwd", "newpass1", assertTrue(slc.changePassword("passwd", "newpass1"))
PasswordDerivationParams(300), 2048))
assertTrue { slc.isLoggedIn } assertTrue { slc.isLoggedIn }
assertEquals("foo", slc.call(api.loginName)) assertEquals("foo", slc.call(api.loginName))