
    Hj                     v   d Z ddlZddlZddlZddlZddlZddlZddlmZm	Z	 ddl
mZ 	 ddlZn# e$ r  ej        d           Y nw xY wdZdZdZd	Z eej                            d
d                    ZddededefdZdededeeef         fdZdefdZedk    r ej         e                       dS dS )u6  
probe_login.py — single login attempt against the Shinemonitor/EyBond API.

Uses the REAL action name (`authSource`) that the reverse-engineered
SolarPower_1.6.1.0 APK uses, not the placeholder `user` action that fails
with ERR_FORBIDDEN.

Usage:
    pip install requests          # only third-party dep
    SOLAR_EMAIL='you@example.com' SOLAR_PASSWORD='yourpass' python3 probe_login.py

Output on success:
    ✔ Login successful.
      utoken: <short prefix...short suffix>  (N chars)
      ztoken: <short prefix...short suffix>  (M chars)
      cached: ./tokens.json
      expires: <ISO8601 timestamp, ~5 days from now>

Output on failure: prints the FULL raw response body, exit code 1.

The cached tokens are written to ./tokens.json (mode 600) and are good for
~5 days.  Re-run run_all_endpoints.py to use them.
    N)datetimetimezone)PathzCERROR: 'requests' is required.  Install with:  pip install requestsz'http://android.shinemonitor.com/public/bnrl_frRFjEz8Mknzcom.eybond.solarpowerz1.6.1.0SOLAR_TOKEN_PATHz./tokens.json actionextrareturnc                 p    dt            dt           }|rd|                    d           nd}d|  | | S )z?Build the i18n/lang/source/app meta suffix the gateway expects.z8&i18n=en&lang=en&source=1&_app_client_=android&_app_id_=z&_app_version_=&r   z&action=)APP_IDAPP_VERSIONlstrip)r	   r
   metasuffixs       /root/solar/probe_login.py_base_actionr   2   sf    	(	( 	( &	( 	( 	 ).5$c""$$$2F,f,f,d,,,    emailpasswordc                 X   t          ddt          j                            | d           dt                     }t          t          t          j                    	                                dz                      }t          j        |                    d                                                                                    }t          j        ||z   |z                       d                                                                                    }t           d| d	| | |fS )
zAReturn (url, salt).  Sign = SHA1(salt + sha1(pwd) + base_action).
authSourcezusr=r   )safez&company-key=i  zutf-8z?sign=z&salt=)r   urllibparsequoteCOMPANY_KEYstrintr   now	timestamphashlibsha1encode	hexdigestlowerBASE_URL)r   r   basesaltpwd_sha1signs         r   
_login_urlr-   >   s    &kV\-?-?B-?-O-O&k&k^i&k&kllDs8<>>++--45566D|HOOG4455??AAGGIIH<4/77@@AAKKMMSSUUD66d66$666<<r   c            
         t           j                            d          } t           j                            d          }| r|st          j        d           t          | |          \  }}t          d|            t          d|             t          ddt          |          z   dt          |           d	           t          d
|            	 t          j        |dddt           di          }n@# t          j
        $ r.}t          j                            d| d           Y d }~dS d }~ww xY wt          d|j         d|j                    t          d|j                            dd                      t          d|j                            dd                      	 |                                }ns# t"          $ rf t          j                            d           t          j                            |j                   t          j                            d           Y dS w xY wt          d           t          t!          j        |dd                     t          d            |                    d!|                    d"|                    d#d$                              }|                    d%|                    d&|                    }t)          |t*                    r|                    d'          nd }	t)          |t*                    r|                    d(          nd }
