-- /ivy/binding/hickory/hickoryOwnerImpl.mesa
-- to validate access to the hickory segment.
-- Last edited by: Binding, August 10, 1984 8:53:56 am PDT
DIRECTORY
BasicTime USING [ nullGMT],
DB USING [ Aborted, Relship, RelshipSet, RelationSubset, NextRelship, SetF, GetF, V2S, S2V, ReleaseRelshipSet, MarkTransaction, TransactionOf, T2V, DeclareRelship],
Hickory USING [ Error],
HickoryOwner,
HickorySupport USING [ StartTransaction, RestartTransaction],
HickoryStorage USING [ protData],
Rope USING [ ROPE, Equal]
;
HickoryOwnerImpl:
CEDAR
MONITOR
LOCKS HickoryStorage.protData
IMPORTS HickoryStorage, HickorySupport, DB, Rope, Hickory
EXPORTS HickoryOwner
SHARES HickorySupport
=
BEGIN
OPEN
DB, HickoryStorage.protData, Hickory;
userCredentials: RECORD [ -- cached info
userName: Rope.ROPE ← NIL,
passWord: Rope.ROPE ← NIL
];
VerifyAccess:
PUBLIC
INTERNAL
PROCEDURE [ userName, passWord: Rope.
ROPE]
RETURNS [ owner:
BOOLEAN] =
BEGIN
query the user credentials from data base
OPEN administrativeRel;
rs: RelshipSet;
tuple: Relship;
un, pw: Rope.ROPE;
success: BOOLEAN ← FALSE;
IF userCredentials.userName #
NIL
THEN
RETURN[ userCredentials.passWord = passWord AND userCredentials.userName = userName];
WHILE NOT success DO
ENABLE Aborted => { HickorySupport.RestartTransaction[]; success ← FALSE; LOOP };
HickorySupport.StartTransaction[];
rs ← RelationSubset[ Rel];
tuple ← NextRelship[ rs]; -- there is only one or none
IF tuple =
NIL
THEN
BEGIN
-- it's the very first time we ever access administrativeRel
tuple ← DeclareRelship[ r: Rel, version: NewOnly];
SetF[ tuple, CleanTime, T2V[ LOOPHOLE[ BasicTime.nullGMT]]];
SetF[ tuple, Owner, S2V[ userName]];
SetF[ tuple, PassWord, S2V[ passWord]];
pw ← passWord; un ← userName;
END
ELSE
BEGIN
pw ← V2S[ GetF[ tuple, PassWord]];
un ← V2S[ GetF[ tuple, Owner]];
IF Rope.Equal[ pw, ""]
OR Rope.Equal[ un, ""]
THEN
BEGIN
only CleanTime was set!
SetF[ tuple, Owner, S2V[ userName]];
SetF[ tuple, PassWord, S2V[ passWord]];
pw ← passWord; un ← userName;
END;
END;
ReleaseRelshipSet[ rs];
MarkTransaction[ TransactionOf[ $Hickory]];
success ← TRUE;
ENDLOOP; -- Transaction
userCredentials ← [ un, pw];
RETURN[ Rope.Equal[ un, userName] AND Rope.Equal[ pw, passWord]];
END; -- VerifyAccess
UpdateOwnerInfo:
PUBLIC
ENTRY
PROCEDURE [ userName, passWord: Rope.
ROPE] =
BEGIN
updates passWord value in administrativeRel if the useName is the same as the one that
is stored.
OPEN administrativeRel;
rs: RelshipSet;
tuple: Relship;
un, pw: Rope.ROPE;
success: BOOLEAN ← FALSE;
IF userCredentials.userName # NIL AND NOT Rope.Equal[ userName, userCredentials.userName] THEN ERROR Error[ NotOwner, userName];
WHILE
NOT success
DO
ENABLE DB.Aborted => { HickorySupport.RestartTransaction[]; success ← FALSE; LOOP;};
HickorySupport.StartTransaction[];
rs ← RelationSubset[ Rel];
tuple ← NextRelship[ rs]; -- there is only one or none
IF tuple =
NIL
THEN
BEGIN
-- it's the very first time we ever access administrativeRel
tuple ← DeclareRelship[ r: Rel, version: NewOnly];
SetF[ tuple, CleanTime, T2V[ LOOPHOLE[ BasicTime.nullGMT]]];
SetF[ tuple, Owner, S2V[ userName]];
SetF[ tuple, PassWord, S2V[ passWord]];
HickoryStorage.protData.owner ← TRUE;
END
ELSE
BEGIN
pw ← V2S[ GetF[ tuple, PassWord]];
un ← V2S[ GetF[ tuple, PassWord]];
IF un = userName
AND pw # passWord
THEN
BEGIN
-- password has changed
SetF[ tuple, PassWord, S2V[ passWord]];
userCredentials ← [ un, passWord];
HickoryStorage.protData.owner ← TRUE;
END
ELSE HickoryStorage.protData.owner ← FALSE;
END;
ReleaseRelshipSet[ rs];
MarkTransaction[ TransactionOf[ $Hickory]];
success ← TRUE;
ENDLOOP; -- Transaction
END; -- UpdateOwnerInfoAccess
END.