B
    Zcw                 @   sh  d dl Z d dlmZ d dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZ d dl
mZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZmZ dd ZG dd deZG dd dejZdd Zdd Zdd Zdd Zdd Z dd Z!d9dd Z"d!d" Z#d#d$ Z$d%d& Z%d'd( Z&d)d* Z'd+d, Z(d-d. Z)d/d0 Z*d1d2 Z+d3d4 Z,G d5d6 d6e-Z.d7d8 Z/dS ):    N)wraps)	countries)settings)DjangoFilterBackend)viewsets)filters)SessionAuthentication)get_system_setting)SystemSetting)Company)DefaultSchemaDefaultPaginationBasec             C   s(   d | |}d t|  }|S )zN
    authorization format: 'Basic base64.encode(client_id:client_secret)'
    z{}:{}zBasic {})formatbase64Z	b64encodeencodedecode)	client_idclient_secretZ"client_id_and_client_secret_formatauthorization r   +G:\easytimepro\master/mysite/cloud\utils.pyhttp_basic_auth   s    r   c               @   s   e Zd Zdd ZdS )CsrfExemptSessionAuthenticationc             C   s   d S )Nr   )selfrequestr   r   r   enforce_csrf!   s    z,CsrfExemptSessionAuthentication.enforce_csrfN)__name__
__module____qualname__r   r   r   r   r   r      s   r   c               @   s(   e Zd ZdZe ZeZee	j
e	jfZdS )CloudViewSetN)r   r   r   Zmodelr   Zschemar   Zpagination_classr   r   ZSearchFilterZOrderingFilterZfilter_backendsr   r   r   r   r   %   s   r   c             C   s    ddl m} | }|| }|S )Nr   )CurrencyCodes)Zforex_python.converterr    Z
get_symbol)currency_alpha_3r    Zcurrency_codecurrency_symbolr   r   r   get_currency_symbol.   s    
r#   c             C   s   t |}dj|t| d}|S )Nz{currency_symbol}{price})r"   price)r#   r   str)r$   r!   r"   Zprice_with_currency_symbolr   r   r   get_price_with_currency_symbol7   s    r&   c             C   sR   dd l }tt|  }|dkr d}|jj|d}|jj|jd}|sHd}n|j}|S )Nr   zUnited States of AmericazUnited States)name)numericZUSD)	pycountrydictr   getZ
currenciesr(   Zalpha_3)country_coder)   country_namecountryZcurrencyr!   r   r   r   get_country_currency>   s    r/   c             C   s   t | }|S )N)r   Zby_name)r-   r,   r   r   r   convert_country_name2codeN   s    
r0   c             C   s   t t|  }|S )N)r*   r   )r,   r-   r   r   r   convert_country_code2nameT   s    r1   c             C   s   dd l }|| j}|S )Nr   )	ipaddress
ip_address
is_private)r3   r2   r4   r   r   r   check_ip_is_privateZ   s    r5   c          
   C   s  dd l }dd l}ddlm} ddlm}m} t }|d	| d }|sfyd}	d}
|sj|j
j| d }|r|jr|jjs|j
j|jd }|r|jr|jr|j}	|j}
nf|| }|jd }	|jd }
y"|j
j||j |	|
d	d
 W n$ tk
r } zW d d }~X Y nX |	|d< |
|d< |jd	| |	|
gdd W n   d|d< d|d< Y nX n|d |d< |d |d< |S )Nr   )cache)TerminalLocationTerminalz!{}_geolocation_latitude_longitude )r3   )Zterminal_id   )latitude	longitude)ZterminalZgps_timedefaultsr;   r<   i  )timeout)geocoderdatetimedjango.core.cacher6   Zmysite.iclock.modelsr7   r8   r*   r+   r   objectsfilterfirstZareaZ
is_defaultidr;   r<   ipZlatlngZupdate_or_createZnow	Exceptionset)r3   devicer?   r@   r6   r7   r8   geolocation_infoZgeolocation_cacher;   r<   Zterminal_locationgeolocationer   r   r   convert_ip2geolocationa   sB    


