Add PoC of request signing
This commit is contained in:
parent
64b007425f
commit
d85a85235f
16 changed files with 223 additions and 72 deletions
|
@ -2,15 +2,17 @@ public final class io/github/wulkanowy/sdk/hebe/Hebe {
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public final fun getBaseUrl ()Ljava/lang/String;
|
public final fun getBaseUrl ()Ljava/lang/String;
|
||||||
public final fun getDeviceModel ()Ljava/lang/String;
|
public final fun getDeviceModel ()Ljava/lang/String;
|
||||||
|
public final fun getKeyId ()Ljava/lang/String;
|
||||||
public final fun getLogLevel ()Lokhttp3/logging/HttpLoggingInterceptor$Level;
|
public final fun getLogLevel ()Lokhttp3/logging/HttpLoggingInterceptor$Level;
|
||||||
public final fun getPrivateKey ()Ljava/lang/String;
|
public final fun getPrivatePem ()Ljava/lang/String;
|
||||||
public final fun getSchoolSymbol ()Ljava/lang/String;
|
public final fun getSchoolSymbol ()Ljava/lang/String;
|
||||||
public final fun getStudents (Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getStudents (Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public final fun register (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun register (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public final fun setBaseUrl (Ljava/lang/String;)V
|
public final fun setBaseUrl (Ljava/lang/String;)V
|
||||||
public final fun setDeviceModel (Ljava/lang/String;)V
|
public final fun setDeviceModel (Ljava/lang/String;)V
|
||||||
|
public final fun setKeyId (Ljava/lang/String;)V
|
||||||
public final fun setLogLevel (Lokhttp3/logging/HttpLoggingInterceptor$Level;)V
|
public final fun setLogLevel (Lokhttp3/logging/HttpLoggingInterceptor$Level;)V
|
||||||
public final fun setPrivateKey (Ljava/lang/String;)V
|
public final fun setPrivatePem (Ljava/lang/String;)V
|
||||||
public final fun setSchoolSymbol (Ljava/lang/String;)V
|
public final fun setSchoolSymbol (Ljava/lang/String;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,16 +32,20 @@ public final class io/github/wulkanowy/sdk/hebe/exception/UnknownTokenException
|
||||||
public fun <init> (Ljava/lang/String;)V
|
public fun <init> (Ljava/lang/String;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class io/github/wulkanowy/sdk/hebe/register/RegisterResponse {
|
public final class io/github/wulkanowy/sdk/hebe/register/RegisterDevice {
|
||||||
public fun <init> (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
public fun <init> (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||||
public final fun component1 ()I
|
public final fun component1 ()I
|
||||||
public final fun component2 ()Ljava/lang/String;
|
public final fun component2 ()Ljava/lang/String;
|
||||||
public final fun component3 ()Ljava/lang/String;
|
public final fun component3 ()Ljava/lang/String;
|
||||||
public final fun component4 ()Ljava/lang/String;
|
public final fun component4 ()Ljava/lang/String;
|
||||||
public final fun copy (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lio/github/wulkanowy/sdk/hebe/register/RegisterResponse;
|
public final fun component5 ()Ljava/lang/String;
|
||||||
public static synthetic fun copy$default (Lio/github/wulkanowy/sdk/hebe/register/RegisterResponse;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/github/wulkanowy/sdk/hebe/register/RegisterResponse;
|
public final fun component6 ()Ljava/lang/String;
|
||||||
|
public final fun copy (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lio/github/wulkanowy/sdk/hebe/register/RegisterDevice;
|
||||||
|
public static synthetic fun copy$default (Lio/github/wulkanowy/sdk/hebe/register/RegisterDevice;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/github/wulkanowy/sdk/hebe/register/RegisterDevice;
|
||||||
public fun equals (Ljava/lang/Object;)Z
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public final fun getCertificateHash ()Ljava/lang/String;
|
||||||
public final fun getLoginId ()I
|
public final fun getLoginId ()I
|
||||||
|
public final fun getPrivatePem ()Ljava/lang/String;
|
||||||
public final fun getRestUrl ()Ljava/lang/String;
|
public final fun getRestUrl ()Ljava/lang/String;
|
||||||
public final fun getUserLogin ()Ljava/lang/String;
|
public final fun getUserLogin ()Ljava/lang/String;
|
||||||
public final fun getUserName ()Ljava/lang/String;
|
public final fun getUserName ()Ljava/lang/String;
|
||||||
|
|
|
@ -6,11 +6,13 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "io.github.wulkanowy:uonet-request-signer:991de26"
|
implementation 'com.github.wulkanowy.uonet-request-signer:hebe-jvm:5412ed8'
|
||||||
|
|
||||||
implementation "com.brsanthu:migbase64:2.2"
|
implementation "com.brsanthu:migbase64:2.2"
|
||||||
|
|
||||||
implementation libs.retrofit.core
|
implementation libs.retrofit.core
|
||||||
implementation libs.retrofit.scalars
|
implementation libs.retrofit.scalars
|
||||||
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
|
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
|
||||||
|
|
||||||
|
testImplementation "io.mockk:mockk-jvm:1.13.4"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package io.github.wulkanowy.sdk.hebe
|
package io.github.wulkanowy.sdk.hebe
|
||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.ZoneOffset.UTC
|
import java.time.ZoneOffset.UTC
|
||||||
import java.time.format.DateTimeFormatter.ofPattern
|
import java.time.format.DateTimeFormatter.ofPattern
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
|
@Serializable
|
||||||
internal data class ApiRequest<T>(
|
internal data class ApiRequest<T>(
|
||||||
|
|
||||||
@SerialName("API")
|
@SerialName("API")
|
||||||
|
@ -15,7 +17,7 @@ internal data class ApiRequest<T>(
|
||||||
val appName: String = "DzienniczekPlus 2.0",
|
val appName: String = "DzienniczekPlus 2.0",
|
||||||
|
|
||||||
@SerialName("AppVersion")
|
@SerialName("AppVersion")
|
||||||
val appVersion: String = "1.0",
|
val appVersion: String = "1.4.2",
|
||||||
|
|
||||||
@SerialName("CertificateId")
|
@SerialName("CertificateId")
|
||||||
val certificateId: String,
|
val certificateId: String,
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package io.github.wulkanowy.sdk.hebe
|
package io.github.wulkanowy.sdk.hebe
|
||||||
|
|
||||||
import io.github.wulkanowy.sdk.hebe.register.RegisterResponse
|
import io.github.wulkanowy.sdk.hebe.register.RegisterDevice
|
||||||
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
||||||
import io.github.wulkanowy.sdk.hebe.repository.RepositoryManager
|
import io.github.wulkanowy.sdk.hebe.repository.RepositoryManager
|
||||||
|
import io.github.wulkanowy.signer.hebe.generateCertificate
|
||||||
|
import io.github.wulkanowy.signer.hebe.generateKeyPair
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.logging.HttpLoggingInterceptor
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
|
|
||||||
|
@ -16,7 +18,13 @@ class Hebe {
|
||||||
resettableManager.reset()
|
resettableManager.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
var privateKey = ""
|
var keyId = ""
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
resettableManager.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
var privatePem = ""
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
resettableManager.reset()
|
resettableManager.reset()
|
||||||
|
@ -42,20 +50,33 @@ class Hebe {
|
||||||
|
|
||||||
private val interceptors: MutableList<Pair<Interceptor, Boolean>> = mutableListOf()
|
private val interceptors: MutableList<Pair<Interceptor, Boolean>> = mutableListOf()
|
||||||
|
|
||||||
private val serviceManager by resettableLazy(resettableManager) { RepositoryManager(logLevel, privateKey, interceptors, baseUrl, schoolSymbol) }
|
private val serviceManager by resettableLazy(resettableManager) {
|
||||||
|
RepositoryManager(
|
||||||
|
logLevel = logLevel,
|
||||||
|
keyId = keyId,
|
||||||
|
privatePem = privatePem,
|
||||||
|
deviceModel = deviceModel,
|
||||||
|
interceptors = interceptors,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private val routes by resettableLazy(resettableManager) { serviceManager.getRoutesRepository() }
|
private val routes by resettableLazy(resettableManager) { serviceManager.getRoutesRepository() }
|
||||||
|
|
||||||
suspend fun register(privateKey: String, certificateId: String, firebaseToken: String, token: String, pin: String, symbol: String): RegisterResponse {
|
suspend fun register(firebaseToken: String, token: String, pin: String, symbol: String): RegisterDevice {
|
||||||
return serviceManager
|
val (publicPem, privatePem, publicHash) = generateKeyPair()
|
||||||
.getRegisterRepository(routes.getRouteByToken(token), symbol)
|
val (certificatePem, certificateHash) = generateCertificate(privatePem)
|
||||||
.registerDevice(
|
|
||||||
privateKey = privateKey,
|
this.privatePem = privatePem
|
||||||
certificateId = certificateId,
|
this.keyId = certificateHash
|
||||||
deviceModel = deviceModel,
|
|
||||||
|
return serviceManager.getRegisterRepository(routes.getRouteByToken(token), symbol)
|
||||||
|
.register(
|
||||||
firebaseToken = firebaseToken,
|
firebaseToken = firebaseToken,
|
||||||
pin = pin,
|
|
||||||
token = token,
|
token = token,
|
||||||
|
pin = pin,
|
||||||
|
privatePem = privatePem,
|
||||||
|
keyId = keyId,
|
||||||
|
deviceModel = deviceModel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,44 @@
|
||||||
package io.github.wulkanowy.sdk.hebe.interceptor
|
package io.github.wulkanowy.sdk.hebe.interceptor
|
||||||
|
|
||||||
|
import io.github.wulkanowy.signer.hebe.getSignatureHeaders
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
import okio.Buffer
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
internal class SignInterceptor(private val privateKey: String) : Interceptor {
|
internal class SignInterceptor(
|
||||||
|
private val keyId: String,
|
||||||
|
private val privatePem: String,
|
||||||
|
private val deviceModel: String,
|
||||||
|
) : Interceptor {
|
||||||
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
return chain.proceed(chain.request())
|
val original = chain.request()
|
||||||
|
val request = original.newBuilder()
|
||||||
|
|
||||||
|
request.header("UserAgent", "Dart/2.10 (dart:io)")
|
||||||
|
request.header("vOS", "Android")
|
||||||
|
request.header("vDeviceModel", deviceModel)
|
||||||
|
request.header("vAPI", "1")
|
||||||
|
|
||||||
|
if (privatePem.isNotBlank()) {
|
||||||
|
val signatureHeaders = Buffer().run {
|
||||||
|
original.body?.writeTo(this)
|
||||||
|
getSignatureHeaders(
|
||||||
|
keyId = keyId,
|
||||||
|
privatePem = privatePem,
|
||||||
|
body = readString(Charset.defaultCharset()),
|
||||||
|
requestPath = original.url.pathSegments.drop(1).joinToString("/"),
|
||||||
|
timestamp = ZonedDateTime.now(ZoneId.of("GMT")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
signatureHeaders.forEach { (key, value) ->
|
||||||
|
request.header(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chain.proceed(request.method(original.method, original.body).build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package io.github.wulkanowy.sdk.hebe.register
|
||||||
|
|
||||||
|
data class RegisterDevice(
|
||||||
|
val loginId: Int,
|
||||||
|
val restUrl: String,
|
||||||
|
val userLogin: String,
|
||||||
|
val userName: String,
|
||||||
|
val certificateHash: String,
|
||||||
|
val privatePem: String,
|
||||||
|
)
|
|
@ -1,8 +1,10 @@
|
||||||
package io.github.wulkanowy.sdk.hebe.register
|
package io.github.wulkanowy.sdk.hebe.register
|
||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
|
@Serializable
|
||||||
internal data class RegisterRequest(
|
internal data class RegisterRequest(
|
||||||
|
|
||||||
@SerialName("Certificate")
|
@SerialName("Certificate")
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package io.github.wulkanowy.sdk.hebe.register
|
package io.github.wulkanowy.sdk.hebe.register
|
||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
data class RegisterResponse(
|
@Serializable
|
||||||
|
internal data class RegisterResponse(
|
||||||
|
|
||||||
@SerialName("LoginId")
|
@SerialName("LoginId")
|
||||||
val loginId: Int,
|
val loginId: Int,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package io.github.wulkanowy.sdk.hebe.repository
|
package io.github.wulkanowy.sdk.hebe.repository
|
||||||
|
|
||||||
import io.github.wulkanowy.sdk.hebe.ApiRequest
|
import io.github.wulkanowy.sdk.hebe.ApiRequest
|
||||||
|
import io.github.wulkanowy.sdk.hebe.ApiResponse
|
||||||
|
import io.github.wulkanowy.sdk.hebe.register.RegisterDevice
|
||||||
import io.github.wulkanowy.sdk.hebe.register.RegisterRequest
|
import io.github.wulkanowy.sdk.hebe.register.RegisterRequest
|
||||||
import io.github.wulkanowy.sdk.hebe.register.RegisterResponse
|
import io.github.wulkanowy.sdk.hebe.register.RegisterResponse
|
||||||
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
||||||
|
@ -8,14 +10,48 @@ import io.github.wulkanowy.sdk.hebe.service.RegisterService
|
||||||
|
|
||||||
internal class RegisterRepository(private val service: RegisterService) {
|
internal class RegisterRepository(private val service: RegisterService) {
|
||||||
|
|
||||||
suspend fun registerDevice(
|
suspend fun register(
|
||||||
|
firebaseToken: String,
|
||||||
|
token: String,
|
||||||
|
pin: String,
|
||||||
|
deviceModel: String,
|
||||||
|
privatePem: String,
|
||||||
|
keyId: String,
|
||||||
|
): RegisterDevice {
|
||||||
|
val response = registerDevice(
|
||||||
|
privateKey = privatePem,
|
||||||
|
certificateId = keyId,
|
||||||
|
deviceModel = deviceModel,
|
||||||
|
firebaseToken = firebaseToken,
|
||||||
|
pin = pin,
|
||||||
|
token = token,
|
||||||
|
)
|
||||||
|
if (response.envelope == null) {
|
||||||
|
when (response.status.code) {
|
||||||
|
// todo: add more codes
|
||||||
|
else -> error("Unknown error: ${response.status.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val envelope = response.envelope!!
|
||||||
|
return RegisterDevice(
|
||||||
|
loginId = envelope.loginId,
|
||||||
|
restUrl = envelope.restUrl,
|
||||||
|
userLogin = envelope.userLogin,
|
||||||
|
userName = envelope.userName,
|
||||||
|
certificateHash = keyId,
|
||||||
|
privatePem = privatePem,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun registerDevice(
|
||||||
privateKey: String,
|
privateKey: String,
|
||||||
certificateId: String,
|
certificateId: String,
|
||||||
deviceModel: String,
|
deviceModel: String,
|
||||||
firebaseToken: String,
|
firebaseToken: String,
|
||||||
pin: String,
|
pin: String,
|
||||||
token: String,
|
token: String,
|
||||||
): RegisterResponse = service.registerDevice(
|
): ApiResponse<RegisterResponse> = service.registerDevice(
|
||||||
ApiRequest(
|
ApiRequest(
|
||||||
certificateId = certificateId,
|
certificateId = certificateId,
|
||||||
firebaseToken = firebaseToken,
|
firebaseToken = firebaseToken,
|
||||||
|
@ -27,7 +63,7 @@ internal class RegisterRepository(private val service: RegisterService) {
|
||||||
securityToken = token,
|
securityToken = token,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
).envelope!!
|
)
|
||||||
|
|
||||||
suspend fun getStudentInfo(): List<StudentInfo> {
|
suspend fun getStudentInfo(): List<StudentInfo> {
|
||||||
return service.getStudentsInfo().envelope!!
|
return service.getStudentsInfo().envelope!!
|
||||||
|
|
|
@ -15,10 +15,10 @@ import retrofit2.create
|
||||||
|
|
||||||
internal class RepositoryManager(
|
internal class RepositoryManager(
|
||||||
private val logLevel: HttpLoggingInterceptor.Level,
|
private val logLevel: HttpLoggingInterceptor.Level,
|
||||||
private val privateKey: String,
|
private val keyId: String,
|
||||||
|
private val privatePem: String,
|
||||||
|
private val deviceModel: String,
|
||||||
private val interceptors: MutableList<Pair<Interceptor, Boolean>>,
|
private val interceptors: MutableList<Pair<Interceptor, Boolean>>,
|
||||||
private val baseUrl: String,
|
|
||||||
private val schoolSymbol: String,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
@ -33,7 +33,7 @@ internal class RepositoryManager(
|
||||||
|
|
||||||
fun getRoutesRepository(): RoutingRulesRepository {
|
fun getRoutesRepository(): RoutingRulesRepository {
|
||||||
return RoutingRulesRepository(
|
return RoutingRulesRepository(
|
||||||
getRetrofitBuilder(interceptors)
|
getRetrofitBuilder(isJson = false, signInterceptor = false)
|
||||||
.baseUrl("http://komponenty.vulcan.net.pl")
|
.baseUrl("http://komponenty.vulcan.net.pl")
|
||||||
.build()
|
.build()
|
||||||
.create(),
|
.create(),
|
||||||
|
@ -41,31 +41,36 @@ internal class RepositoryManager(
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getRegisterRepository(baseUrl: String, symbol: String): RegisterRepository = getRegisterRepository(
|
internal fun getRegisterRepository(baseUrl: String, symbol: String): RegisterRepository = getRegisterRepository(
|
||||||
"${baseUrl.removeSuffix("/")}/$symbol",
|
baseUrl = "${baseUrl.removeSuffix("/")}/$symbol",
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun getRegisterRepository(baseUrl: String): RegisterRepository = RegisterRepository(
|
private fun getRegisterRepository(baseUrl: String): RegisterRepository = RegisterRepository(
|
||||||
getRetrofitBuilder(interceptors)
|
getRetrofitBuilder(signInterceptor = true)
|
||||||
.baseUrl("${baseUrl.removeSuffix("/")}/api/mobile/register/")
|
.baseUrl("${baseUrl.removeSuffix("/")}/api/mobile/register/")
|
||||||
.build()
|
.build()
|
||||||
.create(),
|
.create(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
private fun getRetrofitBuilder(interceptors: MutableList<Pair<Interceptor, Boolean>>): Retrofit.Builder {
|
private fun getRetrofitBuilder(isJson: Boolean = true, signInterceptor: Boolean): Retrofit.Builder {
|
||||||
return Retrofit.Builder()
|
return Retrofit.Builder()
|
||||||
.addConverterFactory(ScalarsConverterFactory.create())
|
.apply {
|
||||||
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
|
if (isJson) {
|
||||||
|
addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
|
||||||
|
} else addConverterFactory(ScalarsConverterFactory.create())
|
||||||
|
}
|
||||||
.client(
|
.client(
|
||||||
OkHttpClient().newBuilder()
|
OkHttpClient().newBuilder()
|
||||||
.addInterceptor(HttpLoggingInterceptor().setLevel(logLevel))
|
|
||||||
.addInterceptor(ErrorInterceptor())
|
.addInterceptor(ErrorInterceptor())
|
||||||
.addInterceptor(SignInterceptor(privateKey))
|
|
||||||
.apply {
|
.apply {
|
||||||
|
if (signInterceptor) {
|
||||||
|
addInterceptor(SignInterceptor(keyId, privatePem, deviceModel))
|
||||||
|
}
|
||||||
interceptors.forEach {
|
interceptors.forEach {
|
||||||
if (it.second) addNetworkInterceptor(it.first)
|
if (it.second) addNetworkInterceptor(it.first)
|
||||||
else addInterceptor(it.first)
|
else addInterceptor(it.first)
|
||||||
}
|
}
|
||||||
|
addInterceptor(HttpLoggingInterceptor().setLevel(logLevel))
|
||||||
}
|
}
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,13 +5,14 @@ import io.github.wulkanowy.sdk.hebe.ApiResponse
|
||||||
import io.github.wulkanowy.sdk.hebe.register.RegisterRequest
|
import io.github.wulkanowy.sdk.hebe.register.RegisterRequest
|
||||||
import io.github.wulkanowy.sdk.hebe.register.RegisterResponse
|
import io.github.wulkanowy.sdk.hebe.register.RegisterResponse
|
||||||
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
||||||
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
|
|
||||||
internal interface RegisterService {
|
internal interface RegisterService {
|
||||||
|
|
||||||
@POST("new")
|
@POST("new")
|
||||||
suspend fun registerDevice(request: ApiRequest<RegisterRequest>): ApiResponse<RegisterResponse>
|
suspend fun registerDevice(@Body request: ApiRequest<RegisterRequest>): ApiResponse<RegisterResponse>
|
||||||
|
|
||||||
@GET("hebe")
|
@GET("hebe")
|
||||||
suspend fun getStudentsInfo(): ApiResponse<List<StudentInfo>>
|
suspend fun getStudentsInfo(): ApiResponse<List<StudentInfo>>
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package io.github.wulkanowy.sdk.hebe
|
||||||
|
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Ignore
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
class HebeRemoteTest {
|
||||||
|
|
||||||
|
private val hebe = Hebe()
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
with(hebe) {
|
||||||
|
logLevel = HttpLoggingInterceptor.Level.BODY
|
||||||
|
keyId = ""
|
||||||
|
privatePem = ""
|
||||||
|
baseUrl = ""
|
||||||
|
schoolSymbol = ""
|
||||||
|
deviceModel = "Pixel 4a (5G)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `register device`() = runTest {
|
||||||
|
val res = hebe.register(
|
||||||
|
firebaseToken = "###",
|
||||||
|
token = "FK11234",
|
||||||
|
pin = "12334",
|
||||||
|
symbol = "powiatwulkanowy",
|
||||||
|
)
|
||||||
|
println(res)
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ public final class io/github/wulkanowy/sdk/Sdk {
|
||||||
public final fun getAttendanceSummary (Ljava/lang/Integer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getAttendanceSummary (Ljava/lang/Integer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public static synthetic fun getAttendanceSummary$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/lang/Integer;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
public static synthetic fun getAttendanceSummary$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/lang/Integer;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||||
public final fun getBuildTag ()Ljava/lang/String;
|
public final fun getBuildTag ()Ljava/lang/String;
|
||||||
public final fun getCertKey ()Ljava/lang/String;
|
|
||||||
public final fun getClassId ()I
|
public final fun getClassId ()I
|
||||||
public final fun getCompletedLessons (Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getCompletedLessons (Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public static synthetic fun getCompletedLessons$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
public static synthetic fun getCompletedLessons$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||||
|
@ -30,6 +29,7 @@ public final class io/github/wulkanowy/sdk/Sdk {
|
||||||
public final fun getGradesPointsStatistics (ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getGradesPointsStatistics (ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public final fun getGradesSemesterStatistics (ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getGradesSemesterStatistics (ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public final fun getHomework (Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getHomework (Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
public final fun getKeyId ()Ljava/lang/String;
|
||||||
public final fun getKidsLuckyNumbers (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getKidsLuckyNumbers (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public final fun getKidsTimetable (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getKidsTimetable (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public final fun getKindergartenDiaryId ()I
|
public final fun getKindergartenDiaryId ()I
|
||||||
|
@ -52,7 +52,7 @@ public final class io/github/wulkanowy/sdk/Sdk {
|
||||||
public final fun getNotes (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getNotes (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public final fun getPassword ()Ljava/lang/String;
|
public final fun getPassword ()Ljava/lang/String;
|
||||||
public final fun getPasswordResetCaptchaCode (Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getPasswordResetCaptchaCode (Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public final fun getPrivateKey ()Ljava/lang/String;
|
public final fun getPrivatePem ()Ljava/lang/String;
|
||||||
public final fun getReceivedMessages (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getReceivedMessages (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public static synthetic fun getReceivedMessages$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
public static synthetic fun getReceivedMessages$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||||
public final fun getRecipients (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun getRecipients (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
|
@ -85,18 +85,18 @@ public final class io/github/wulkanowy/sdk/Sdk {
|
||||||
public final fun sendPasswordResetRequest (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
public final fun sendPasswordResetRequest (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||||
public final fun setAndroidVersion (Ljava/lang/String;)V
|
public final fun setAndroidVersion (Ljava/lang/String;)V
|
||||||
public final fun setBuildTag (Ljava/lang/String;)V
|
public final fun setBuildTag (Ljava/lang/String;)V
|
||||||
public final fun setCertKey (Ljava/lang/String;)V
|
|
||||||
public final fun setClassId (I)V
|
public final fun setClassId (I)V
|
||||||
public final fun setDiaryId (I)V
|
public final fun setDiaryId (I)V
|
||||||
public final fun setEmail (Ljava/lang/String;)V
|
public final fun setEmail (Ljava/lang/String;)V
|
||||||
public final fun setEmptyCookieJarInterceptor (Z)V
|
public final fun setEmptyCookieJarInterceptor (Z)V
|
||||||
|
public final fun setKeyId (Ljava/lang/String;)V
|
||||||
public final fun setKindergartenDiaryId (I)V
|
public final fun setKindergartenDiaryId (I)V
|
||||||
public final fun setLogLevel (Lokhttp3/logging/HttpLoggingInterceptor$Level;)V
|
public final fun setLogLevel (Lokhttp3/logging/HttpLoggingInterceptor$Level;)V
|
||||||
public final fun setLoginType (Lio/github/wulkanowy/sdk/Sdk$ScrapperLoginType;)V
|
public final fun setLoginType (Lio/github/wulkanowy/sdk/Sdk$ScrapperLoginType;)V
|
||||||
public final fun setMobileBaseUrl (Ljava/lang/String;)V
|
public final fun setMobileBaseUrl (Ljava/lang/String;)V
|
||||||
public final fun setMode (Lio/github/wulkanowy/sdk/Sdk$Mode;)V
|
public final fun setMode (Lio/github/wulkanowy/sdk/Sdk$Mode;)V
|
||||||
public final fun setPassword (Ljava/lang/String;)V
|
public final fun setPassword (Ljava/lang/String;)V
|
||||||
public final fun setPrivateKey (Ljava/lang/String;)V
|
public final fun setPrivatePem (Ljava/lang/String;)V
|
||||||
public final fun setSchoolSymbol (Ljava/lang/String;)V
|
public final fun setSchoolSymbol (Ljava/lang/String;)V
|
||||||
public final fun setSchoolYear (I)V
|
public final fun setSchoolYear (I)V
|
||||||
public final fun setScrapperBaseUrl (Ljava/lang/String;)V
|
public final fun setScrapperBaseUrl (Ljava/lang/String;)V
|
||||||
|
@ -145,7 +145,7 @@ public final class io/github/wulkanowy/sdk/exception/VulcanException : java/io/I
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class io/github/wulkanowy/sdk/mapper/StudentsMapperKt {
|
public final class io/github/wulkanowy/sdk/mapper/StudentsMapperKt {
|
||||||
public static final fun mapHebeUser (Ljava/util/List;Lio/github/wulkanowy/sdk/hebe/register/RegisterResponse;Ljava/lang/String;Ljava/lang/String;)Lio/github/wulkanowy/sdk/pojo/RegisterUser;
|
public static final fun mapHebeUser (Ljava/util/List;Lio/github/wulkanowy/sdk/hebe/register/RegisterDevice;)Lio/github/wulkanowy/sdk/pojo/RegisterUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class io/github/wulkanowy/sdk/pojo/Absent {
|
public final class io/github/wulkanowy/sdk/pojo/Absent {
|
||||||
|
@ -879,10 +879,10 @@ public final class io/github/wulkanowy/sdk/pojo/RegisterSymbol {
|
||||||
public final fun copy (Ljava/lang/String;Ljava/lang/Throwable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)Lio/github/wulkanowy/sdk/pojo/RegisterSymbol;
|
public final fun copy (Ljava/lang/String;Ljava/lang/Throwable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)Lio/github/wulkanowy/sdk/pojo/RegisterSymbol;
|
||||||
public static synthetic fun copy$default (Lio/github/wulkanowy/sdk/pojo/RegisterSymbol;Ljava/lang/String;Ljava/lang/Throwable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;ILjava/lang/Object;)Lio/github/wulkanowy/sdk/pojo/RegisterSymbol;
|
public static synthetic fun copy$default (Lio/github/wulkanowy/sdk/pojo/RegisterSymbol;Ljava/lang/String;Ljava/lang/Throwable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;ILjava/lang/Object;)Lio/github/wulkanowy/sdk/pojo/RegisterSymbol;
|
||||||
public fun equals (Ljava/lang/Object;)Z
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
public final fun getCertificateKey ()Ljava/lang/String;
|
|
||||||
public final fun getError ()Ljava/lang/Throwable;
|
public final fun getError ()Ljava/lang/Throwable;
|
||||||
public final fun getHebeBaseUrl ()Ljava/lang/String;
|
public final fun getHebeBaseUrl ()Ljava/lang/String;
|
||||||
public final fun getPrivateKey ()Ljava/lang/String;
|
public final fun getKeyId ()Ljava/lang/String;
|
||||||
|
public final fun getPrivatePem ()Ljava/lang/String;
|
||||||
public final fun getSchools ()Ljava/util/List;
|
public final fun getSchools ()Ljava/util/List;
|
||||||
public final fun getSymbol ()Ljava/lang/String;
|
public final fun getSymbol ()Ljava/lang/String;
|
||||||
public final fun getUserName ()Ljava/lang/String;
|
public final fun getUserName ()Ljava/lang/String;
|
||||||
|
|
|
@ -104,16 +104,16 @@ class Sdk {
|
||||||
hebe.baseUrl = value
|
hebe.baseUrl = value
|
||||||
}
|
}
|
||||||
|
|
||||||
var certKey = ""
|
var keyId = ""
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
// hebe.certKey = value
|
hebe.keyId = value
|
||||||
}
|
}
|
||||||
|
|
||||||
var privateKey = ""
|
var privatePem = ""
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
hebe.privateKey = privateKey
|
hebe.privatePem = privatePem
|
||||||
}
|
}
|
||||||
|
|
||||||
var scrapperBaseUrl = ""
|
var scrapperBaseUrl = ""
|
||||||
|
@ -268,20 +268,15 @@ class Sdk {
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getStudentsFromHebe(token: String, pin: String, symbol: String, firebaseToken: String): RegisterUser {
|
suspend fun getStudentsFromHebe(token: String, pin: String, symbol: String, firebaseToken: String): RegisterUser {
|
||||||
val privateKey = "" // TODO
|
val registerDevice = hebe.register(
|
||||||
val certificateId = "" // TODO
|
|
||||||
|
|
||||||
val registerResponse = hebe.register(
|
|
||||||
privateKey = privateKey,
|
|
||||||
certificateId = certificateId,
|
|
||||||
firebaseToken = firebaseToken,
|
firebaseToken = firebaseToken,
|
||||||
token = token,
|
token = token,
|
||||||
pin = pin,
|
pin = pin,
|
||||||
symbol = symbol,
|
symbol = symbol,
|
||||||
)
|
)
|
||||||
return hebe
|
return hebe
|
||||||
.getStudents(registerResponse.restUrl, symbol)
|
.getStudents(registerDevice.restUrl, symbol)
|
||||||
.mapHebeUser(registerResponse, certificateId, privateKey)
|
.mapHebeUser(registerDevice)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getStudentsHybrid(
|
suspend fun getStudentsHybrid(
|
||||||
|
@ -316,8 +311,8 @@ class Sdk {
|
||||||
firebaseToken = firebaseToken,
|
firebaseToken = firebaseToken,
|
||||||
)
|
)
|
||||||
symbol.copy(
|
symbol.copy(
|
||||||
certificateKey = hebeUser.symbols.first().certificateKey,
|
keyId = hebeUser.symbols.first().keyId,
|
||||||
privateKey = hebeUser.symbols.first().privateKey,
|
privatePem = hebeUser.symbols.first().privatePem,
|
||||||
hebeBaseUrl = hebeUser.symbols.first().hebeBaseUrl,
|
hebeBaseUrl = hebeUser.symbols.first().hebeBaseUrl,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package io.github.wulkanowy.sdk.mapper
|
package io.github.wulkanowy.sdk.mapper
|
||||||
|
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.sdk.hebe.register.RegisterResponse
|
import io.github.wulkanowy.sdk.hebe.register.RegisterDevice
|
||||||
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
import io.github.wulkanowy.sdk.hebe.register.StudentInfo
|
||||||
import io.github.wulkanowy.sdk.pojo.RegisterEmployee
|
import io.github.wulkanowy.sdk.pojo.RegisterEmployee
|
||||||
import io.github.wulkanowy.sdk.pojo.RegisterStudent
|
import io.github.wulkanowy.sdk.pojo.RegisterStudent
|
||||||
|
@ -31,8 +31,8 @@ internal fun SdkRegisterSymbol.mapSymbol(): RegisterSymbol = RegisterSymbol(
|
||||||
symbol = symbol,
|
symbol = symbol,
|
||||||
userName = userName,
|
userName = userName,
|
||||||
error = error,
|
error = error,
|
||||||
certificateKey = null,
|
keyId = null,
|
||||||
privateKey = null,
|
privatePem = null,
|
||||||
hebeBaseUrl = null,
|
hebeBaseUrl = null,
|
||||||
schools = schools.map { it.mapUnit() },
|
schools = schools.map { it.mapUnit() },
|
||||||
)
|
)
|
||||||
|
@ -73,12 +73,10 @@ internal fun ScrapperRegisterStudent.mapStudent(): RegisterStudent = RegisterStu
|
||||||
)
|
)
|
||||||
|
|
||||||
fun List<StudentInfo>.mapHebeUser(
|
fun List<StudentInfo>.mapHebeUser(
|
||||||
registerResponse: RegisterResponse,
|
device: RegisterDevice,
|
||||||
certificateKey: String,
|
|
||||||
privateKey: String,
|
|
||||||
): RegisterUser = RegisterUser(
|
): RegisterUser = RegisterUser(
|
||||||
email = registerResponse.userName,
|
email = device.userName,
|
||||||
login = registerResponse.userLogin,
|
login = device.userLogin,
|
||||||
scrapperBaseUrl = null,
|
scrapperBaseUrl = null,
|
||||||
loginType = null,
|
loginType = null,
|
||||||
loginMode = Sdk.Mode.HEBE,
|
loginMode = Sdk.Mode.HEBE,
|
||||||
|
@ -88,9 +86,9 @@ fun List<StudentInfo>.mapHebeUser(
|
||||||
RegisterSymbol(
|
RegisterSymbol(
|
||||||
symbol = symbol,
|
symbol = symbol,
|
||||||
error = null,
|
error = null,
|
||||||
certificateKey = certificateKey,
|
keyId = device.certificateHash,
|
||||||
privateKey = privateKey,
|
privatePem = device.privatePem,
|
||||||
hebeBaseUrl = registerResponse.restUrl,
|
hebeBaseUrl = device.restUrl,
|
||||||
userName = students.firstOrNull()?.login?.displayName ?: return@mapNotNull null,
|
userName = students.firstOrNull()?.login?.displayName ?: return@mapNotNull null,
|
||||||
schools = students.mapUnit(),
|
schools = students.mapUnit(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,8 +16,8 @@ data class RegisterSymbol(
|
||||||
val symbol: String,
|
val symbol: String,
|
||||||
val error: Throwable?,
|
val error: Throwable?,
|
||||||
val userName: String,
|
val userName: String,
|
||||||
val certificateKey: String?,
|
val keyId: String?,
|
||||||
val privateKey: String?,
|
val privatePem: String?,
|
||||||
val hebeBaseUrl: String?,
|
val hebeBaseUrl: String?,
|
||||||
val schools: List<RegisterUnit>,
|
val schools: List<RegisterUnit>,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue