Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 17 additions & 8 deletions stdlib/examples/produce-exchange/serverActor.as
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ actor server {
Register a new user, who may play several roles in the exchange.

The given `user_name` must be unique to the exchange; the operation fails otherwise.

*/

registrarAddUser(
Expand All @@ -84,7 +84,7 @@ actor server {
isTransporter
),
{#idErr}
)
)
};

/**
Expand All @@ -108,6 +108,15 @@ actor server {
)
};

/**
`validateUser`
---------------------------
Returns true if the user id matches the public key.
*/
validateUser(public_key: T.PublicKey, id: T.UserId) : async Bool {
getModel().isValidPublicKey(#user(id), public_key);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now wondering if there is some concrete motivation/use case/benefit to exposing this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added passwords to the login page, so the idea is to call validateUser in the login action, and if that returns false, then display a user error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that seems like good reason to have this;
also, the new unit tests are useful, and require exposing such a function, too.


/**
`TruckType`
==============
Expand All @@ -132,14 +141,14 @@ actor server {
getModel()
.truckTypeTable.addInfoGetId(
func (id_:T.TruckTypeId) : T.TruckTypeInfo =

// xxx: AS should have more concise syntax for this pattern, below:
// two problems I see, that are separate:
// 1: repeating the label/variable name, which is the same in each case, twice.
// 2: explicit type annotations, because of "type error, cannot infer type of forward variable ..."
// but two other sources exist for each type: the type of `insert` is known, and hence, this record has a known type,
// and, the type of each of these `variables` is known, as well.

shared {
id=id_ :T.TruckTypeId;
short_name=short_name_:Text;
Expand All @@ -162,7 +171,7 @@ actor server {
Result.fromOption<(),T.IdErr>(
getModel().truckTypeTable.remGetUnit(id),
{#idErr}
)
)
};

/**
Expand Down Expand Up @@ -401,15 +410,15 @@ actor server {
Result.fromOption<T.ProducerInfo,T.IdErr>(
getModel().producerTable.getInfo(id),
{#idErr}
)
)
};

/**
`allProducerInfo`
---------------------
*/

allProducerInfo() : async [T.ProducerInfo] {
allProducerInfo() : async [T.ProducerInfo] {
getModel().producerTable.allInfo()
};

Expand Down Expand Up @@ -461,7 +470,7 @@ actor server {
Result.fromOption<(),T.IdErr>(
getModel().retailerTable.remGetUnit(id),
{#idErr}
)
)
};

/**
Expand Down
7 changes: 7 additions & 0 deletions stdlib/examples/produce-exchange/serverModel.as
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type Result<Ok,Err> = Result.Result<Ok,Err>;
type RouteInventoryMap = Trie<(T.RouteId, T.InventoryId), (M.RouteDoc, M.InventoryDoc)>;

type RoleId = {
#user : T.UserId;
#producer : T.ProducerId;
#transporter : T.TransporterId;
#retailer : T.RetailerId;
Expand All @@ -66,6 +67,12 @@ class Model() {
*/
func isValidPublicKey(id:RoleId, public_key:T.PublicKey) : Bool {
switch id {
case (#user id) {
switch (userTable.getDoc(id)) {
case null false;
case (?p) { p.public_key == public_key };
}
};
case (#producer id) {
switch (producerTable.getDoc(id)) {
case null false;
Expand Down
16 changes: 14 additions & 2 deletions stdlib/examples/produce-exchange/test/simpleSetupAndQuery.as
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,13 @@ actor class Test() = this {

// a double-remove should return null
//assertErr(await s.transporterRemRoute(pkc, assertUnwrapAny<RouteId>(rtc_c_e_tta)));

printEntityCount("Route@time3", (await s.getCounts()).route_count);

//////////////////////////////////////////////////////////////////

print "\nExchange setup: Done.\n====================================\n";

//await debugDumpAll(s);
await debugDumpAll();

Expand All @@ -313,13 +313,25 @@ actor class Test() = this {
printEntityCount("Retailer query", counts.retailer_query_count);
printLabeledCost("Retailer query", counts.retailer_query_cost);

print "\nAuthentication test:\n====================================\n";

print "\npk a == uid a";
assert(await s.validateUser(pka, Result.assertUnwrapAny<T.UserId>(uida)));
print "\npk b == uid b";
assert(await s.validateUser(pkb, Result.assertUnwrapAny<T.UserId>(uidb)));
print "\npk a != uid b";
assert(not(await s.validateUser(pka, Result.assertUnwrapAny<T.UserId>(uidb))));
print "\npk b != uid a";
assert(not(await s.validateUser(pkb, Result.assertUnwrapAny<T.UserId>(uida))));

//////////////////////////////////////////////////////////////////
// xxx --- todo: separate test(s) for expected failures
// User c should not be able to remove user a's route
if false {
print "\nAuthentication test, expect Result.assertion failure:\n";
ignore(await s.transporterRemRoute(pkc, Result.assertUnwrapAny<T.RouteId>(rta_a_c_tta)))
};
print "\n";
})
};
};
Expand Down