"rM   c       
      C   s   dd l }ddlm} ddlm} t }|d|d }|syf||}|jrX|j|d< n2|	| }|j
}	|	j|d< |	jd d |_|  |d||d  W q tk
r   d|d< Y qX n|d||d< |S )Nr   )r6   )	getDevicez{}_device_ip_to_addressaddress(   -)r?   rA   r6   Zmysite.iclock.utilsrN   r*   r+   r   Zgps_locationrF   Zcurrent_resultrO   ZsaverH   	TypeError)
r3   Zsnr?   r6   rN   Zdevice_address_infoZdevice_address_cacherI   rK   resultr   r   r   convert_ip2address   s(    

rT   c             C   s  dd l }ddlm} ddlm} |jr.|j}n|j}t }|dksF|srd|d< d|d< d	|d
< d|d< d|d< n~|	d
| d }|stjj	| dj}td|}	|	rd|	krd|	kr|	d }
|	d }|	d }|	d }|	d }n$y||}||}|d d d }|d }
|d }|d d }t|}|d }|d }|d }|d }|	r|
|	d< ||	d< ||	d< ||	d< ||	d< ||	d< tjj|ddjt|	d tjj|d j|||d! d"|jdt|f }|| W n* tk
r   d}
d}d	}d}d}Y nX |
|d< ||d< ||d
< ||d< ||d< |d
| |
 |d#
| | |d$
| | |d%
| | |d&
| | nd|	d
| |d< |	d#
| |d< |	d$
| |d
< |	d%
| |d< |	d&
| |d< |S )'Nr   )r6   )r   ZDefaultgPfS@r;   gbu)@r<   ZIndiar.   zNot setprovincecityz{}_geolocation_info_latitude)Zname__iexactZcompany_settingcompany_latitudecompany_longituder-   company_provincecompany_cityZgeometrylocationZlatZlngaddress_componentscountry_long_namecountry_short_namecompany_country)
company_idr'   )value)rE   )r.   rV   rU   z%s_%s_%sz{}_geolocation_info_longitudez{}_geolocation_info_countryz{}_geolocation_info_provincez{}_geolocation_info_city)
googlemapsrA   r6   django.confr   ZCLOUD_VERSIONZINTELLIGENTTIME_MAPS_APIZEASYTIMEPRO_MAPS_APIr*   r+   r   r   rB   rE   r	   ZClientZgeocodecompany_addressr
   rC   updatejsondumpsZUNITr%   deleterG   rH   )Zcompany_namerO   rb   r6   r   ZMAPS_API_KEYrJ   Zgeolocation_info_cacher`   Zcompany_settingsrW   rX   r_   rY   rZ   Zgoogle_mapsZgeocode_resultr[   r\   Zcompany_locationZcompany_country_short_nameZ	cache_keyr   r   r   convert_address2geolocation   s    




ri   c             C   sv   i }xl| D ]d}|d d dkr6|d |d< |d |d< |d d dkrR|d |d	< |d d d
kr
|d |d< q
W |S )Ntypesr   r.   Z	long_namer]   Z
short_namer^   Zadministrative_area_level_1rU   ZlocalityrV   r   )r\   Zaddress_dictZ
componentsr   r   r   rd     s    
rd   c                sD   ddl m ddlm  t fdd}j|_j|_|S )Nr   )
Membership)HttpResponseForbiddenc                sH   | j }|jrDjj|dd }|s.|jdkr>| f||S   S d S )N   )userroleadmin)rn   Zis_authenticatedrB   rC   existsusername)r   argskwargsrn   Zmembership_exist)rl   rk   viewr   r   wrapper  s    z0admin_and_vendor_login_required.<locals>.wrapper)mysite.base.modelsrk   django.httprl   r   __doc__r   )ru   rv   r   )rl   rk   ru   r   admin_and_vendor_login_required  s    
rz   c                s6   ddl m  t fdd}j|_j|_|S )Nr   )rl   c                s&   | j }|jr| f||S   S d S )N)rn   is_super_admin)r   rs   rt   rn   )rl   ru   r   r   rv   &  s    z%admin_login_required.<locals>.wrapper)rx   rl   r   ry   r   )ru   rv   r   )rl   ru   r   admin_login_required#  s
    r|   c                s<   ddl m m t fdd}j|_j|_|S )Nr   )rl   HttpResponseNotFoundc                s:   | j }|js0|js|jr(| f||S   S n S d S )N)rn   Zis_anonymousZis_vendor_displayr{   )r   rs   rt   rn   )rl   r}   ru   r   r   rv   7  s    z/admin_or_vendor_login_required.<locals>.wrapper)rx   rl   r}   r   ry   r   )ru   rv   r   )rl   r}   ru   r   admin_or_vendor_login_required4  s
    r~   c             C   s   ddl m} ddlm} | j}|jj|dd}|jj|d}g }g }x,|D ]$}|t	|j
 |t	|j
 qNW xtt|dkr|d }	|jj|	d}
d	d
 |
D }x*|D ]"}||kr|| || P qW |d |	krx|  qxW |S )u  
    Get all companies id list to which the current vendor belongs
    :param request:
    :return: belongs company id list
    The company structure can be converted to a multi-tree
    Use non-recursive method of depth-first traversal
    Traverse the current vendor and the company that belongs to this vendor as a sub-vendor
    the company that the sub-vendor belongs to, and so on ...
    E.g
                                   vendor_1
                                /      /                                  /       /                                  /        /                                  /         /                                  /          /                                  /           /                                  /            /                            company_1        company_2       company_6
                 /             /                   /              /               company_3      company_4  company_5
                                                                                                                   company_7

    Company_ * of any node login to the backend dashboard
    and iterate to find all company lists of its subordinates

    If I login in in "vendor_1", and the "all company count" is 7(company_1, company_2, company_3, company_4, company_5, company_6, company_7)
    If I login in in "company_2", and the "all company count" is 3(company_4, company_5, company_7)
    If I login in in "company_1", and the "all company count" is 1(company_3)
    r   )rk   )r   )rn   company)id__in)vendor_company_idc             S   s   g | ]}|j jqS r   )r   rE   ).0mr   r   r   
<listcomp>{  s    z0get_all_belongs_companies_id.<locals>.<listcomp>)rw   rk   mysite.cloud.modelsr   rn   rB   rC   values_listappendr%   rE   lenpop)r   rk   r   current_userZcurrent_user_company_id_listZcurrent_user_company_querycompany_id_listZbelongs_company_id_listcr`   Zcurrent_belongs_companyZsub_belongs_company_listZsub_belongs_companyr   r   r   get_all_belongs_companies_idH  s,    !



r   c             C   sb   ddl m} | jj}| jjr(|j }n6| jjrPt| }|jj	|dj
|d}n|jj	|d}|S )z
    get company query by three types: super admin's company/superuser extra's company/current company
    :param request:
    :return: company query
    r   )r   )r   )rE   )r   r   rn   Zcurrent_companyr{   rB   allZis_superuser_extrar   rC   Zexclude)r   r   current_company_idcompany_queryall_belongs_companies_idr   r   r   get_company_query  s    r   c             C   s:   ddl m} | jjr |j }nt| }|jj|d}|S )z
    get company query by two types: super admin's company/other user's company for order and payment record ViewSet
    :param request:
    :return: company query
    r   )r   )r   )r   r   rn   r{   rB   r   r   rC   )r   r   r   r   r   r   r   )get_company_query_without_superuser_extra  s    r   c             C   s   ddl m} ddlm} | j}| j}g }|jj|d	d}x,|D ]$}|jj|d
 }|rF|| qFW |jdkr|jj|d}	n"|jjdd		d}
|jj|
d}	|	S )
u  
    Get the vendor query
    The company structure can be converted to a multi-tree
    E.g
                                       vendor_1
                                    /      /                                      /       /                                      /        /                                      /         /                                      /          /                                      /           /                                      /            /                                company_1        company_2       company_6
                     /             /                       /              /                  company_3    company_4    company_5
                                                                                                                               company_7

    Vendor mean：Find the number of non-leaf nodes with a multi-tree depth of 1
    If I login in in "vendor_1", and the "vendor count" is 2(company_1, company_2)
    If I login in in "company_1", and the "vendor count" is 0
    If I login in in "company_2", and the "vendor count" is 1(company_5)
    :param request:
    :return: vendor query
    r   )rk   )r   )r   r   rp   )r   rm   )ro   )rw   rk   r   r   rn   Zget_current_companyrE   rB   rC   r   rq   r   rr   )r   rk   r   r   r   Z"vendor_first_depth_company_id_listZfist_depth_company_id_listr`   Z
