Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protocol part of the federation authentication on FE2 #1838

Merged
merged 26 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3c007df
Some messageData added
quadcopterman May 1, 2024
e61e5ea
Added more messageData
quadcopterman May 1, 2024
cfef266
Created ViewModel
quadcopterman May 1, 2024
7e77e9b
Created repository and handler for challenge messages
quadcopterman May 2, 2024
dc0eb50
Send message correctly
quadcopterman May 2, 2024
a767529
Added qr scanner and other elements
quadcopterman May 6, 2024
f0df64b
Debugged scanner, added mechanisms to send federation expect and init
quadcopterman May 6, 2024
b8ecf95
QR code is now displayed correctly, corrected a few other errors
quadcopterman May 6, 2024
b44c5fa
Corrected the used channel
quadcopterman May 13, 2024
d01b559
Resolve merge conflicts
quadcopterman May 13, 2024
f1fd114
Some debugging, sending/receiving Challenge and displaying QR code wo…
quadcopterman May 13, 2024
18aea21
Corrected init and expect messages, wrote some tests
quadcopterman May 15, 2024
260f8ad
Delete fe2-android/app/src/main/java/com/github/dedis/popstellar/plac…
quadcopterman May 15, 2024
c6f7b63
Some more tests
quadcopterman May 15, 2024
3b1308c
Merge remote-tracking branch 'origin/work-fe2-johan-federation' into …
quadcopterman May 15, 2024
36bb77a
Tests for the repository
quadcopterman May 15, 2024
ec32968
Merge branch 'master' into work-fe2-johan-federation
Kaz-ookid May 16, 2024
bb35d98
merged master and adapted for new QR Scanning interface
Kaz-ookid May 16, 2024
be8e199
Subscribed to the federation channel, added tests
quadcopterman May 22, 2024
a82b258
Debugging and tests
quadcopterman May 22, 2024
874e4d2
Added scanning tests
quadcopterman May 22, 2024
17f251c
Added federation exchange qr code
quadcopterman May 23, 2024
5c73373
Little enhancements
quadcopterman May 28, 2024
b21e409
This fix is not working
quadcopterman May 28, 2024
bc4e9df
Reverted last commit and some last little improvements
quadcopterman May 29, 2024
9ae488c
Added more tests for federation home and invite fragments
quadcopterman May 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
matteosz marked this conversation as resolved.
Show resolved Hide resolved
}
}
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
matteosz marked this conversation as resolved.
Show resolved Hide resolved
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
Loading