Skip to content

Commit

Permalink
Merge pull request #1838 from dedis/work-fe2-johan-federation
Browse files Browse the repository at this point in the history
Protocol part of the federation authentication on FE2
  • Loading branch information
matteosz authored May 29, 2024
2 parents 08b8aab + 9ae488c commit eea305d
Show file tree
Hide file tree
Showing 34 changed files with 1,530 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.github.dedis.popstellar.model.network.method.message.data.election.El
import com.github.dedis.popstellar.model.network.method.message.data.election.ElectionOpen
import com.github.dedis.popstellar.model.network.method.message.data.election.ElectionResult
import com.github.dedis.popstellar.model.network.method.message.data.election.ElectionSetup
import com.github.dedis.popstellar.model.network.method.message.data.federation.Challenge
import com.github.dedis.popstellar.model.network.method.message.data.lao.CreateLao
import com.github.dedis.popstellar.model.network.method.message.data.lao.GreetLao
import com.github.dedis.popstellar.model.network.method.message.data.lao.StateLao
Expand All @@ -39,6 +40,7 @@ import com.github.dedis.popstellar.utility.handler.data.ConsensusHandler
import com.github.dedis.popstellar.utility.handler.data.ElectionHandler
import com.github.dedis.popstellar.utility.handler.data.HandlerContext
import com.github.dedis.popstellar.utility.handler.data.LaoHandler
import com.github.dedis.popstellar.utility.handler.data.LinkedOrganizationsHandler
import com.github.dedis.popstellar.utility.handler.data.MeetingHandler
import com.github.dedis.popstellar.utility.handler.data.ReactionHandler
import com.github.dedis.popstellar.utility.handler.data.RollCallHandler
Expand Down Expand Up @@ -67,7 +69,8 @@ object DataRegistryModule {
chirpHandler: ChirpHandler,
reactionHandler: ReactionHandler,
transactionCoinHandler: TransactionCoinHandler,
witnessMessageHandler: WitnessingHandler
witnessMessageHandler: WitnessingHandler,
linkedOrganizationsHandler: LinkedOrganizationsHandler
): DataRegistry {

val builder = DataRegistry.Builder()
Expand Down Expand Up @@ -249,6 +252,13 @@ object DataRegistryModule {
transactionCoinHandler.handlePostTransactionCoin(context, postTransactionCoin)
}

// Federation
builder.add(Objects.FEDERATION, Action.CHALLENGE, Challenge::class.java) {
context: HandlerContext,
challenge: Challenge ->
linkedOrganizationsHandler.handleChallenge(context, challenge)
}

return builder.build()
}

Expand Down Expand Up @@ -315,6 +325,9 @@ object DataRegistryModule {
// Digital Cash
builder.add(Objects.COIN, Action.POST_TRANSACTION, PostTransactionCoin::class.java, null)

// Federation
builder.add(Objects.FEDERATION, Action.CHALLENGE, Challenge::class.java, null)

return builder.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ enum class Action
KEY("key"),
POST_TRANSACTION("post_transaction"),
AUTH("authenticate"),
CHALLENGE_REQUEST("challenge_request"),
CHALLENGE("challenge"),
INIT("init"),
EXPECT("expect"),
RUMOR("rumor");

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum class Objects
REACTION("reaction"),
COIN("coin"),
POPCHA("popcha"),
FEDERATION("federation"),
GOSSIP("gossip");

/**
Expand All @@ -41,7 +42,7 @@ enum class Objects
COIN.`object`,
MESSAGE.`object` -> true

// Consensus and Popcha are for now the ones excluded from persistence
// Consensus, Popcha and Federation are for now the ones excluded from persistence
else -> false
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.github.dedis.popstellar.model.network.method.message.data.federation

import com.github.dedis.popstellar.model.network.method.message.data.Action
import com.github.dedis.popstellar.model.network.method.message.data.Data
import com.github.dedis.popstellar.model.network.method.message.data.Objects
import com.google.gson.annotations.SerializedName
import kotlin.math.max

/** Challenge sent by the server */
class Challenge
/**
* Constructor for a data Challenge
*
* @param value value of the Challenge (A 32 bytes array encoded in hexadecimal)
* @param validUntil expiration time of the Challenge
*/
(val value: String, validUntil: Long) : Data {
@SerializedName("valid_until") val validUntil: Long

init {
this.validUntil = max(0L, validUntil)
}

override val `object`: String
get() = Objects.FEDERATION.`object`

override val action: String
get() = Action.CHALLENGE.action

override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null || javaClass != other.javaClass) {
return false
}
val that = other as Challenge
return value == that.value && validUntil == that.validUntil
}

