<div dir="ltr"><div dir="auto">HI.</div><div dir="auto"><br></div><div dir="auto">Could someone that has used ServerDirectory verifies it still works with this change?  The rest of the changes I've burned in for a couple of months, but never having used ServerDirectory (and being confused by it, too), I haven't verified that part.  It *should* continue to work without issues.</div><div dir="auto"><br></div><div dir="auto">Thanks,</div><div dir="auto">cbc<br><div dir="auto"><br></div></div></div><br><div class="gmail_quote"><div class="gmail_attr" dir="ltr">On Fri, Jun 7, 2019, 12:56  <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">Chris Cunningham uploaded a new version of Network to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Network-cbc.234.mcz" target="_blank" rel="noreferrer noreferrer">http://source.squeak.org/inbox/Network-cbc.234.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Network-cbc.234<br>
Author: cbc<br>
Time: 7 June 2019, 12:56:17.741581 pm<br>
UUID: a2081791-f54f-40fd-bd59-b8da1d52265d<br>
Ancestors: Network-pre.233<br>
<br>
Password was very specific for ServerDirectory.<br>
Re-factor Password into a more generic password holder (usuable in other classes).<br>
Create ServerPassword as a sub-class of Password with necessary specilizations moved down to it.<br>
Make ServcieDirectory point to ServerPassword.<br>
<br>
This allows us to use Password generally to store a password in memory (encoded) during a Squeak session, which is cleared out when saving.  The intended use case is to not store passwords in code or in the file system - instead prompt the user at first use and cache it for the rest of the life of the session.<br>
<br>
=============== Diff against Network-pre.233 ===============<br>
<br>
Item was changed:<br>
  Object subclass: #Password<br>
+       instanceVariableNames: 'cache'<br>
-       instanceVariableNames: 'cache sequence'<br>
        classVariableNames: ''<br>
        poolDictionaries: ''<br>
        category: 'Network-Kernel'!<br>
<br>
+ !Password commentStamp: 'cbc 6/7/2019 11:19' prior: 0!<br>
+ "Hold a password in memory during a run of the app.<br>
- !Password commentStamp: 'pre 12/11/2018 15:53' prior: 0!<br>
- "Hold a password.  There are three ways to get the password.<br>
<br>
+ After each save (after each startup), when an applicaiton asks for a password, one of two things will happen:<br>
+   1> the user will be prompted for the password<br>
+   2> If the user was previously prompted, return that password<br>
- If there is no password (sequence == nil), ask the user for it.<br>
<br>
+ Passwords are stored encoded.<br>
+ At shutDown, passwords are cleared (will not be written to disc).<br>
- If the user supplied one during this session, return that.  It is cleared at shutDown.<br>
<br>
+ The intent for this class is to avoid storing passwords in code or on files on the system.  Instead, prompt the user during the running of the application."!<br>
- If sequence is a number, get the server passwords off the disk.  File '<a href="http://sqk.info" target="_blank" rel="noreferrer noreferrer">sqk.info</a>' must be in the same folder 'Squeak.sources' file.  Decode the file.  Return the password indexed by sequence."!<br>
<br>
Item was changed:<br>
  ----- Method: Password>>cache: (in category 'accessing') -----<br>
  cache: anObject<br>
+       "if anObject is nil, then clear out cache - don't store values to disc"<br>
+       anObject ifNil: [^cache := nil].<br>
+       "Otherwise, 'encode' (trivially) the password while it resides in memory - no plain text"<br>
+       cache := self decode: anObject!<br>
-       cache := anObject!<br>
<br>
Item was removed:<br>
- ----- Method: Password>>passwordFor: (in category 'accessing') -----<br>
- passwordFor: serverDir<br>
-       "Returned the password from one of many sources.  OK if send in a nil arg."<br>
- <br>
-       | sp msg |<br>
-       cache ifNotNil: [^ cache].<br>
-       sequence ifNotNil: [<br>
-               (sp := self serverPasswords) ifNotNil: [<br>
-                       sequence <= sp size ifTrue: [^ sp at: sequence]]].<br>
-       msg := serverDir isRemoteDirectory<br>
-               ifTrue: [serverDir moniker]<br>
-               ifFalse: ['this directory'].<br>
-       (serverDir user = 'anonymous') & (serverDir typeWithDefault == #ftp) ifTrue: [<br>
-                       ^ cache := UIManager default request: 'Please let this anonymous ftp\server know your email address.\This is the polite thing to do.' withCRs<br>
-                       initialAnswer: '<a href="mailto:yourName@company.com" target="_blank" rel="noreferrer">yourName@company.com</a>'].<br>
- <br>
-       ^ cache := UIManager default requestPassword: 'Password for ', serverDir user, ' at ', msg, ':'.<br>
-               "Diff between empty string and abort?"!<br>
<br>
Item was added:<br>
+ ----- Method: Password>>passwordForMessage: (in category 'accessing') -----<br>
+ passwordForMessage: msg<br>
+       cache ifNotNil: [^self decode: cache]. "Our stored value is encoded"<br>
+       ^self decode: (cache := self decode: (UIManager default requestPassword: 'Password for ', msg, ':')).!<br>
<br>
Item was removed:<br>
- ----- Method: Password>>sequence (in category 'accessing') -----<br>
- sequence<br>
-       ^sequence!<br>
<br>
Item was removed:<br>
- ----- Method: Password>>sequence: (in category 'accessing') -----<br>
- sequence: anNumber<br>
-       sequence := anNumber!<br>
<br>
Item was removed:<br>
- ----- Method: Password>>serverPasswords (in category 'accessing') -----<br>
- serverPasswords<br>
-       "Get the server passwords off the disk and decode them. The file '<a href="http://sqk.info" target="_blank" rel="noreferrer noreferrer">sqk.info</a>' must be in some folder that Squeak thinks is special (vm folder, or default directory).  (Note: This code works even if you are running with no system sources file.)"<br>
- <br>
-       | sfile |<br>
-       (sfile := FileDirectory lookInUsualPlaces: '<a href="http://sqk.info" target="_blank" rel="noreferrer noreferrer">sqk.info</a>') ifNil: [^ nil].<br>
-               "If not there, Caller will ask user for password"<br>
-               "If you don't have this file, and you really do want to release an update, <br>
-                contact Ted Kaehler."<br>
-       ^ (self decode: (sfile contentsOfEntireFile)) lines<br>
- !<br>
<br>
Item was changed:<br>
  ----- Method: ServerDirectory>>password (in category 'accessing') -----<br>
  password<br>