node_exitsr   r   r   r   r   get_vendor_query  s    


r   c               @   sr   e Zd ZdZejejfddZdddZddd	Z	dd
dZ
ddejejejdddfddZdejdfddZdS )AWSBoto3APIz
    :type aws_access_key_id: string
    :param aws_access_key_id: AWS access key ID

    :type aws_secret_access_key: string
    :param aws_secret_access_key: AWS secret access key
    c             C   s*   dd l }|| _|| _|| j| j| _d S )Nr   )boto3aws_access_key_idaws_secret_access_keyZSession_session)r   r   r   r   r   r   r   __init__  s    zAWSBoto3API.__init__acmc             C   s0   | j j|tjd}|jdddgd}|d }|S )a*  
        docs: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/acm.html#ACM.Client.list_certificates
        :param server_name: aws server name
        :return: Returns a dictionary (e.g., [
        {'CertificateArn': 'arn:aws:acm:us-east-2:402510031561:certificate/6c37409d-57ea-4f7e-92c5-8028316828cd',
        'DomainName': 'biotime.mx'},
        {'CertificateArn': 'arn:aws:acm:us-east-2:402510031561:certificate/c8ddddc1-fee3-446f-a158-4f7ad33b988d',
        'DomainName': '*.robin-vendor.biotime.mx'}
        ])
        )region_nameZPENDING_VALIDATIONZISSUEDZINACTIVE)ZCertificateStatusesZCertificateSummaryList)r   clientr   AWS_REGION_NAMEZlist_certificates)r   server_name
acm_clientresponseZcertificate_summary_listr   r   r   acm_list_certificates  s
    z!AWSBoto3API.acm_list_certificatesNc             C   sF   | j j|tjd}|j|dddid|dd dgd	}|d
 }|S )a|  
        docs: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/acm.html#ACM.Client.request_certificate
        :param server_name: aws server name
        :param domain_name: the domain name which need to add
        :return: Returns a certificate arn (e.g., arn:aws:acm:us-east-2:402510031561:certificate/b59c71a2-0456-4aa3-a5c9-f362fdea1674).
        )r   ZDNSZ(CertificateTransparencyLoggingPreferenceZDISABLEDzvendor-company-subdomainz*.r   )ZKeyValue)Z
DomainNameZValidationMethodZOptionsZTagsCertificateArn)r   r   r   r   Zrequest_certificatesplit)r   r   domain_namer   r   certificate_arnr   r   r   acm_request_certificate
  s    z#AWSBoto3API.acm_request_certificatec             C   s2   | j j|tjd}|j|d}|d d d }|S )a  
        docs: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/acm.html#ACM.Client.describe_certificate
        :param server_name: aws server name
        :param certificate_arn: the certificate arn
        :return: Return a dict (e.g., {'DomainName': '*.robin-vendor.biotime.mx',
        'ValidationDomain': '*.robin-vendor.biotime.mx', 'ValidationStatus': 'SUCCESS',
        'ResourceRecord': {'Name': '_d0a9d5454bbffb5c6ea9d3df796d5d66.robin-vendor.biotime.mx.',
        'Type': 'CNAME', 'Value': '_704209c9b88b9f8204b46ef27789a2c7.qqqfmgwtgn.acm-validations.aws.'},
        'ValidationMethod': 'DNS'}).
        )r   )r   ZCertificateZDomainValidationOptionsr   )r   r   r   r   Zdescribe_certificate)r   r   r   r   r   Zdomain_validation_optionsr   r   r   acm_describe_certificate$  s
    z$AWSBoto3API.acm_describe_certificateZroute53ZCREATEc	             C   s   | j j|tjd}	|||d|ddddgd|d}
