class PresenceService(object): SERVICE_NAME_SIZE = 32 SERVICE_DATA_SIZE = 200 """A Service that may be announced via the Presence daemon.""" def __init__(self, name = 'unnamed', port = 0, data = ''): """Constructor. Creates a presence service object that can be registered with the Presence daemon. @type name: string @param name: The name of the service. This must be between 1 and 32 characters. @type port: int @param port: The port that the service is listening on. This must be a number between 0 and 65535. @type data: string @param data: The (optional) service data. Currently this can at most be 184 bytes. @raise PresenceException: Raised if the input parameters are invalid. """ super(PresenceService, self).__init__() self._name = ServiceName(name) self._port = UInt16(port) self._data = ServiceData(data) def name(): #@NoSelf def fget(self): return self._name.name def fset(self, value): self._name.name = value return locals() name = property(**name()) def port(): #@NoSelf def fget(self): return self._port.value def fset(self, value): self._port.value = value return locals() port = property(**port()) def data(): #@NoSelf def fget(self): return self._data.data def fset(self, value): self._data.data = value return locals() data = property(**data()) def pack(self): """Packs the service into a string for transfer through a socket.""" return ''.join([self._name.pack(), self._port.pack(), self._data.pack()]) def unpack(self, string_repr): try: idx = self._name.unpack(string_repr) idx += self._port.unpack(string_repr[idx:]) idx += self._data.unpack(string_repr[idx:]) return idx except (UnpackingError, ValidationError), excep: raise UnpackingError('Error unpacking service description. Message was="%s"'%excep.args[0])
def get(self, command): ''' process GET request ''' # get cookies user_cookies = cookies.Cookies(self) user = users.get_current_user() if user == None: url = users.create_login_url(dest_url=self.request.url) self.redirect(url) return if command == 'dropbox_auth': # make an authenticator dba = auth.Authenticator(backend.dropbox_backend.DropboxBackend.config) if self.request.get('oauth_token'): # get access token token = oauth.OAuthToken.from_string(user_cookies['token']) access_token = dba.obtain_access_token(token, '') keyname = user.user_id() + "_dropbox" creds = ServiceData.get_or_insert(keyname) creds.owner = user.user_id() creds.service = "dropbox" creds.credentials = access_token.to_string() creds.put() self.response.out.write("done!") else: # grab the request token token = dba.obtain_request_token() user_cookies['token'] = token.to_string() # make the user log in and authorize this token self.redirect(dba.build_authorize_url(token, self.request.url)) elif command == 'unite': keyname = user.user_id() + "_dropbox" creds_dbox = ServiceData.get_or_insert(keyname) keyname = user.user_id() + "_gdocs" creds_gdocs = ServiceData.get_or_insert(keyname) if creds_dbox == None: self.response.out.write("Error: not authorized to use Dropbox") return if creds_gdocs == None: self.response.out.write("Error: not authorized to use GDocs") return keyname = user.user_id() + "_united" creds = ServiceData.get_or_insert(keyname) creds.owner = user.user_id() creds.service = "united" united_creds = [creds_dbox.credentials, creds_gdocs.credentials] creds.credentials = json.dumps(united_creds) creds.put() self.response.out.write("done!")
def post(self, command, service=None): ''' process POST request ''' if service == None: # select service adapter self.service, self.backend = self.detect_service() command = self.request.path_info_pop() # Check authorization user_auth = auth.valid_token(self.request) if user_auth == None: self.send_unauthorized() return if command == 'files': # pass whole file to user creds_key = user_auth.owner + "_" + self.service creds = ServiceData.get_by_key_name(creds_key) if creds == None: self.send_unauthorized('no authorization data for service '+self.service) else: path = self.request.path_info # construct file-like object for backend import StringIO # use raw post parameter buf = StringIO.StringIO(self.request.str_POST['file']) status = self.backend.put_file(path, creds.credentials, buf) self.response.set_status(status) return if command == 'share': # add public link # call addshare handler self.get('addshare', self.service)
def get(self): # Write our pages title self.response.out.write("""<html><head><title> Authorization</title>""") self.response.out.write('</head><body>') # Allow the user to sign in or sign out next_url = atom.url.Url('http', self.request.host, path='/util/gdata_auth') if users.get_current_user(): self.response.out.write('<a href="%s">Sign Out</a><br>' % ( users.create_logout_url(str(next_url)))) else: self.response.out.write('<a href="%s">Sign In</a><br>' % ( users.create_login_url(str(next_url)))) # Initialize a client client = gdata.docs.service.DocsService(source='vsd-cloudstorageproxy') gdata.alt.appengine.run_on_appengine(client) session_token = None # Find the AuthSub token and upgrade it to a session token. auth_token = gdata.auth.extract_auth_sub_token_from_url(self.request.uri) if auth_token: # Upgrade the single-use AuthSub token to a multi-use session token. session_token = client.upgrade_to_session_token(auth_token) if session_token and users.get_current_user(): # If there is a current user, store the token in the datastore and # associate it with the current user. user = users.get_current_user() keyname = user.user_id() + "_gdocs" creds = ServiceData.get_or_insert(keyname) creds.owner = user.user_id() creds.service = "gdocs" creds.credentials = session_token.get_token_string() creds.put() elif session_token: # Since there is no current user, we will put the session token # in a property of the client. We will not store the token in the # datastore, since we wouldn't know which user it belongs to. # Since a new client object is created with each get call, we don't # need to worry about the anonymous token being used by other users. client.current_token = session_token self.response.out.write('<div id="main"></div>') self.response.out.write( '<div id="sidebar"><div id="scopes"><h4>Request a token</h4><ul>') self.response.out.write('<li><a href="%s">Google Documents</a></li>' % ( client.GenerateAuthSubURL( next_url, ('http://docs.google.com/feeds/',), secure=False, session=True))) self.response.out.write('</ul></div><br/><div id="tokens">')
def __init__(self, name = 'unnamed', port = 0, data = ''): """Constructor. Creates a presence service object that can be registered with the Presence daemon. @type name: string @param name: The name of the service. This must be between 1 and 32 characters. @type port: int @param port: The port that the service is listening on. This must be a number between 0 and 65535. @type data: string @param data: The (optional) service data. Currently this can at most be 184 bytes. @raise PresenceException: Raised if the input parameters are invalid. """ super(PresenceService, self).__init__() self._name = ServiceName(name) self._port = UInt16(port) self._data = ServiceData(data)
def get(self, command, service=None): ''' process GET request ''' if service == None: # select service adapter self.service, self.backend = self.detect_service() command = self.request.path_info_pop() # not all commands need authorization if self.check_public_commands(command): return # Check authorization user_auth = auth.valid_token(self.request) if user_auth == None: self.send_unauthorized() return if command == 'files': # pass whole file to user creds_key = user_auth.owner + "_" + self.service creds = ServiceData.get_by_key_name(creds_key) if creds == None: self.send_unauthorized('no authorization data for service '+self.service) else: if self.request.get('version'): params = {'version' : self.request.get('version')} else: params = None path = self.request.path_info status = self.backend.get_file(self.response.out, path, creds.credentials, params) self.response.set_status(status) return if command == 'metadata': # return metadata creds_key = user_auth.owner + "_" + self.service creds = ServiceData.get_by_key_name(creds_key) if creds == None: self.send_unauthorized('no authorization data for service '+self.service) else: if self.request.get('list'): params = {'list' : True if self.request.get('list') == 'true' else False } else: params = None path = self.request.path_info status, metadata = self.backend.get_metadata(path, creds.credentials, params) # output json json.dump(metadata, self.response.out, ensure_ascii=False) self.response.set_status(status) return if command == 'addshare': # create public link to file creds_key = user_auth.owner + "_" + self.service creds = ServiceData.get_by_key_name(creds_key) if creds == None: self.send_unauthorized('no authorization data for service '+self.service) else: path = self.request.path_info link_key = creds_key + path link = ShareLink.get_or_insert(link_key, data=creds, path=path) link.regenerate_link() # generate link code self.response.out.write(link.link) return if command == 'share': # return list of shares # get credentials creds_key = user_auth.owner + "_" + self.service creds = ServiceData.get_by_key_name(creds_key) if creds == None: self.send_unauthorized('no authorization data for service '+self.service) else: links = ShareLink.gql('WHERE data = :1', creds) link_list = [(link.path, link.link) for link in links] # return json json.dump(link_list, self.response.out, ensure_ascii=False) return if command == 'unshare': # delete public link to file # get credentials creds_key = user_auth.owner + "_" + self.service creds = ServiceData.get_by_key_name(creds_key) if creds == None: self.send_unauthorized('no authorization data for service '+self.service) else: path = self.request.path_info link_key = creds_key + path link = ShareLink.get_by_key_name(link_key) if link == None: self.error(404) else: link.delete() return # if we got down here then command is not recognized # report error self.error(400) self.response.headers.add_header("Cache-Control", "no-store") self.response.out.write("Unsupported command")