<br>
+       passwordHolder ifNil: [passwordHolder := ServerPassword new].<br>
-       passwordHolder ifNil: [passwordHolder := Password new].<br>
        ^ passwordHolder passwordFor: self      "may ask the user"!<br>
<br>
Item was changed:<br>
  ----- Method: ServerDirectory>>password: (in category 'accessing') -----<br>
  password: pp<br>
<br>
+       passwordHolder := ServerPassword new.<br>
-       passwordHolder := Password new.<br>
        pp isString <br>
                ifTrue: [passwordHolder cache: pp. ^ self].<br>
        pp isInteger <br>
                ifTrue: [passwordHolder sequence: pp]<br>
                ifFalse: [passwordHolder := pp].!<br>
<br>
Item was changed:<br>
  ----- Method: ServerDirectory>>passwordSequence: (in category 'accessing') -----<br>
  passwordSequence: aNumber<br>
<br>
+       passwordHolder ifNil: [passwordHolder := ServerPassword new].<br>
-       passwordHolder ifNil: [passwordHolder := Password new].<br>
        passwordHolder sequence: aNumber!<br>
<br>
Item was added:<br>
+ Password subclass: #ServerPassword<br>
+       instanceVariableNames: 'sequence'<br>
+       classVariableNames: ''<br>
+       poolDictionaries: ''<br>
+       category: 'Network-Kernel'!<br>
+ <br>
+ !ServerPassword commentStamp: 'cbc 6/7/2019 11:15' prior: 0!<br>
+ "Hold a password.  There are three ways to get the password.<br>
+ <br>
+ If there is no password (sequence == nil), ask the user for it.<br>
+ <br>
+ If the user supplied one during this session, return that.  It is cleared at shutDown.<br>
+ <br>
+ If sequence is a number, get the server passwords off the disk.  File '<a href="http://sqk.info" target="_blank" rel="noreferrer noreferrer">sqk.info</a>' must be in the same folder 'Squeak.sources' file.  Decode the file.  Return the password indexed by sequence."!<br>
<br>
Item was added:<br>
+ ----- Method: ServerPassword>>cache: (in category 'accessing') -----<br>
+ cache: anObject<br>
+       cache := anObject!<br>
<br>
Item was added:<br>
+ ----- Method: ServerPassword>>passwordFor: (in category 'accessing') -----<br>
+ passwordFor: serverDir<br>
+       "Returned the password from one of many sources.  OK if send in a nil arg."<br>
+ <br>
+       | sp msg |<br>
+       cache ifNotNil: [^ cache].<br>
+       sequence ifNotNil: [<br>
+               (sp := self serverPasswords) ifNotNil: [<br>
+                       sequence <= sp size ifTrue: [^ sp at: sequence]]].<br>
+       msg := serverDir isRemoteDirectory<br>
+               ifTrue: [serverDir moniker]<br>
+               ifFalse: ['this directory'].<br>
+       (serverDir user = 'anonymous') & (serverDir typeWithDefault == #ftp) ifTrue: [<br>
+                       ^ cache := UIManager default request: 'Please let this anonymous ftp\server know your email address.\This is the polite thing to do.' withCRs<br>
+                       initialAnswer: '<a href="mailto:yourName@company.com" target="_blank" rel="noreferrer">yourName@company.com</a>'].<br>
+ <br>
+       ^ cache := UIManager default requestPassword: 'Password for ', serverDir user, ' at ', msg, ':'.<br>
+               "Diff between empty string and abort?"!<br>
<br>
Item was added:<br>
+ ----- Method: ServerPassword>>sequence (in category 'accessing') -----<br>
+ sequence<br>
+       ^sequence!<br>
<br>
Item was added:<br>
+ ----- Method: ServerPassword>>sequence: (in category 'accessing') -----<br>
+ sequence: anNumber<br>
+       sequence := anNumber!<br>
<br>
Item was added:<br>
+ ----- Method: ServerPassword>>serverPasswords (in category 'accessing') -----<br>
+ serverPasswords<br>
+       "Get the server passwords off the disk and decode them. The file '<a href="http://sqk.info" target="_blank" rel="noreferrer noreferrer">sqk.info</a>' must be in some folder that Squeak thinks is special (vm folder, or default directory).  (Note: This code works even if you are running with no system sources file.)"<br>
+ <br>
+       | sfile |<br>
+       (sfile := FileDirectory lookInUsualPlaces: '<a href="http://sqk.info" target="_blank" rel="noreferrer noreferrer">sqk.info</a>') ifNil: [^ nil].<br>
+               "If not there, Caller will ask user for password"<br>
+               "If you don't have this file, and you really do want to release an update, <br>
+                contact Ted Kaehler."<br>
+       ^ (self decode: (sfile contentsOfEntireFile)) lines<br>
+ !<br>
<br>
<br>
</blockquote></div>