||d	|igd
dddgd|d}|	j||
d |	j||d dS )a  
        docs: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/route53.html#Route53.Client.change_resource_record_sets
        :param server_name: aws server name
        :param action_type: CREATE
        :param alias_dns_name: load balancer instance's DNS name of EC2
        :param alias_hosted_zone_id: load balancer instance's hosted zone id of EC2
        :param route53_hosted_zone_id: route 53 hosted zone id
        :param domain_name: domain name
        :param resource_record_name: the resource record name
        :param resource_record_value: the resource record value
        :return: True
        )r   F)ZDNSNameZEvaluateTargetHealthHostedZoneIdA)NameZAliasTargetType)ZActionZResourceRecordSetzSubdomain for {})ZChangesCommentr   <   ZCNAME)r   ZResourceRecordsZTTLr   )r   ZChangeBatchT)r   r   r   r   r   Zchange_resource_record_sets)r   r   Zaction_typeZalias_dns_nameZalias_hosted_zone_idZroute53_hosted_zone_idr   Zresource_record_nameZresource_record_valueZroute53_clientZchange_batch_aZchange_batch_cnamer   r   r   #route53_change_resource_record_sets8  s*    z/AWSBoto3API.route53_change_resource_record_setsZelbv2c             C   s*   | j j|tjd}|j|d|igd}|S )a}  
        docs: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/elbv2.html#ElasticLoadBalancingv2.Client.add_listener_certificates
        :param server_name: aws server name
        :param listener_arn: load balancer instance's 443 listener id's arn of EC2
        :param certificate_arn: acm certificate arn
        :return: Return a dictionary
        )r   r   )ZListenerArnZCertificates)r   r   r   r   Zadd_listener_certificates)r   r   Zlistener_arnr   Zelbv2_clientr   r   r   r   elbv2_add_listener_certificates  s
    
z+AWSBoto3API.elbv2_add_listener_certificates)r   )r   N)r   N)r   r   r   ry   r   ZAWS_ACCESS_KEY_IDZAWS_SECRET_ACCESS_KEYr   r   r   r   ZAWS_EC2_ALIAS_DNS_NAMEZAWS_EC2_ALIAS_HOSTED_ZONE_IDZAWS_ROUTE53_HOSTED_ZONE_IDr   ZAWS_EC2_LISTENER_ARNr   r   r   r   r   r     s    


Cr   c                s@   dd l  ddlm t fdd}j|_j|_|S )Nr   )	urlencodec                s   y| j d }W n tk
r   tj}tj}tj}| j dd }|st||}d|d}d|i}	|	}
 jtj	||
d
 }|d }|d }|| j d< | j | Y nX | f||S )Naccess_tokenz!application/x-www-form-urlencoded)zContent-TypeZAuthorization
grant_type)Zheadersdata
expires_in)ZsessionKeyErrorr   Z
GRANT_TYPEZ	CLIENT_IDZCLIENT_SECRETr+   r   ZpostZ	TOKEN_URLrf   Z
set_expiry)r   rs   rt   r   r   r   r   r   Zauthorization_headersZbodyZx_www_form_urlencoded_type_bodyZauthorization_contentr   )requestsr   ru   r   r   rv     s(    

z2get_or_update_oauth2_access_token.<locals>.wrapper)r   Zurllib.parser   r   ry   r   )ru   rv   r   )r   r   ru   r   !get_or_update_oauth2_access_token  s    4r   )N)0r   	functoolsr   rf   Zdjango_countriesr   rc   r   Zdjango_filters.rest_frameworkr   Zrest_frameworkr   r   Zrest_framework.authenticationr   Zmysite.utilsr	   Zmysite.base.models.sys_settingr
   r   r   Zmysite.api.utils_classr   r   r   r   ZGenericViewSetr   r#   r&   r/   r0   r1   r5   rM   rT   ri   rd   rz   r|   r~   r   r   r   r   objectr   r   r   r   r   r   <module>   sF   		
,X@4 8