override fun hashCode(): Int {
return java.util.Objects.hash(value, validUntil)
}

override fun toString(): String {
return "Challenge{value='$value', valid_until='$validUntil'}"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.github.dedis.popstellar.model.network.method.message.data.federation

import com.github.dedis.popstellar.model.Immutable
import com.github.dedis.popstellar.model.network.method.message.data.Action
import com.github.dedis.popstellar.model.network.method.message.data.Data
import com.github.dedis.popstellar.model.network.method.message.data.Objects

/** Data sent to get a challenge */
@Immutable
class ChallengeRequest
/**
* Constructor for a data Challenge Request
*
* @param timestamp time of the Challenge Request
*/
(val timestamp: Long) : Data {

override val `object`: String
get() = Objects.FEDERATION.`object`

override val action: String
get() = Action.CHALLENGE_REQUEST.action

override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null || javaClass != other.javaClass) {
return false
}
val that = other as ChallengeRequest
return timestamp == that.timestamp
}

override fun hashCode(): Int {
return java.util.Objects.hash(timestamp)
}

override fun toString(): String {
return "ChallengeRequest{timestamp='$timestamp'}"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.github.dedis.popstellar.model.network.method.message.data.federation

import com.github.dedis.popstellar.model.network.method.message.MessageGeneral
import com.github.dedis.popstellar.model.network.method.message.data.Action
import com.github.dedis.popstellar.model.network.method.message.data.Data
import com.github.dedis.popstellar.model.network.method.message.data.Objects
import com.google.gson.annotations.SerializedName

/** Federation Expect message */
class FederationExpect
/**
* Constructor for a data Federation Expect
*
* @param laoId ID of the remote LAO
* @param serverAddress public address of the remote organizer server
* @param publicKey public key of the remote organizer
* @param challenge challenge for the server
*/
(
@SerializedName("lao_id") val laoId: String,
@SerializedName("server_address") val serverAddress: String,
@SerializedName("public_key") val publicKey: String,
val challenge: MessageGeneral
) : Data {

override val `object`: String
get() = Objects.FEDERATION.`object`

override val action: String
get() = Action.EXPECT.action

override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null || javaClass != other.javaClass) {
return false
}
val that = other as FederationExpect
return laoId == that.laoId &&
serverAddress == that.serverAddress &&
publicKey == that.publicKey &&
challenge == that.challenge
}

override fun hashCode(): Int {
return java.util.Objects.hash(laoId, serverAddress, publicKey, challenge)
}

override fun toString(): String {
return "FederationExpect{lao_id='$laoId', server_address='$serverAddress'," +
"public_key='$publicKey', challenge='$challenge'}"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.github.dedis.popstellar.model.network.method.message.data.federation

import com.github.dedis.popstellar.model.network.method.message.MessageGeneral
import com.github.dedis.popstellar.model.network.method.message.data.Action
import com.github.dedis.popstellar.model.network.method.message.data.Data
import com.github.dedis.popstellar.model.network.method.message.data.Objects
import com.google.gson.annotations.SerializedName

/** Initiates a federation link */
class FederationInit
/**
* Constructor for a data Federation Init
*
* @param laoId ID of the remote LAO
* @param serverAddress public address of the remote organizer server
* @param publicKey public key of the remote organizer
* @param challenge challenge from the other server
*/
(
@SerializedName("lao_id") val laoId: String,
@SerializedName("server_address") val serverAddress: String,
@SerializedName("public_key") val publicKey: String,
val challenge: MessageGeneral
) : Data {

override val `object`: String
get() = Objects.FEDERATION.`object`

override val action: String
get() = Action.INIT.action

override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other == null || javaClass != other.javaClass) {
return false
}
val that = other as FederationInit
return laoId == that.laoId &&
serverAddress == that.serverAddress &&
publicKey == that.publicKey &&
challenge == that.challenge
}

override fun hashCode(): Int {
return java.util.Objects.hash(laoId, serverAddress, publicKey, challenge)
}