|d)v r|	rt,          j                            d*d*+           |	|
t3          j        t6          j                                      d,-          d.| t<          d/}t,                              t!          j        |d0                     t          j         t,          d1           t          d2           t          d3|	d d4          d5|	d6d           d7t          |	           d	           |
r7t          d8|
d d4          d5|
d6d           d7t          |
           d	           nt          d9           t          d:t,          !                                            t3          j"        tG          j#                    |d;         z   t6          j        <                              d,-          }t          d=|            t          d>           d?S |                    d!d          }|                    d@          p@|                    dA          p+|                    dB          p|                    dC          pdD}t          j                            dE| dF|d           t          j                            dG           dHS )INSOLAR_EMAILSOLAR_PASSWORDa  ERROR: SOLAR_EMAIL and SOLAR_PASSWORD env vars are required.
  Example:
    SOLAR_EMAIL='you@example.com' SOLAR_PASSWORD='yourpass' python3 probe_login.py
  Or in a shell:
    export SOLAR_EMAIL='you@example.com'
    export SOLAR_PASSWORD='yourpass'
    python3 probe_login.py
zGET  z  email    = z  password = *z (z chars)z  salt     =    z
User-AgentzSolarPower/z Android)timeoutheadersz
NETWORK ERROR: 
   z
HTTP  zContent-Type:   zContent-Type?zContent-Length: zContent-Lengthz
NON-JSON RESPONSE BODY:
   z
=== FULL API RESPONSE ===   F)indentensure_asciiz=== END API RESPONSE ===
errcodestatusdatdatautokenztoken)r   0T)parentsexist_okseconds)timespeci )rC   rD   	issued_atvalid_for_sr   base_url)r;   i  u   ✔ Login successful.z  utoken:     u   …iz  (z  ztoken:  z  ztoken:  (none returned)z  cached:  rK   )tzz  expires: u   
Next:
  • Tokens are good for ~5 days.  Re-running this script will
    get a fresh pair (and overwrite the cache).
  • To exercise the rest of the API, run:
        python3 run_all_endpoints.py
    (the runner auto-uses the cached tokens).r   descerrMsgmsgmessagez(no message field)u   
✘ LOGIN FAILED: err=z
  message=aI    Common causes:
    err=16  ERR_PASSWORD_VERIF_FAIL  signature rejected (rate-limit
                                       or clock skew); back off 15 min
    err=17  ERR_USER_NOT_EXIST       email not registered
    err=18  ERR_PASSWORD             wrong password
    err=20  ERR_FREQ                 too many logins; back off
   )$osenvirongetsysexitr-   printlenrequestsr   RequestExceptionstderrwritestatus_codereasonr4   json
ValueErrortextdumps
isinstancedict
TOKEN_PATHparentmkdirr   r!   r   utc	isoformatr(   
write_textchmodresolvefromtimestamptime)r   r   urlr*   resperB   r>   innerutokztokcacheexpiresr=   rQ   s                  r   mainry   G   s   z~~m,,Ez~~.//H 	
 	
+	
 	
 	
 5(++IC	-#--	
!%
!
!"""	
G#H-
G
GX
G
G
GHHH	
 $
 
 !!!|ClDgR]DgDgDg5hiii$   
2Q222333qqqqq 

4D$
4
4t{
4
4555	
DT\--ncBB
D
DEEE	
FT\--.>DD
F
FGGGyy{{   
6777
###
qq	 

'(((	$*T!%
8
8
8999	
&'''HHUDHHVTXXh-C-CDDEEDHHUDHHVT2233E#-eT#:#:DEIIhD#-eT#:#:DEIIhDxDt<<<#<55???SS( #
 
 	djq999:::
U###%&&&JD"IJJ$rss)JJD		JJJKKK 	0NSbS	NNd233iNNCIINNNOOOO.///2J..0022333(IKK%..8<
 
 

)Y)
'
' 	 	%G%%&&&<	
 	
 	
 q
((5#

C 	 88H	 88E??	  88I	     JHHHsHHHIIIJ	K   1s+   "C7 7D4#D//D4-G A,H21H2__main__)r   )__doc__rT   rW   ra   rp   r#   urllib.parser   r   r   pathlibr   r[   ImportErrorrX   r(   r   r   r   rU   rV   rg   r   r   tupler-   r    ry   __name__ r   r   <module>r      s   0 
			 



        ' ' ' ' ' ' ' '      TOOOO T T TCHRSSSSST :"'RZ^^$6HHII
	- 	- 	-S 	-# 	- 	- 	- 	-=c =S =U38_ = = = =ac a a a aH zCHTTVV s   / AA