-- /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: BOOLEANFALSE;
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.