override fun toString(): String {
return "FederationInit{lao_id='$laoId', server_address='$serverAddress'," +
"public_key='$publicKey', challenge='$challenge'}"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ object JsonUtils {
const val CONNECT_TO_LAO_SCHEMA = "protocol/qrcode/connect_to_lao.json"
const val POP_TOKEN_SCHEME = "protocol/qrcode/pop_token.json"
const val MAIN_PK_SCHEME = "protocol/qrcode/main_public_key.json"
const val FEDERATION_DETAILS = "protocol/qrcode/federation_exchange.json"

private val schemas: MutableMap<String, JsonSchema> = ConcurrentHashMap()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.github.dedis.popstellar.model.qrcode

import com.github.dedis.popstellar.model.Immutable
import com.github.dedis.popstellar.model.network.method.message.data.federation.Challenge
import com.github.dedis.popstellar.model.network.serializer.JsonUtils
import com.google.gson.Gson
import com.google.gson.annotations.SerializedName

@Immutable
class FederationDetails(
@field:SerializedName("lao_id") val laoId: String,
@field:SerializedName("server_address") val serverAddress: String,
@field:SerializedName("public_key") val publicKey: String,
val challenge: Challenge? = null
) {

companion object {
/**
* Extract data from the given json string
*
* @param gson is used to parse the json string into the object
* @param json representation of the data
* @return the extracted data
* @throws com.google.gson.JsonParseException if the value cannot be parsed
*/
@JvmStatic
fun extractFrom(gson: Gson, json: String?): FederationDetails {
JsonUtils.verifyJson(JsonUtils.FEDERATION_DETAILS, json)

return gson.fromJson(json, FederationDetails::class.java)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.github.dedis.popstellar.repository

import com.github.dedis.popstellar.model.network.method.message.data.federation.Challenge
import javax.inject.Inject
import javax.inject.Singleton

/**
* This class is the repository of federation
*
* Its main purpose is to store received messages
*/
@Singleton
class LinkedOrganizationsRepository @Inject constructor() {
private var challenge: Challenge? = null
private var onChallengeUpdatedCallback: ((Challenge) -> Unit)? = null
var otherLaoId: String? = null
var otherServerAddr: String? = null
var otherPublicKey: String? = null

/**
* Updates the challenge
*
* @param challenge the new Challenge
*/
fun updateChallenge(challenge: Challenge) {
this.challenge = challenge
onChallengeUpdatedCallback?.invoke(challenge)
}

fun setOnChallengeUpdatedCallback(callback: (Challenge) -> Unit) {
onChallengeUpdatedCallback = callback
}

fun getChallenge(): Challenge? {
return challenge
}

fun flush() {
otherLaoId = null
otherServerAddr = null
otherPublicKey = null
challenge = null
onChallengeUpdatedCallback = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.github.dedis.popstellar.ui.lao.event.eventlist.EventListFragment
import com.github.dedis.popstellar.ui.lao.event.meeting.MeetingViewModel
import com.github.dedis.popstellar.ui.lao.event.rollcall.RollCallViewModel
import com.github.dedis.popstellar.ui.lao.federation.LinkedOrganizationsFragment
import com.github.dedis.popstellar.ui.lao.federation.LinkedOrganizationsViewModel
import com.github.dedis.popstellar.ui.lao.popcha.PoPCHAHomeFragment
import com.github.dedis.popstellar.ui.lao.popcha.PoPCHAViewModel
import com.github.dedis.popstellar.ui.lao.socialmedia.SocialMediaHomeFragment
Expand Down Expand Up @@ -434,6 +435,19 @@ class LaoActivity : AppCompatActivity() {
return popCHAViewModel
}

@JvmStatic
fun obtainLinkedOrganizationsViewModel(
activity: FragmentActivity,
laoId: String?
): LinkedOrganizationsViewModel {
val linkedOrganizationsViewModel =
ViewModelProvider(activity)[LinkedOrganizationsViewModel::class.java]
if (laoId != null) {
linkedOrganizationsViewModel.setLaoId(laoId)
}
return linkedOrganizationsViewModel
}

/**
* Set the current fragment in the container of the activity
*
Expand Down
Loading

0 comments on commit eea305d

Please sign in to comment.