<s> import nacl . signing <EOL> import random <EOL> import string <EOL> from email . header import Header <EOL> from twisted . web . resource import Resource <EOL> from unpaddedbase64 import encode_base64 <EOL> import json <EOL> from sydent . db . invite_tokens import JoinTokenStore <EOL> from sydent . db . threepid_associations import GlobalAssociationStore <EOL> from sydent . http . servlets import require_args , send_cors <EOL> from sydent . util . emailutils import sendEmail <EOL> class StoreInviteServlet ( Resource ) : <EOL> def __init__ ( self , syd ) : <EOL> self . sydent = syd <EOL> def render_POST ( self , request ) : <EOL> send_cors ( request ) <EOL> err = require_args ( request , ( "<STR_LIT>" , "<STR_LIT:address>" , "<STR_LIT>" , "<STR_LIT>" , ) ) <EOL> if err : <EOL> return json . dumps ( err ) <EOL> medium = request . args [ "<STR_LIT>" ] [ <NUM_LIT:0> ] <EOL> address = request . args [ "<STR_LIT:address>" ] [ <NUM_LIT:0> ] <EOL> roomId = request . args [ "<STR_LIT>" ] [ <NUM_LIT:0> ] <EOL> sender = request . args [ "<STR_LIT>" ] [ <NUM_LIT:0> ] <EOL> globalAssocStore = GlobalAssociationStore ( self . sydent ) <EOL> mxid = globalAssocStore . getMxid ( medium , address ) <EOL> if mxid : <EOL> request . setResponseCode ( <NUM_LIT> ) <EOL> return json . dumps ( { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:error>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : mxid , <EOL> } ) <EOL> if medium != "<STR_LIT:email>" : <EOL> request . setResponseCode ( <NUM_LIT> ) <EOL> return json . dumps ( { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:error>" : "<STR_LIT>" % ( medium , ) , <EOL> } ) <EOL> token = self . _randomString ( <NUM_LIT> ) <EOL> tokenStore = JoinTokenStore ( self . sydent ) <EOL> ephemeralPrivateKey = nacl . signing . SigningKey . generate ( ) <EOL> ephemeralPublicKey = ephemeralPrivateKey . verify_key <EOL> ephemeralPrivateKeyBase64 = encode_base64 ( ephemeralPrivateKey . encode ( ) , True ) <EOL> ephemeralPublicKeyBase64 = encode_base64 ( ephemeralPublicKey . encode ( ) , True ) <EOL> tokenStore . storeEphemeralPublicKey ( ephemeralPublicKeyBase64 ) <EOL> tokenStore . storeToken ( medium , address , roomId , sender , token ) <EOL> substitutions = { } <EOL> for key , values in request . args . items ( ) : <EOL> if len ( values ) == <NUM_LIT:1> and type ( values [ <NUM_LIT:0> ] ) == str : <EOL> substitutions [ key ] = values [ <NUM_LIT:0> ] <EOL> substitutions [ "<STR_LIT>" ] = token <EOL> required = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> for k in required : <EOL> substitutions . setdefault ( k , '<STR_LIT>' ) <EOL> substitutions [ "<STR_LIT>" ] = ephemeralPrivateKeyBase64 <EOL> if substitutions [ "<STR_LIT>" ] != '<STR_LIT>' : <EOL> substitutions [ "<STR_LIT>" ] = "<STR_LIT>" % substitutions [ "<STR_LIT>" ] <EOL> subject_header = Header ( self . sydent . cfg . get ( '<STR_LIT:email>' , '<STR_LIT>' , raw = True ) % substitutions , '<STR_LIT:utf8>' ) <EOL> substitutions [ "<STR_LIT>" ] = subject_header . encode ( ) <EOL> sendEmail ( self . sydent , "<STR_LIT>" , address , substitutions ) <EOL> pubKey = self . sydent . keyring . ed25519 . verify_key <EOL> pubKeyBase64 = encode_base64 ( pubKey . encode ( ) ) <EOL> baseUrl = "<STR_LIT>" % ( self . sydent . cfg . get ( '<STR_LIT:http>' , '<STR_LIT>' ) , ) <EOL> keysToReturn = [ ] <EOL> keysToReturn . append ( { <EOL> "<STR_LIT>" : pubKeyBase64 , <EOL> "<STR_LIT>" : baseUrl + "<STR_LIT>" , <EOL> } ) <EOL> keysToReturn . append ( { <EOL> "<STR_LIT>" : ephemeralPublicKeyBase64 , <EOL> "<STR_LIT>" : baseUrl + "<STR_LIT>" , <EOL> } ) <EOL> resp = { <EOL> "<STR_LIT>" : token , <EOL> "<STR_LIT>" : pubKeyBase64 , <EOL> "<STR_LIT>" : keysToReturn , <EOL> "<STR_LIT>" : self . redact ( address ) , <EOL> } <EOL> return json . dumps ( resp ) <EOL> def redact ( self , address ) : <EOL> return "<STR_LIT:@>" . join ( map ( self . _redact , address . split ( "<STR_LIT:@>" , <NUM_LIT:1> ) ) ) <EOL> def _redact ( self , s ) : <EOL> if len ( s ) > <NUM_LIT:5> : <EOL> return s [ : <NUM_LIT:3> ] + "<STR_LIT>" <EOL> elif len ( s ) > <NUM_LIT:1> : <EOL> return s [ <NUM_LIT:0> ] + "<STR_LIT>" <EOL> else : <EOL> return "<STR_LIT>" <EOL> def _randomString ( self , length ) : <EOL> return '<STR_LIT>' . join ( random . choice ( string . ascii_letters ) for _ in xrange ( length ) ) </s>
