<commit_before>#
# Copyright (c) 2008 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.rpath.com/permanent/licenses/CPL-1.0.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#
import re
import urllib

class _Controller(object):

    # Declarative configuration variables.  The following variables control
    # the behavior of the controller.  See documentation of Controller
    # subclass for what they do.
    modelName = None
    modelRegex = '[^/]*'
    processSuburls = False
    urls = None

    def __init__(self, parent, path, subhandlerParams=None):
        """

        """
        self.parent = parent
        if parent:
            self._url = '%s/%s' % (parent._url, path)
            self.root = parent.root
        else:
            self._url = ''
            self.root = self

        if self.modelName:
            self.baseMethods = dict(POST='create',
                                    DELETE='destroy_all',
                                    PUT='update_all',
                                    GET='index')
            self.modelMethods = dict(POST='process',
                                GET='get',
                                PUT='update',
                                DELETE='destroy')
        else:
            self.baseMethods = dict(POST='process',
                                    GET='index',
                                    PUT='update',
                                    DELETE='destroy')

        if not subhandlerParams:
            subhandlerParams = []
        self.urls = self._initializeUrls(self.urls, subhandlerParams)

    def _initializeUrls(self, urls, subhandlerParams):
        if not urls:
            return {}
        newUrls = {}
        for key, handler in urls.items():
            if isinstance(handler, str):
                newUrls[key] = getattr(self, handler)
            elif isinstance(handler, dict):
                d = {}
                for method, handlerStr in handler.iteritems():
                    d[method] = getattr(self, handlerStr)
                newUrls[key] = d
            else:
                newUrls[key] = handler(self, key, *subhandlerParams)
        return newUrls

    def url(self, request, location, *args):
        return request.url(location, *args)

    def splitId(self, url):
        match = re.match('/?(%s)/?(.*|)' % self.modelRegex, urllib.unquote(url))
        if match:
            return match.groups()
        raise NotImplementedError

    def splitSubdir(self, url):
        if url[0] == '/':
            url = url[1:]
        parts = url.split('/', 1)
        return (parts + [''])[0:2]

    def getView(self, method, url):
        # FIXME: this should separate into one part that dispatches
        # to the right depth (getController)
        # and a second part that assumes that the current controller
        # is the right one (getView body)
        return self.getController(method, url, (), {})

    def getController(self, method, url, args, kwargs):
        if not url or url == '/':
            viewFnName = self.baseMethods.get(method, None)
            if viewFnName:
                viewFnName = getattr(self, viewFnName)
                return viewFnName, '', args, kwargs
            else:
                raise NotImplementedError
        elif self.modelName:
            modelId, newUrl = self.splitId(url)
            kwargs[self.modelName] = modelId
            return self.getControllerWithId(method, newUrl, args, kwargs)
        else:
            subDir, newUrl = self.splitSubdir(url)
            return self.getNextController(method, subDir, newUrl, args, kwargs)

    def getControllerWithId(self, method, url, args, kwargs):
        controller = None
        if url:
            subDir, newUrl  = self.splitSubdir(url)
            if self.urls and subDir in self.urls:
                controller = self.urls[subDir]
                if isinstance(controller, dict):
                    if method in controller:
                        controller = controller[method]
                    else:
                        raise NotImplementedError
                if hasattr(controller, 'getController'):
                    return controller.getController(method, newUrl,
                                                    args, kwargs)
                return controller, newUrl, args, kwargs
        if not url or self.processSuburls:
            controller = self.modelMethods.get(method, None)
            if controller:
                controller = getattr(self, controller)
                return controller, url, args, kwargs
        raise NotImplementedError

    def getNextController(self, method, subDir, url, args, kwargs):
        if self.urls and subDir in self.urls:
            controller = self.urls[subDir]
            if isinstance(controller, dict):
                if method in controller:
                    controller = controller[method]
            if hasattr(controller, 'getController'):
                return controller.getController(method, url, args, kwargs)
            if hasattr(controller, '__call__'):
                return controller, url, args, kwargs
        raise NotImplementedError

class RestController(_Controller):
    """
    Controller object.  Contains logic for determining
    what view to render.  Also often contains the views that are called
    as methods of this class.

    Any url parsing is controlled by the urls dictionary (described below)
    If there is no url to parse, the following methods are called for each
    HTTP method.  The default implementations raise NotImplementedError,
    which is automatically translated to a 404 response.

    GET: index
    POST: process
    PUT: update
    DELETE: destroy

    These methods will be called with a request object as the first parameter.
    The remainder parameters will be controlled by the process of parsing
    the url structures, but in general will be keywords determined by the
    model controllers that parsed parts of the url structure to get to the
    current controller (see the modelName description for more details).

    The behavior is controlled by several class variables.

    @cvar urls: A dictionary that describes how the controller should
    process the leftmost part of the url.  The keys of the dictionary are
    strings that map to the leftmost part of the url (by default, the part
    between the leftmost slashes).

    * If the value is not a string or a dictionary, it should be a subclass
    of the Controller class (or something that acts like a controller class).

    Example:

    If your top level controller contains:

    {'books'  : BooksController,
     'movies' : MoviesController}

    Then any request to /books will be passed to the BooksController and
    any request to /movies will be passed to the MoviesController.

    * If the value is a string, the string should correspond to a method of the
    current class.  This method will be returned as the view if and only if
    the current controller has parsed the remainder of the url.

    Example:

    If your urls for your top level controller contains:

    { 'people' : 'list_people'}

    And your controller class contains a method:

    def list_people(request):
        return Response('People in this database: john, mary, sue')

    Then the list_people view will be used for the request /people/, but
    not for /people/some/url or /people/

    * If the value is a dictionary, the keys of this subdictionary should be
    http methods (GET, POST, PUT, DELETE), and the values should be either
    strings or subclasses of the controller class as above.

    Example:

    With the following urls dictionary:

    urls = {'invitation'  : { 'POST' : 'send_invitation',
                              'GET'  : 'get_invitation'}}

    A GET request to '/invitation/' will use the 'get_invitation' method,
    a POST request will use the 'send_invitation' method, and a DELETE request
    will return a 404 RequestNotFound error code.

    @cvar modelName: contains the name of the model that this controller
    parses for.  Changes the parsing and dispatching behavior of the controller.
    Also results in the url section parsed as the model being passed into the
    view as a keyword.  The keyword name is the value stored in modelName,
    and the keyword value is the string parsed from the url.

    When creating REST APIs, part of the url often represents
    a particular instance of an object.  For example, /people/john may be
    used to represent a particular person, John.

    To enable this behavior for a particular Controller, set the modelName
    variable to something that can be used as a keyword name in python.

    If there is no url to process, then the following views will be used:

    GET: index
    POST: create
    DELETE: destroy_all
    PUT: update_all

    If there is a url to process, then the first part of the url will be used
    as the model parameter (and passed in as a keyword to whatever view is
    finally called).  By default, the model parameter will be assumed to be
    whatever is between the first two slashes, but that behavior can be
    controlled by the splitId() method.

    If after splitting out the model parameter, there is more url to parse,
    then the urls dictionary will be used to determine how to process the rest
    of the url.  Otherwise, the following views will be used:

    GET: get
    PUT: update
    POST: process
    DELETE: destroy

    Example:

    class BookController(Controller):
        modelName = 'bookName'
        urls = {'chapter' : ChapterController}

        def get(self, request, bookName):
            # get book with name bookName and return some representation of it
            # return Response

        def index(self, request):
            # list all books and return some representation
            # return Response

        def destroy(self, request, bookName):
            # get and delete bookName
            # return "Deleted" response or redirect to index.

    class RootController(Controller):
        urls = {'books' : BookController }

    The following urls would call the following methods:

    GET /books/ - BookController.index
    GET /books/Snow+Crash - BookController.get with bookName="Snow Crash"
    DELETE /books/Snow+Crash - BookController.destroy with bookName="Snow Crash"
    DELETE /books - 404 because destroy_all is not implemented

    @cvar modelRegex: Controls the way model ids are parsed out of urls.
    Defaults to '[^/]*' which treats anything between two /'s as the model
    name, (the empty string will be used if two /s are right next to each
    other.)  If you wish to fully control the model parsing, you can override
    the splitId method.

    @cvar processSuburls: defaults to False.  If set to True, any extra
    remaining url (after processing the modelName if any) will be ignored and
    instead stored in request.unparsedPath.  The view to be returned will be
    processed as if there were no url remaining to be parsed.
    """

    def index(self, request, *args, **kwargs):
        raise NotImplementedError

    def process(self, request, *args, **kwargs):
        raise NotImplementedError

    def create(self, request, *args, **kwargs):
        raise NotImplementedError

    def get(self, request, *args, **kwargs):
        raise NotImplementedError

    def destroy(self, request, *args, **kwargs):
        raise NotImplementedError

    def update(self, request, *args, **kwargs):
        raise NotImplementedError
<commit_msg>Rearrange Controller stubs and add some missing ones.<commit_after>#
# Copyright (c) 2008 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.rpath.com/permanent/licenses/CPL-1.0.
#
# This program is distributed in the hope that it will be useful, but
# without any warranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#
import re
import urllib

class _Controller(object):

    # Declarative configuration variables.  The following variables control
    # the behavior of the controller.  See documentation of Controller
    # subclass for what they do.
    modelName = None
    modelRegex = '[^/]*'
    processSuburls = False
    urls = None

    def __init__(self, parent, path, subhandlerParams=None):
        """

        """
        self.parent = parent
        if parent:
            self._url = '%s/%s' % (parent._url, path)
            self.root = parent.root
        else:
            self._url = ''
            self.root = self

        if self.modelName:
            self.baseMethods = dict(POST='create',
                                    DELETE='destroy_all',
                                    PUT='update_all',
                                    GET='index')
            self.modelMethods = dict(POST='process',
                                GET='get',
                                PUT='update',
                                DELETE='destroy')
        else:
            self.baseMethods = dict(POST='process',
                                    GET='index',
                                    PUT='update',
                                    DELETE='destroy')

        if not subhandlerParams:
            subhandlerParams = []
        self.urls = self._initializeUrls(self.urls, subhandlerParams)

    def _initializeUrls(self, urls, subhandlerParams):
        if not urls:
            return {}
        newUrls = {}
        for key, handler in urls.items():
            if isinstance(handler, str):
                newUrls[key] = getattr(self, handler)
            elif isinstance(handler, dict):
                d = {}
                for method, handlerStr in handler.iteritems():
                    d[method] = getattr(self, handlerStr)
                newUrls[key] = d
            else:
                newUrls[key] = handler(self, key, *subhandlerParams)
        return newUrls

    def url(self, request, location, *args):
        return request.url(location, *args)

    def splitId(self, url):
        match = re.match('/?(%s)/?(.*|)' % self.modelRegex, urllib.unquote(url))
        if match:
            return match.groups()
        raise NotImplementedError

    def splitSubdir(self, url):
        if url[0] == '/':
            url = url[1:]
        parts = url.split('/', 1)
        return (parts + [''])[0:2]

    def getView(self, method, url):
        # FIXME: this should separate into one part that dispatches
        # to the right depth (getController)
        # and a second part that assumes that the current controller
        # is the right one (getView body)
        return self.getController(method, url, (), {})

    def getController(self, method, url, args, kwargs):
        if not url or url == '/':
            viewFnName = self.baseMethods.get(method, None)
            if viewFnName:
                viewFnName = getattr(self, viewFnName)
                return viewFnName, '', args, kwargs
            else:
                raise NotImplementedError
        elif self.modelName:
            modelId, newUrl = self.splitId(url)
            kwargs[self.modelName] = modelId
            return self.getControllerWithId(method, newUrl, args, kwargs)
        else:
            subDir, newUrl = self.splitSubdir(url)
            return self.getNextController(method, subDir, newUrl, args, kwargs)

    def getControllerWithId(self, method, url, args, kwargs):
        controller = None
        if url:
            subDir, newUrl  = self.splitSubdir(url)
            if self.urls and subDir in self.urls:
                controller = self.urls[subDir]
                if isinstance(controller, dict):
                    if method in controller:
                        controller = controller[method]
                    else:
                        raise NotImplementedError
                if hasattr(controller, 'getController'):
                    return controller.getController(method, newUrl,
                                                    args, kwargs)
                return controller, newUrl, args, kwargs
        if not url or self.processSuburls:
            controller = self.modelMethods.get(method, None)
            if controller:
                controller = getattr(self, controller)
                return controller, url, args, kwargs
        raise NotImplementedError

    def getNextController(self, method, subDir, url, args, kwargs):
        if self.urls and subDir in self.urls:
            controller = self.urls[subDir]
            if isinstance(controller, dict):
                if method in controller:
                    controller = controller[method]
            if hasattr(controller, 'getController'):
                return controller.getController(method, url, args, kwargs)
            if hasattr(controller, '__call__'):
                return controller, url, args, kwargs
        raise NotImplementedError

class RestController(_Controller):
    """
    Controller object.  Contains logic for determining
    what view to render.  Also often contains the views that are called
    as methods of this class.

    Any url parsing is controlled by the urls dictionary (described below)
    If there is no url to parse, the following methods are called for each
    HTTP method.  The default implementations raise NotImplementedError,
    which is automatically translated to a 404 response.

    GET: index
    POST: process
    PUT: update
    DELETE: destroy

    These methods will be called with a request object as the first parameter.
    The remainder parameters will be controlled by the process of parsing
    the url structures, but in general will be keywords determined by the
    model controllers that parsed parts of the url structure to get to the
    current controller (see the modelName description for more details).

    The behavior is controlled by several class variables.

    @cvar urls: A dictionary that describes how the controller should
    process the leftmost part of the url.  The keys of the dictionary are
    strings that map to the leftmost part of the url (by default, the part
    between the leftmost slashes).

    * If the value is not a string or a dictionary, it should be a subclass
    of the Controller class (or something that acts like a controller class).

    Example:

    If your top level controller contains:

    {'books'  : BooksController,
     'movies' : MoviesController}

    Then any request to /books will be passed to the BooksController and
    any request to /movies will be passed to the MoviesController.

    * If the value is a string, the string should correspond to a method of the
    current class.  This method will be returned as the view if and only if
    the current controller has parsed the remainder of the url.

    Example:

    If your urls for your top level controller contains:

    { 'people' : 'list_people'}

    And your controller class contains a method:

    def list_people(request):
        return Response('People in this database: john, mary, sue')

    Then the list_people view will be used for the request /people/, but
    not for /people/some/url or /people/

    * If the value is a dictionary, the keys of this subdictionary should be
    http methods (GET, POST, PUT, DELETE), and the values should be either
    strings or subclasses of the controller class as above.

    Example:

    With the following urls dictionary:

    urls = {'invitation'  : { 'POST' : 'send_invitation',
                              'GET'  : 'get_invitation'}}

    A GET request to '/invitation/' will use the 'get_invitation' method,
    a POST request will use the 'send_invitation' method, and a DELETE request
    will return a 404 RequestNotFound error code.

    @cvar modelName: contains the name of the model that this controller
    parses for.  Changes the parsing and dispatching behavior of the controller.
    Also results in the url section parsed as the model being passed into the
    view as a keyword.  The keyword name is the value stored in modelName,
    and the keyword value is the string parsed from the url.

    When creating REST APIs, part of the url often represents
    a particular instance of an object.  For example, /people/john may be
    used to represent a particular person, John.

    To enable this behavior for a particular Controller, set the modelName
    variable to something that can be used as a keyword name in python.

    If there is no url to process, then the following views will be used:

    GET: index
    POST: create
    DELETE: destroy_all
    PUT: update_all

    If there is a url to process, then the first part of the url will be used
    as the model parameter (and passed in as a keyword to whatever view is
    finally called).  By default, the model parameter will be assumed to be
    whatever is between the first two slashes, but that behavior can be
    controlled by the splitId() method.

    If after splitting out the model parameter, there is more url to parse,
    then the urls dictionary will be used to determine how to process the rest
    of the url.  Otherwise, the following views will be used:

    GET: get
    PUT: update
    POST: process
    DELETE: destroy

    Example:

    class BookController(Controller):
        modelName = 'bookName'
        urls = {'chapter' : ChapterController}

        def get(self, request, bookName):
            # get book with name bookName and return some representation of it
            # return Response

        def index(self, request):
            # list all books and return some representation
            # return Response

        def destroy(self, request, bookName):
            # get and delete bookName
            # return "Deleted" response or redirect to index.

    class RootController(Controller):
        urls = {'books' : BookController }

    The following urls would call the following methods:

    GET /books/ - BookController.index
    GET /books/Snow+Crash - BookController.get with bookName="Snow Crash"
    DELETE /books/Snow+Crash - BookController.destroy with bookName="Snow Crash"
    DELETE /books - 404 because destroy_all is not implemented

    @cvar modelRegex: Controls the way model ids are parsed out of urls.
    Defaults to '[^/]*' which treats anything between two /'s as the model
    name, (the empty string will be used if two /s are right next to each
    other.)  If you wish to fully control the model parsing, you can override
    the splitId method.

    @cvar processSuburls: defaults to False.  If set to True, any extra
    remaining url (after processing the modelName if any) will be ignored and
    instead stored in request.unparsedPath.  The view to be returned will be
    processed as if there were no url remaining to be parsed.
    """

    ## Base methods
    # POST
    def create(self, request, *args, **kwargs):
        raise NotImplementedError
    # GET (also non-model)
    def index(self, request, *args, **kwargs):
        raise NotImplementedError
    # PUT
    def update_all(self, request, *args, **kwargs):
        raise NotImplementedError
    # DELETE
    def destroy_all(self, request, *args, **kwargs):
        raise NotImplementedError

    ## Model & non-model methods
    # POST
    def process(self, request, *args, **kwargs):
        raise NotImplementedError
    # GET (model only)
    def get(self, request, *args, **kwargs):
        raise NotImplementedError
    # PUT
    def update(self, request, *args, **kwargs):
        raise NotImplementedError
    # DELETE
    def destroy(self, request, *args, **kwargs):
        raise NotImplementedError
<|endoftext|>


<commit_before>import click
import yaml

mine = """Daniel Alabi
Fotis Psallidas
Gabriel Ryan
Hamed Nilforoshan
Haoci Zhang
Ian Yiran Huang
James Sands
Kevin Lin
Rahul Khanna
Thibault Sellam
Yiliang Shi
Yiru Chen
Zhengjie Miao"""
mine = set([auth.strip().lower() for auth in mine.split("\n")])

def format_auth(auth):
  parts = auth.split()
  lastname = parts[-1]
  rest = " ".join(parts[:-1])
  name = "%s. %s" % (lastname[0], rest)
  if auth.lower() in mine:
    return "\\underline{\\bf %s}" % name
  else:
    return name

def format_auths(auths):
  return ", ".join(map(format_auth, auths))

def print_pub(pub):
  try:
    auths = pub.get("authors", "")
    auths = [auth.strip() for auth in auths.split(",")]
    auths = format_auths(auths)
    title = pub.get("title", "")
    title = title.strip(".")
    conf = pub.get("conf", "")
    conf = conf.strip(".")
    return "%s. ``{\\it %s.}'' %s." % (auths, title, conf)
  except Exception as e:
    print e
    print pub
    raise e

def get_year(pub):
  for v in pub['conf'].strip().split():
    try:
      return int(v)
    except:
      pass
  return -1

@click.command()
@click.argument("pubfname")
def main(pubfname):
  """
  Give the YML pubs file from the website
  """
  with open(pubfname, "r") as f:
    try:
      data = yaml.load(f)
    except Exception as e:
      print e
      return

  data.sort(key=get_year, reverse=True)
  for i, pub in enumerate(data):
    pub = print_pub(pub)
    print "\\smallskip $[%d]$ & \\smallskip %s\\\\" % (i+1, pub)

if __name__ == "__main__":
  main()
<commit_msg>lazy commit msg<commit_after>import click
import yaml

mine = """Daniel Alabi
Fotis Psallidas
Gabriel Ryan
Hamed Nilforoshan
Haoci Zhang
Ian Yiran Huang
James Sands
Kevin Lin
Rahul Khanna
Thibault Sellam
Yiliang Shi
Yiru Chen
Zhengjie Miao"""
mine = set([auth.strip().lower() for auth in mine.split("\n")])

def format_auth(auth):
  parts = auth.split()
  lastname = parts[-1]
  rest = " ".join(parts[:-1])
  name = "%s. %s" % (lastname[0], rest)
  if auth.lower() in mine:
    return "\\underline{\\bf %s}" % name
  else:
    return name

def format_auths(auths):
  return ", ".join(map(format_auth, auths))

def print_pub(pub):
  try:
    auths = pub.get("authors", "")
    auths = [auth.strip() for auth in auths.split(",")]
    auths = format_auths(auths)
    title = pub.get("title", "")
    title = title.strip(".")
    conf = pub.get("conf", "")
    conf = conf.strip(".")
    return "%s. ``{\\it %s.}'' %s." % (auths, title, conf)
  except Exception as e:
    print e
    print pub
    raise e

def get_year(pub):
  for v in pub['conf'].strip().split():
    try:
      return int(v)
    except:
      pass
  return None

@click.command()
@click.argument("pubfname")
def main(pubfname):
  """
  Give the YML pubs file from the website
  """
  with open(pubfname, "r") as f:
    try:
      data = yaml.load(f)
    except Exception as e:
      print e
      return

  data = filter(get_year, data)
  data.sort(key=get_year, reverse=True)
  for i, pub in enumerate(data):
    pub = print_pub(pub)
    print "\\smallskip $[%d]$ & \\smallskip %s\\\\" % (i+1, pub)

if __name__ == "__main__":
  main()
<|endoftext|>


<commit_before>"""PyroDaemon: Wrapper class around pyro daemon

__author__ = "gemalto http://www.gemalto.com"

Copyright 2001-2011 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com

This file is part of pyscard.

pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
"""

import signal
from threading import Thread
import time

import Pyro.core
import Pyro.naming

class PyroDaemon:
    """Singleton class to wrap the pyro daemon."""

    class _PyroDaemon:
        """The pyro daemon actual wrapper class.

        A single instance of this class is created
        by the public PyroDaemon class.
        """
        def __init__(self):
            self.daemon = Pyro.core.Daemon()
            self.handler = signal.signal( signal.SIGINT, self )
            ns=Pyro.naming.NameServerLocator().getNS()
            self.daemon.useNameServer(ns)

        def __call__(self, signame, sf):
            """Ctrl+c handler that will gracefully shutdown the server
            upon Ctrl+C signal"""
            print 'PyroDaemon Ctrl+C handler'
            self.daemon.shutdown(True)
            time.sleep(1)
            self.handler( signame, sf )

        def connect(self,object,name=None):
            return self.daemon.connect(object,name)

        def disconnect(self,object):
            return self.daemon.disconnect(object)

        def start(self):
            """start pyro daemon."""
            self.daemon.requestLoop()

    # the singleton
    instance = None

    def __init__(self):
        if not PyroDaemon.instance:
            PyroDaemon.instance = PyroDaemon._PyroDaemon()

    def __getattr__( self, name ):
        return getattr( self.instance, name )

class PyroDaemonThread(Thread):
    """Thread running the Pyro daemon server.
    """

    def __init__(self):
        """Initialize pyro event server with command line arguments.
        For a complete list of command line arguments, see pyro documentation
        for pyro-es start script."""
        Thread.__init__( self )
        self.setDaemon( True )
        self.setName( 'smartcard.pyro.server.PyroDaemonThread' )
        self.daemon = PyroDaemon()

    def run(self):
        """Starts Pyro daemon."""
        self.daemon.start()

<commit_msg>Fix PEP8 warnings<commit_after>"""PyroDaemon: Wrapper class around pyro daemon

__author__ = "gemalto http://www.gemalto.com"

Copyright 2001-2011 gemalto
Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com

This file is part of pyscard.

pyscard is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

pyscard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with pyscard; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
"""

import signal
from threading import Thread
import time

import Pyro.core
import Pyro.naming

class PyroDaemon:
    """Singleton class to wrap the pyro daemon."""

    class _PyroDaemon:
        """The pyro daemon actual wrapper class.

        A single instance of this class is created
        by the public PyroDaemon class.
        """
        def __init__(self):
            self.daemon = Pyro.core.Daemon()
            self.handler = signal.signal(signal.SIGINT, self)
            ns = Pyro.naming.NameServerLocator().getNS()
            self.daemon.useNameServer(ns)

        def __call__(self, signame, sf):
            """Ctrl+c handler that will gracefully shutdown the server
            upon Ctrl+C signal"""
            print 'PyroDaemon Ctrl+C handler'
            self.daemon.shutdown(True)
            time.sleep(1)
            self.handler(signame, sf)

        def connect(self, object, name=None):
            return self.daemon.connect(object, name)

        def disconnect(self, object):
            return self.daemon.disconnect(object)

        def start(self):
            """start pyro daemon."""
            self.daemon.requestLoop()

    # the singleton
    instance = None

    def __init__(self):
        if not PyroDaemon.instance:
            PyroDaemon.instance = PyroDaemon._PyroDaemon()

    def __getattr__(self, name):
        return getattr(self.instance, name)

class PyroDaemonThread(Thread):
    """Thread running the Pyro daemon server.
    """

    def __init__(self):
        """Initialize pyro event server with command line arguments.
        For a complete list of command line arguments, see pyro documentation
        for pyro-es start script."""
        Thread.__init__(self)
        self.setDaemon(True)
        self.setName('smartcard.pyro.server.PyroDaemonThread')
        self.daemon = PyroDaemon()

    def run(self):
        """Starts Pyro daemon."""
        self.daemon.start()
<|endoftext|>


<commit_before>
import os
import datetime

import osnap.const
import osnap.util

class MakeNSIS:
    # basic format is from:
    # http://nsis.sourceforge.net/A_simple_installer_with_start_menu_shortcut_and_uninstaller

    def __init__(self, defines, file_path, project_packages=[]):
        self.defines = defines  # ordered dict with the defines
        self.file_path = file_path
        self.project_packages = project_packages
        self.file = None
        # we run this in a special subfolder so put the installers one level up
        self.installers_folder = os.path.join('..', 'installers')
        osnap.util.rm_mk_tree(self.installers_folder)

    def write_line(self, l):
        self.file.write(l)
        self.file.write('\n')

    def write_all(self):
        self.file = open(self.file_path, 'w')
        self.write_line('')
        self.write_line('# *** DO NOT EDIT ***')
        self.write_line('# Programmatically generated by %s on %s.' % (__file__, str(datetime.datetime.now())))
        self.write_line('')
        for define in self.defines:
            self.write_line('!define %s %s' % (define, self.defines[define]))
        self.header()
        self.pages()
        self.admin()
        self.install()
        self.uninstall()
        self.file.close()

    def header(self):
        self.write_line('')
        self.write_line('RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)')
        self.write_line('InstallDir "$PROGRAMFILES\${COMPANYNAME}\${APPNAME}"')
        self.write_line('LicenseData "LICENSE"')
        self.write_line("# This will be in the installer/uninstaller's title bar")
        self.write_line('Name "${COMPANYNAME} - ${APPNAME}"')
        self.write_line('Icon "${APPNAME}.ico"')
        self.write_line('outFile "%s\${APPNAME}_installer.exe"' % self.installers_folder)
        self.write_line('')
        self.write_line('!include LogicLib.nsh')

    def pages(self):
        # child classes can override this if they have a different set of pages
        self.write_line('')
        self.write_line('page license')
        self.write_line('page directory')
        self.write_line('Page instfiles')

    def admin(self):
        self.write_line('')
        self.write_line('!macro VerifyUserIsAdmin')
        self.write_line('UserInfo::GetAccountType')
        self.write_line('pop $0')
        self.write_line('${If} $0 != "admin" ;Require admin rights on NT4+')
        self.write_line('        messageBox mb_iconstop "Administrator rights required!"')
        self.write_line('        setErrorLevel 740 ;ERROR_ELEVATION_REQUIRED')
        self.write_line('        quit')
        self.write_line('${EndIf}')
        self.write_line('!macroend')
        self.write_line('')
        self.write_line('function .onInit')
        self.write_line('	setShellVarContext all')
        self.write_line('	!insertmacro VerifyUserIsAdmin')
        self.write_line('functionEnd')

    def install(self):
        self.write_line('')
        self.write_line('section "install"')
        self.write_line('# Files for the install directory - to build the installer, these should be in the same directory as the install script (this file)')
        self.write_line('setOutPath $INSTDIR')
        self.write_line('# Files added here should be removed by the uninstaller (see section "uninstall")')
        self.write_line('file /r *')

        self.write_line('')
        self.write_line('# Uninstaller - See function un.onInit and section "uninstall" for configuration')
        self.write_line('writeUninstaller "$INSTDIR\\uninstall.exe"')
        self.write_line('')
        self.write_line('# Start Menu')
        self.write_line('createDirectory "$SMPROGRAMS\\${COMPANYNAME}"')
        self.write_line('createShortCut "$SMPROGRAMS\\${COMPANYNAME}\\${APPNAME}.lnk" "$INSTDIR\\${EXENAME}" "" "$INSTDIR\\${APPNAME}.ico"')
        self.write_line('')
        self.write_line('# run on Windows startup')
        self.write_line('WriteRegStr HKEY_LOCAL_MACHINE "Software\\Microsoft\\Windows\\CurrentVersion\\Run" "${APPNAME}" "$INSTDIR\\${EXENAME}"')
        self.write_line('')
        self.write_line('# Registry information for add/remove programs')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "DisplayName" "${COMPANYNAME} - ${APPNAME} - ${DESCRIPTION}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "UninstallString" "$\\"$INSTDIR\\uninstall.exe$\\""')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "QuietUninstallString" "$\\"$INSTDIR\\uninstall.exe$\\" /S"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "InstallLocation" "$INSTDIR"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "DisplayIcon" "$\\"$INSTDIR\\logo.ico$\\""')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "Publisher" "${COMPANYNAME}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "HelpLink" "${HELPURL}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "URLUpdateInfo" "${UPDATEURL}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "URLInfoAbout" "${ABOUTURL}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "DisplayVersion" "${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}"')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "VersionMajor" ${VERSIONMAJOR}')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "VersionMinor" ${VERSIONMINOR}')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "NoModify" 1')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "NoRepair" 1')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "EstimatedSize" ${INSTALLSIZE}')
        self.write_line('sectionEnd')

    def uninstall(self):
        self.write_line('# Uninstaller')
        self.write_line('function un.onInit')
        self.write_line('	SetShellVarContext all')

        self.write_line('# Verify the uninstaller - last chance to back out')
        self.write_line('	MessageBox MB_OKCANCEL "Permanantly remove ${APPNAME}?" IDOK next')
        self.write_line('		Abort')
        self.write_line('	next:')
        self.write_line('!insertmacro VerifyUserIsAdmin')
        self.write_line('functionEnd')

        self.write_line('section "uninstall"')

        self.write_line('# Remove Start Menu launcher')
        self.write_line('delete "$SMPROGRAMS\\${COMPANYNAME}\\${APPNAME}.lnk"')
        self.write_line('# Try to remove the Start Menu folder - this will only happen if it is empty')
        self.write_line('rmDir "$SMPROGRAMS\\${COMPANYNAME}"')

        self.write_line('# Remove files')
        self.write_line('RMDir /r $INSTDIR\\%s' % osnap.const.python_folder)
        for project_package in self.project_packages:
            self.write_line('RMDir /r $INSTDIR\\%s' % project_package)
        self.write_line('delete $INSTDIR\\${EXENAME}')
        self.write_line('delete $INSTDIR\\LICENSE')
        self.write_line('delete $INSTDIR\\*.ico')
        self.write_line('delete $INSTDIR\\*.md')
        self.write_line('delete $INSTDIR\\*.py')
        self.write_line('delete $INSTDIR\\*.pyd')
        self.write_line('delete $INSTDIR\\*.exe')

        self.write_line('# Always delete uninstaller as the last action')
        self.write_line('delete $INSTDIR\\uninstall.exe')

        self.write_line('# Try to remove the install directory - this will only happen if it is empty')
        self.write_line('rmDir $INSTDIR')

        self.write_line('# Remove uninstaller information from the registry')
        self.write_line('DeleteRegKey HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}"')
        self.write_line('sectionEnd')

def get_folder_size(folder_path):
    total_size = 0
    for d, _, fns in os.walk(folder_path):
        for f in fns:
            total_size += os.path.getsize(os.path.join(d, f))
    return total_size
<commit_msg>remove superfluous "installers" dir creation<commit_after>
import os
import datetime

import osnap.const
import osnap.util

class MakeNSIS:
    # basic format is from:
    # http://nsis.sourceforge.net/A_simple_installer_with_start_menu_shortcut_and_uninstaller

    def __init__(self, defines, file_path, project_packages=[]):
        self.defines = defines  # ordered dict with the defines
        self.file_path = file_path
        self.project_packages = project_packages
        self.file = None
        # we run this in a special subfolder so designate the installers one level up
        self.installers_folder = os.path.join('..', 'installers')

    def write_line(self, l):
        self.file.write(l)
        self.file.write('\n')

    def write_all(self):
        self.file = open(self.file_path, 'w')
        self.write_line('')
        self.write_line('# *** DO NOT EDIT ***')
        self.write_line('# Programmatically generated by %s on %s.' % (__file__, str(datetime.datetime.now())))
        self.write_line('')
        for define in self.defines:
            self.write_line('!define %s %s' % (define, self.defines[define]))
        self.header()
        self.pages()
        self.admin()
        self.install()
        self.uninstall()
        self.file.close()

    def header(self):
        self.write_line('')
        self.write_line('RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)')
        self.write_line('InstallDir "$PROGRAMFILES\${COMPANYNAME}\${APPNAME}"')
        self.write_line('LicenseData "LICENSE"')
        self.write_line("# This will be in the installer/uninstaller's title bar")
        self.write_line('Name "${COMPANYNAME} - ${APPNAME}"')
        self.write_line('Icon "${APPNAME}.ico"')
        self.write_line('outFile "%s\${APPNAME}_installer.exe"' % self.installers_folder)
        self.write_line('')
        self.write_line('!include LogicLib.nsh')

    def pages(self):
        # child classes can override this if they have a different set of pages
        self.write_line('')
        self.write_line('page license')
        self.write_line('page directory')
        self.write_line('Page instfiles')

    def admin(self):
        self.write_line('')
        self.write_line('!macro VerifyUserIsAdmin')
        self.write_line('UserInfo::GetAccountType')
        self.write_line('pop $0')
        self.write_line('${If} $0 != "admin" ;Require admin rights on NT4+')
        self.write_line('        messageBox mb_iconstop "Administrator rights required!"')
        self.write_line('        setErrorLevel 740 ;ERROR_ELEVATION_REQUIRED')
        self.write_line('        quit')
        self.write_line('${EndIf}')
        self.write_line('!macroend')
        self.write_line('')
        self.write_line('function .onInit')
        self.write_line('	setShellVarContext all')
        self.write_line('	!insertmacro VerifyUserIsAdmin')
        self.write_line('functionEnd')

    def install(self):
        self.write_line('')
        self.write_line('section "install"')
        self.write_line('# Files for the install directory - to build the installer, these should be in the same directory as the install script (this file)')
        self.write_line('setOutPath $INSTDIR')
        self.write_line('# Files added here should be removed by the uninstaller (see section "uninstall")')
        self.write_line('file /r *')

        self.write_line('')
        self.write_line('# Uninstaller - See function un.onInit and section "uninstall" for configuration')
        self.write_line('writeUninstaller "$INSTDIR\\uninstall.exe"')
        self.write_line('')
        self.write_line('# Start Menu')
        self.write_line('createDirectory "$SMPROGRAMS\\${COMPANYNAME}"')
        self.write_line('createShortCut "$SMPROGRAMS\\${COMPANYNAME}\\${APPNAME}.lnk" "$INSTDIR\\${EXENAME}" "" "$INSTDIR\\${APPNAME}.ico"')
        self.write_line('')
        self.write_line('# run on Windows startup')
        self.write_line('WriteRegStr HKEY_LOCAL_MACHINE "Software\\Microsoft\\Windows\\CurrentVersion\\Run" "${APPNAME}" "$INSTDIR\\${EXENAME}"')
        self.write_line('')
        self.write_line('# Registry information for add/remove programs')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "DisplayName" "${COMPANYNAME} - ${APPNAME} - ${DESCRIPTION}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "UninstallString" "$\\"$INSTDIR\\uninstall.exe$\\""')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "QuietUninstallString" "$\\"$INSTDIR\\uninstall.exe$\\" /S"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "InstallLocation" "$INSTDIR"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "DisplayIcon" "$\\"$INSTDIR\\logo.ico$\\""')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "Publisher" "${COMPANYNAME}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "HelpLink" "${HELPURL}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "URLUpdateInfo" "${UPDATEURL}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "URLInfoAbout" "${ABOUTURL}"')
        self.write_line('WriteRegStr HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "DisplayVersion" "${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}"')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "VersionMajor" ${VERSIONMAJOR}')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "VersionMinor" ${VERSIONMINOR}')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "NoModify" 1')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "NoRepair" 1')
        self.write_line('WriteRegDWORD HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}" "EstimatedSize" ${INSTALLSIZE}')
        self.write_line('sectionEnd')

    def uninstall(self):
        self.write_line('# Uninstaller')
        self.write_line('function un.onInit')
        self.write_line('	SetShellVarContext all')

        self.write_line('# Verify the uninstaller - last chance to back out')
        self.write_line('	MessageBox MB_OKCANCEL "Permanantly remove ${APPNAME}?" IDOK next')
        self.write_line('		Abort')
        self.write_line('	next:')
        self.write_line('!insertmacro VerifyUserIsAdmin')
        self.write_line('functionEnd')

        self.write_line('section "uninstall"')

        self.write_line('# Remove Start Menu launcher')
        self.write_line('delete "$SMPROGRAMS\\${COMPANYNAME}\\${APPNAME}.lnk"')
        self.write_line('# Try to remove the Start Menu folder - this will only happen if it is empty')
        self.write_line('rmDir "$SMPROGRAMS\\${COMPANYNAME}"')

        self.write_line('# Remove files')
        self.write_line('RMDir /r $INSTDIR\\%s' % osnap.const.python_folder)
        for project_package in self.project_packages:
            self.write_line('RMDir /r $INSTDIR\\%s' % project_package)
        self.write_line('delete $INSTDIR\\${EXENAME}')
        self.write_line('delete $INSTDIR\\LICENSE')
        self.write_line('delete $INSTDIR\\*.ico')
        self.write_line('delete $INSTDIR\\*.md')
        self.write_line('delete $INSTDIR\\*.py')
        self.write_line('delete $INSTDIR\\*.pyd')
        self.write_line('delete $INSTDIR\\*.exe')

        self.write_line('# Always delete uninstaller as the last action')
        self.write_line('delete $INSTDIR\\uninstall.exe')

        self.write_line('# Try to remove the install directory - this will only happen if it is empty')
        self.write_line('rmDir $INSTDIR')

        self.write_line('# Remove uninstaller information from the registry')
        self.write_line('DeleteRegKey HKLM "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${COMPANYNAME} ${APPNAME}"')
        self.write_line('sectionEnd')

def get_folder_size(folder_path):
    total_size = 0
    for d, _, fns in os.walk(folder_path):
        for f in fns:
            total_size += os.path.getsize(os.path.join(d, f))
    return total_size
<|endoftext|>


<commit_before>#!/usr/bin/env python3
#
# Copyright (C) 2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
import jmespath
import json
import unittest

from base_vyostest_shim import VyOSUnitTestSHIM

from vyos.configsession import ConfigSessionError
from vyos.util import cmd
from vyos.util import dict_search

base_path = ['nat66']
src_path = base_path + ['source']
dst_path = base_path + ['destination']

class TestNAT66(VyOSUnitTestSHIM.TestCase):
    @classmethod
    def setUpClass(cls):
        super(TestNAT66, cls).setUpClass()

        # ensure we can also run this test on a live system - so lets clean
        # out the current configuration :)
        cls.cli_delete(cls, base_path)

    def tearDown(self):
        self.cli_delete(base_path)
        self.cli_commit()

    def verify_nftables(self, nftables_search, table, inverse=False, args=''):
        nftables_output = cmd(f'sudo nft {args} list table {table}')

        for search in nftables_search:
            matched = False
            for line in nftables_output.split("\n"):
                if all(item in line for item in search):
                    matched = True
                    break
            self.assertTrue(not matched if inverse else matched, msg=search)

    def test_source_nat66(self):
        source_prefix = 'fc00::/64'
        translation_prefix = 'fc01::/64'
        self.cli_set(src_path + ['rule', '1', 'outbound-interface', 'eth1'])
        self.cli_set(src_path + ['rule', '1', 'source', 'prefix', source_prefix])
        self.cli_set(src_path + ['rule', '1', 'translation', 'address', translation_prefix])

        self.cli_set(src_path + ['rule', '2', 'outbound-interface', 'eth1'])
        self.cli_set(src_path + ['rule', '2', 'source', 'prefix', source_prefix])
        self.cli_set(src_path + ['rule', '2', 'translation', 'address', 'masquerade'])

        self.cli_set(src_path + ['rule', '3', 'outbound-interface', 'eth1'])
        self.cli_set(src_path + ['rule', '3', 'source', 'prefix', source_prefix])
        self.cli_set(src_path + ['rule', '3', 'exclude'])

        self.cli_commit()

        nftables_search = [
            ['oifname "eth1"', 'ip6 saddr fc00::/64', 'snat prefix to fc01::/64'],
            ['oifname "eth1"', 'ip6 saddr fc00::/64', 'masquerade'],
            ['oifname "eth1"', 'ip6 saddr fc00::/64', 'return']
        ]

        self.verify_nftables(nftables_search, 'ip6 nat')

    def test_source_nat66_address(self):
        source_prefix = 'fc00::/64'
        translation_address = 'fc00::1'
        self.cli_set(src_path + ['rule', '1', 'outbound-interface', 'eth1'])
        self.cli_set(src_path + ['rule', '1', 'source', 'prefix', source_prefix])
        self.cli_set(src_path + ['rule', '1', 'translation', 'address', translation_address])

        # check validate() - outbound-interface must be defined
        self.cli_commit()

        tmp = cmd('sudo nft -j list table ip6 nat')
        data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp))

        for idx in range(0, len(data_json)):
            data = data_json[idx]

            self.assertEqual(data['chain'], 'POSTROUTING')
            self.assertEqual(data['family'], 'ip6')
            self.assertEqual(data['table'], 'nat')

            iface = dict_search('match.right', data['expr'][0])
            address = dict_search('match.right.prefix.addr', data['expr'][2])
            mask = dict_search('match.right.prefix.len', data['expr'][2])
            snat_address = dict_search('snat.addr', data['expr'][3])

            self.assertEqual(iface, 'eth1')
            # check for translation address
            self.assertEqual(snat_address, translation_address)
            self.assertEqual(f'{address}/{mask}', source_prefix)

    def test_destination_nat66(self):
        destination_address = 'fc00::1'
        translation_address = 'fc01::1'
        source_address = 'fc02::1'
        self.cli_set(dst_path + ['rule', '1', 'inbound-interface', 'eth1'])
        self.cli_set(dst_path + ['rule', '1', 'destination', 'address', destination_address])
        self.cli_set(dst_path + ['rule', '1', 'translation', 'address', translation_address])

        self.cli_set(dst_path + ['rule', '2', 'inbound-interface', 'eth1'])
        self.cli_set(dst_path + ['rule', '2', 'destination', 'address', destination_address])
        self.cli_set(dst_path + ['rule', '2', 'source', 'address', source_address])
        self.cli_set(dst_path + ['rule', '2', 'exclude'])

        # check validate() - outbound-interface must be defined
        self.cli_commit()

        nftables_search = [
            ['iifname "eth1"', 'ip6 daddr fc00::1', 'dnat to fc01::1'],
            ['iifname "eth1"', 'ip6 saddr fc02::1', 'ip6 daddr fc00::1', 'return']
        ]

        self.verify_nftables(nftables_search, 'ip6 nat')

    def test_destination_nat66_prefix(self):
        destination_prefix = 'fc00::/64'
        translation_prefix = 'fc01::/64'
        self.cli_set(dst_path + ['rule', '1', 'inbound-interface', 'eth1'])
        self.cli_set(dst_path + ['rule', '1', 'destination', 'address', destination_prefix])
        self.cli_set(dst_path + ['rule', '1', 'translation', 'address', translation_prefix])

        # check validate() - outbound-interface must be defined
        self.cli_commit()

        tmp = cmd('sudo nft -j list table ip6 nat')
        data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp))

        for idx in range(0, len(data_json)):
            data = data_json[idx]

            self.assertEqual(data['chain'], 'PREROUTING')
            self.assertEqual(data['family'], 'ip6')
            self.assertEqual(data['table'], 'nat')

            iface = dict_search('match.right', data['expr'][0])
            translation_address = dict_search('dnat.addr.prefix.addr', data['expr'][3])
            translation_mask = dict_search('dnat.addr.prefix.len', data['expr'][3])

            self.assertEqual(f'{translation_address}/{translation_mask}', translation_prefix)
            self.assertEqual(iface, 'eth1')

    def test_source_nat66_required_translation_prefix(self):
        # T2813: Ensure translation address is specified
        rule = '5'
        source_prefix = 'fc00::/64'
        self.cli_set(src_path + ['rule', rule, 'source', 'prefix', source_prefix])

        # check validate() - outbound-interface must be defined
        with self.assertRaises(ConfigSessionError):
            self.cli_commit()
        self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'eth0'])

        # check validate() - translation address not specified
        with self.assertRaises(ConfigSessionError):
            self.cli_commit()

        self.cli_set(src_path + ['rule', rule, 'translation', 'address', 'masquerade'])
        self.cli_commit()

    def test_nat66_no_rules(self):
        # T3206: deleting all rules but keep the direction 'destination' or
        # 'source' resulteds in KeyError: 'rule'.
        #
        # Test that both 'nat destination' and 'nat source' nodes can exist
        # without any rule
        self.cli_set(src_path)
        self.cli_set(dst_path)
        self.cli_commit()

if __name__ == '__main__':
    unittest.main(verbosity=2)
<commit_msg>smoketest: T4631: Extend smoketes fot nat66 protocol<commit_after>#!/usr/bin/env python3
#
# Copyright (C) 2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
import jmespath
import json
import unittest

from base_vyostest_shim import VyOSUnitTestSHIM

from vyos.configsession import ConfigSessionError
from vyos.util import cmd
from vyos.util import dict_search

base_path = ['nat66']
src_path = base_path + ['source']
dst_path = base_path + ['destination']

class TestNAT66(VyOSUnitTestSHIM.TestCase):
    @classmethod
    def setUpClass(cls):
        super(TestNAT66, cls).setUpClass()

        # ensure we can also run this test on a live system - so lets clean
        # out the current configuration :)
        cls.cli_delete(cls, base_path)

    def tearDown(self):
        self.cli_delete(base_path)
        self.cli_commit()

    def verify_nftables(self, nftables_search, table, inverse=False, args=''):
        nftables_output = cmd(f'sudo nft {args} list table {table}')

        for search in nftables_search:
            matched = False
            for line in nftables_output.split("\n"):
                if all(item in line for item in search):
                    matched = True
                    break
            self.assertTrue(not matched if inverse else matched, msg=search)

    def test_source_nat66(self):
        source_prefix = 'fc00::/64'
        translation_prefix = 'fc01::/64'
        self.cli_set(src_path + ['rule', '1', 'outbound-interface', 'eth1'])
        self.cli_set(src_path + ['rule', '1', 'source', 'prefix', source_prefix])
        self.cli_set(src_path + ['rule', '1', 'translation', 'address', translation_prefix])

        self.cli_set(src_path + ['rule', '2', 'outbound-interface', 'eth1'])
        self.cli_set(src_path + ['rule', '2', 'source', 'prefix', source_prefix])
        self.cli_set(src_path + ['rule', '2', 'translation', 'address', 'masquerade'])

        self.cli_set(src_path + ['rule', '3', 'outbound-interface', 'eth1'])
        self.cli_set(src_path + ['rule', '3', 'source', 'prefix', source_prefix])
        self.cli_set(src_path + ['rule', '3', 'exclude'])

        self.cli_commit()

        nftables_search = [
            ['oifname "eth1"', 'ip6 saddr fc00::/64', 'snat prefix to fc01::/64'],
            ['oifname "eth1"', 'ip6 saddr fc00::/64', 'masquerade'],
            ['oifname "eth1"', 'ip6 saddr fc00::/64', 'return']
        ]

        self.verify_nftables(nftables_search, 'ip6 nat')

    def test_source_nat66_address(self):
        source_prefix = 'fc00::/64'
        translation_address = 'fc00::1'
        self.cli_set(src_path + ['rule', '1', 'outbound-interface', 'eth1'])
        self.cli_set(src_path + ['rule', '1', 'source', 'prefix', source_prefix])
        self.cli_set(src_path + ['rule', '1', 'translation', 'address', translation_address])

        # check validate() - outbound-interface must be defined
        self.cli_commit()

        tmp = cmd('sudo nft -j list table ip6 nat')
        data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp))

        for idx in range(0, len(data_json)):
            data = data_json[idx]

            self.assertEqual(data['chain'], 'POSTROUTING')
            self.assertEqual(data['family'], 'ip6')
            self.assertEqual(data['table'], 'nat')

            iface = dict_search('match.right', data['expr'][0])
            address = dict_search('match.right.prefix.addr', data['expr'][2])
            mask = dict_search('match.right.prefix.len', data['expr'][2])
            snat_address = dict_search('snat.addr', data['expr'][3])

            self.assertEqual(iface, 'eth1')
            # check for translation address
            self.assertEqual(snat_address, translation_address)
            self.assertEqual(f'{address}/{mask}', source_prefix)

    def test_destination_nat66(self):
        destination_address = 'fc00::1'
        translation_address = 'fc01::1'
        source_address = 'fc02::1'
        self.cli_set(dst_path + ['rule', '1', 'inbound-interface', 'eth1'])
        self.cli_set(dst_path + ['rule', '1', 'destination', 'address', destination_address])
        self.cli_set(dst_path + ['rule', '1', 'translation', 'address', translation_address])

        self.cli_set(dst_path + ['rule', '2', 'inbound-interface', 'eth1'])
        self.cli_set(dst_path + ['rule', '2', 'destination', 'address', destination_address])
        self.cli_set(dst_path + ['rule', '2', 'source', 'address', source_address])
        self.cli_set(dst_path + ['rule', '2', 'exclude'])

        # check validate() - outbound-interface must be defined
        self.cli_commit()

        nftables_search = [
            ['iifname "eth1"', 'ip6 daddr fc00::1', 'dnat to fc01::1'],
            ['iifname "eth1"', 'ip6 saddr fc02::1', 'ip6 daddr fc00::1', 'return']
        ]

        self.verify_nftables(nftables_search, 'ip6 nat')

    def test_destination_nat66_protocol(self):
        translation_address = '2001:db8:1111::1'
        source_prefix = '2001:db8:2222::/64'
        dport = '4545'
        sport = '8080'
        tport = '5555'
        proto = 'tcp'
        self.cli_set(dst_path + ['rule', '1', 'inbound-interface', 'eth1'])
        self.cli_set(dst_path + ['rule', '1', 'destination', 'port', dport])
        self.cli_set(dst_path + ['rule', '1', 'source', 'address', source_prefix])
        self.cli_set(dst_path + ['rule', '1', 'source', 'port', sport])
        self.cli_set(dst_path + ['rule', '1', 'protocol', proto])
        self.cli_set(dst_path + ['rule', '1', 'translation', 'address', translation_address])
        self.cli_set(dst_path + ['rule', '1', 'translation', 'port', tport])

        # check validate() - outbound-interface must be defined
        self.cli_commit()

        nftables_search = [
            ['iifname "eth1"', 'tcp dport { 4545 } ip6 saddr 2001:db8:2222::/64 tcp sport { 8080 } dnat to 2001:db8:1111::1:5555']
        ]

        self.verify_nftables(nftables_search, 'ip6 nat')

    def test_destination_nat66_prefix(self):
        destination_prefix = 'fc00::/64'
        translation_prefix = 'fc01::/64'
        self.cli_set(dst_path + ['rule', '1', 'inbound-interface', 'eth1'])
        self.cli_set(dst_path + ['rule', '1', 'destination', 'address', destination_prefix])
        self.cli_set(dst_path + ['rule', '1', 'translation', 'address', translation_prefix])

        # check validate() - outbound-interface must be defined
        self.cli_commit()

        tmp = cmd('sudo nft -j list table ip6 nat')
        data_json = jmespath.search('nftables[?rule].rule[?chain]', json.loads(tmp))

        for idx in range(0, len(data_json)):
            data = data_json[idx]

            self.assertEqual(data['chain'], 'PREROUTING')
            self.assertEqual(data['family'], 'ip6')
            self.assertEqual(data['table'], 'nat')

            iface = dict_search('match.right', data['expr'][0])
            translation_address = dict_search('dnat.addr.prefix.addr', data['expr'][3])
            translation_mask = dict_search('dnat.addr.prefix.len', data['expr'][3])

            self.assertEqual(f'{translation_address}/{translation_mask}', translation_prefix)
            self.assertEqual(iface, 'eth1')

    def test_source_nat66_required_translation_prefix(self):
        # T2813: Ensure translation address is specified
        rule = '5'
        source_prefix = 'fc00::/64'
        self.cli_set(src_path + ['rule', rule, 'source', 'prefix', source_prefix])

        # check validate() - outbound-interface must be defined
        with self.assertRaises(ConfigSessionError):
            self.cli_commit()
        self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'eth0'])

        # check validate() - translation address not specified
        with self.assertRaises(ConfigSessionError):
            self.cli_commit()

        self.cli_set(src_path + ['rule', rule, 'translation', 'address', 'masquerade'])
        self.cli_commit()

    def test_source_nat66_protocol(self):
        translation_address = '2001:db8:1111::1'
        source_prefix = '2001:db8:2222::/64'
        dport = '9999'
        sport = '8080'
        tport = '80'
        proto = 'tcp'
        self.cli_set(src_path + ['rule', '1', 'outbound-interface', 'eth1'])
        self.cli_set(src_path + ['rule', '1', 'destination', 'port', dport])
        self.cli_set(src_path + ['rule', '1', 'source', 'prefix', source_prefix])
        self.cli_set(src_path + ['rule', '1', 'source', 'port', sport])
        self.cli_set(src_path + ['rule', '1', 'protocol', proto])
        self.cli_set(src_path + ['rule', '1', 'translation', 'address', translation_address])
        self.cli_set(src_path + ['rule', '1', 'translation', 'port', tport])

        # check validate() - outbound-interface must be defined
        self.cli_commit()

        nftables_search = [
            ['oifname "eth1"', 'ip6 saddr 2001:db8:2222::/64 tcp dport { 9999 } tcp sport { 8080 } snat to 2001:db8:1111::1:80']
        ]

        self.verify_nftables(nftables_search, 'ip6 nat')

    def test_nat66_no_rules(self):
        # T3206: deleting all rules but keep the direction 'destination' or
        # 'source' resulteds in KeyError: 'rule'.
        #
        # Test that both 'nat destination' and 'nat source' nodes can exist
        # without any rule
        self.cli_set(src_path)
        self.cli_set(dst_path)
        self.cli_commit()

if __name__ == '__main__':
    unittest.main(verbosity=2)
<|endoftext|>


<commit_before># Copyright (c) 2013 Spotify AB
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

import numpy
from common import TestCase
from annoy import AnnoyIndex
import os
import h5py
try:
    from urllib import urlretrieve
except ImportError:
    from urllib.request import urlretrieve # Python 3

class SeedTest(TestCase):
    def test_seeding(self):
        f = 10
        X = numpy.random.rand(1000, f)
        Y = numpy.random.rand(50, f)

        indexes = []
        for i in range(2):
            index = AnnoyIndex(f, 'angular')
            index.set_seed(42)
            for j in range(X.shape[0]):
                index.add_item(j, X[j])

            index.build(10)
            indexes.append(index)

        for k in range(Y.shape[0]):
            self.assertEquals(indexes[0].get_nns_by_vector(Y[k], 100),
                              indexes[1].get_nns_by_vector(Y[k], 100))

    def test_historical(self):
        dataset = "fashion-mnist-784-euclidean"
        url = 'http://vectors.erikbern.com/%s.hdf5' % dataset
        vectors_fn = os.path.join('test', dataset + '.hdf5')
        if not os.path.exists(vectors_fn):
            urlretrieve(url, vectors_fn)

        dataset_f = h5py.File(vectors_fn, 'r')
        f = dataset_f['train'].shape[1]

        # Round 1, checking that we recover historical results with the default seed.
        annoy = AnnoyIndex(f, 'euclidean')
        for i, v in enumerate(dataset_f['train']):
            annoy.add_item(i, v)

        annoy.build(10)
        self.assertEquals(annoy.get_nns_by_item(0, 10),
                          [0, 27655, 18247, 9936, 48748, 26244, 49961, 38909, 55767, 38152])
        self.assertEquals(annoy.get_nns_by_item(10, 10),
                          [10, 48474, 15493, 18055, 54960, 32003, 13842, 24831, 24497, 26585])
        self.assertEquals(annoy.get_nns_by_item(100, 10),
                          [100, 19840, 28600, 4270, 49340, 38437, 26777, 57981, 25662, 46624])
        self.assertEquals(annoy.get_nns_by_item(1000, 10),
                          [1000, 55577, 20213, 379, 17810, 12464, 35858, 53879, 56078, 25054])
        self.assertEquals(annoy.get_nns_by_item(10000, 10),
                          [10000, 46719, 50444, 15672, 36818, 30426, 4374, 58080, 10938, 25192])

        # Round 2, checking that changing the seed actually does have an effect.
        annoy2 = AnnoyIndex(f, 'euclidean')
        for i, v in enumerate(dataset_f['train']):
            annoy2.add_item(i, v)

        annoy2.set_seed(0)
        annoy2.build(10)
        self.assertEquals(annoy2.get_nns_by_item(0, 10),
                          [0, 25719, 27655, 55310, 18247, 9936, 48748, 49961, 35683, 47527])
        self.assertEquals(annoy2.get_nns_by_item(10, 10),
                          [10, 48474, 15493, 18055, 54960, 32003, 14603, 13842, 24831, 24497])
        self.assertEquals(annoy2.get_nns_by_item(100, 10),
                          [100, 19840, 28600, 4270, 49340, 38437, 26777, 57981, 52911, 25662])
        self.assertEquals(annoy2.get_nns_by_item(1000, 10),
                          [1000, 55577, 20213, 379, 17810, 35858, 53879, 56078, 25054, 20816])
        self.assertEquals(annoy2.get_nns_by_item(10000, 10),
                          [10000, 50444, 15672, 36818, 30426, 4374, 58080, 25192, 47437, 25348])

<commit_msg>Revert "Added unit tests with hard-coded historical results."<commit_after># Copyright (c) 2013 Spotify AB
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

import numpy
from common import TestCase
from annoy import AnnoyIndex

class SeedTest(TestCase):
    def test_seeding(self):
        f = 10
        X = numpy.random.rand(1000, f)
        Y = numpy.random.rand(50, f)

        indexes = []
        for i in range(2):
            index = AnnoyIndex(f, 'angular')
            index.set_seed(42)
            for j in range(X.shape[0]):
                index.add_item(j, X[j])

            index.build(10)
            indexes.append(index)

        for k in range(Y.shape[0]):
            self.assertEquals(indexes[0].get_nns_by_vector(Y[k], 100),
                              indexes[1].get_nns_by_vector(Y[k], 100))

<|endoftext|>


<commit_before>from openid.consumer.stores import ConsumerAssociation
from openid import util

import string
import random

allowed_handle = []
for c in string.printable:
    if c not in string.whitespace:
        allowed_handle.append(c)
allowed_handle = ''.join(allowed_handle)

allowed_secret = ''.join(map(chr, range(256)))

allowed_nonce = string.letters + string.digits

rand = random.SystemRandom()

def rnd(n, pop):
    chars = []
    for _ in xrange(n):
        chars.append(rand.choice(pop))
    return ''.join(chars)

def generateHandle(n):
    return rnd(n, allowed_handle)

def generateSecret(n):
    return rnd(n, allowed_secret)

def generateNonce():
    return rnd(8, allowed_nonce)

def testStore(store):
    server_url = 'http://www.myopenid.com/openid'
    secret = generateSecret(20)
    handle = generateHandle(128)

    assoc = ConsumerAssociation.fromExpiresIn(600, server_url, handle, secret)

    missing_assoc = store.getAssociation(server_url, handle)

    assert missing_assoc is None

    store.storeAssociation(assoc)
    retrieved_assoc = store.getAssociation(server_url, handle)
    assert retrieved_assoc.secret == assoc.secret
    assert retrieved_assoc.handle == assoc.handle
    assert retrieved_assoc.server_url == assoc.server_url

    retrieved_assoc = store.getAssociation(server_url, handle)
    assert retrieved_assoc.secret == assoc.secret
    assert retrieved_assoc.handle == assoc.handle
    assert retrieved_assoc.server_url == assoc.server_url

    store.storeAssociation(assoc)
    retrieved_assoc = store.getAssociation(server_url, handle)
    assert retrieved_assoc.secret == assoc.secret
    assert retrieved_assoc.handle == assoc.handle
    assert retrieved_assoc.server_url == assoc.server_url

    wrong_handle = generateHandle(128)
    retrieved_assoc = store.getAssociation(server_url, wrong_handle)
    assert retrieved_assoc is None

    present = store.removeAssociation(server_url, wrong_handle)
    assert not present

    present = store.removeAssociation(server_url, handle)
    assert present

    present = store.removeAssociation(server_url, handle)
    assert not present

    # Nonce functions

    # Random nonce (not in store)
    nonce1 = generateNonce()

    # A nonce is not present by default
    present = store.useNonce(nonce1)
    assert not present

    # Storing once causes useNonce to return True the first, and only
    # the first, time it is called after the store.
    store.storeNonce(nonce1)
    present = store.useNonce(nonce1)
    assert present
    present = store.useNonce(nonce1)
    assert not present

    # Storing twice has the same effect as storing once.
    store.storeNonce(nonce1)
    store.storeNonce(nonce1)
    present = store.useNonce(nonce1)
    assert present
    present = store.useNonce(nonce1)
    assert not present

if __name__ == '__main__':
    from openid.consumer import filestore
    import tempfile
    import shutil
    temp_dir = tempfile.mkdtemp()
    try:
        store = filestore.FilesystemOpenIDStore(temp_dir)
        testStore(store)
    finally:
        shutil.rmtree(temp_dir)
<commit_msg>[project @ Add auth key tests and comment association tests]<commit_after>from openid.consumer.stores import ConsumerAssociation
from openid import util

import string
import random

allowed_handle = []
for c in string.printable:
    if c not in string.whitespace:
        allowed_handle.append(c)
allowed_handle = ''.join(allowed_handle)

allowed_secret = ''.join(map(chr, range(256)))

allowed_nonce = string.letters + string.digits

rand = random.SystemRandom()

def rnd(n, pop):
    chars = []
    for _ in xrange(n):
        chars.append(rand.choice(pop))
    return ''.join(chars)

def generateHandle(n):
    return rnd(n, allowed_handle)

def generateSecret(n):
    return rnd(n, allowed_secret)

def generateNonce():
    return rnd(8, allowed_nonce)

def testStore(store):
    ### Association functions

    server_url = 'http://www.myopenid.com/openid'
    secret = generateSecret(20)
    handle = generateHandle(128)

    assoc = ConsumerAssociation.fromExpiresIn(600, server_url, handle, secret)

    # Make sure that a missing association returns no result
    missing_assoc = store.getAssociation(server_url, handle)
    assert missing_assoc is None

    # Check that after storage, getting returns the same result
    store.storeAssociation(assoc)
    retrieved_assoc = store.getAssociation(server_url, handle)
    assert retrieved_assoc.secret == assoc.secret
    assert retrieved_assoc.handle == assoc.handle
    assert retrieved_assoc.server_url == assoc.server_url

    # more than once
    retrieved_assoc = store.getAssociation(server_url, handle)
    assert retrieved_assoc.secret == assoc.secret
    assert retrieved_assoc.handle == assoc.handle
    assert retrieved_assoc.server_url == assoc.server_url

    # Storing more than once has no ill effect
    store.storeAssociation(assoc)
    retrieved_assoc = store.getAssociation(server_url, handle)
    assert retrieved_assoc.secret == assoc.secret
    assert retrieved_assoc.handle == assoc.handle
    assert retrieved_assoc.server_url == assoc.server_url

    # Getting with the same url but a wrong handle returns no result
    wrong_handle = generateHandle(128)
    retrieved_assoc = store.getAssociation(server_url, wrong_handle)
    assert retrieved_assoc is None

    # and does not affect the existing data
    retrieved_assoc = store.getAssociation(server_url, handle)
    assert retrieved_assoc.secret == assoc.secret
    assert retrieved_assoc.handle == assoc.handle
    assert retrieved_assoc.server_url == assoc.server_url

    # Removing an association that does not exist returns not present
    present = store.removeAssociation(server_url, wrong_handle)
    assert not present

    # Removing an association that is present returns present
    present = store.removeAssociation(server_url, handle)
    assert present

    # but not present on subsequent calls
    present = store.removeAssociation(server_url, handle)
    assert not present

    # One association with server_url
    store.storeAssociation(assoc)
    assoc2 = ConsumerAssociation.fromExpiresIn(
        600, server_url, wrong_handle, secret)
    store.storeAssociation(assoc2)

    # After storing an association with a different handle, but the
    # same server_url, the most recent association is available. There
    # is no guarantee either way about the first association.
    retrieved_assoc = store.getAssociation(server_url, wrong_handle)
    assert retrieved_assoc.server_url == server_url
    assert retrieved_assoc.handle == wrong_handle
    assert retrieved_assoc.secret == secret

    ### Nonce functions

    # Random nonce (not in store)
    nonce1 = generateNonce()

    # A nonce is not present by default
    present = store.useNonce(nonce1)
    assert not present

    # Storing once causes useNonce to return True the first, and only
    # the first, time it is called after the store.
    store.storeNonce(nonce1)
    present = store.useNonce(nonce1)
    assert present
    present = store.useNonce(nonce1)
    assert not present

    # Storing twice has the same effect as storing once.
    store.storeNonce(nonce1)
    store.storeNonce(nonce1)
    present = store.useNonce(nonce1)
    assert present
    present = store.useNonce(nonce1)
    assert not present

    ### Auth key functions

    # There is no key to start with, so generate a new key and return it.
    key = store.getAuthKey()

    # The second time around should return the same as last time.
    key2 = store.getAuthKey()
    assert key == key2
    assert len(key) == store.AUTH_KEY_LEN

    # The store rejects keys of the wrong length
    bad_auth_key = ''
    try:
        store.setAuthKey(bad_auth_key)
    except ValueError:
        pass
    else:
        assert False, 'Bad auth key set successfully'

    # The store allows you to set a specific key even if there is
    # already a key present.
    new_key = generateSecret(store.AUTH_KEY_LEN)
    store.setAuthKey(new_key)
    key = store.getAuthKey()
    assert key == new_key

if __name__ == '__main__':
    from openid.consumer import filestore
    import tempfile
    import shutil
    temp_dir = tempfile.mkdtemp()
    try:
        store = filestore.FilesystemOpenIDStore(temp_dir)
        testStore(store)
    finally:
        shutil.rmtree(temp_dir)
<|endoftext|>


<commit_before>"""
An extension to the Django web framework that provides version control for model instances.

Developed by Dave Hall.

<http://www.etianen.com/>
"""

try:
    import django  # noqa
except ImportError:  # pragma: no cover
    # The top-level API requires Django, which might not be present if setup.py
    # is importing reversion to get __version__.
    pass
else:
    from reversion.errors import (  # noqa
        RevertError,
        RevisionManagementError,
        RegistrationError,
    )
    from reversion.revisions import (  # noqa
        is_active,
        is_manage_manually,
        get_user,
        set_user,
        get_comment,
        set_comment,
        get_date_created,
        set_date_created,
        add_meta,
        add_to_revision,
        create_revision,
        register,
        is_registered,
        unregister,
        get_registered_models,
    )

__version__ = VERSION = (2, 0, 9)
<commit_msg>v2.0.10<commit_after>"""
An extension to the Django web framework that provides version control for model instances.

Developed by Dave Hall.

<http://www.etianen.com/>
"""

try:
    import django  # noqa
except ImportError:  # pragma: no cover
    # The top-level API requires Django, which might not be present if setup.py
    # is importing reversion to get __version__.
    pass
else:
    from reversion.errors import (  # noqa
        RevertError,
        RevisionManagementError,
        RegistrationError,
    )
    from reversion.revisions import (  # noqa
        is_active,
        is_manage_manually,
        get_user,
        set_user,
        get_comment,
        set_comment,
        get_date_created,
        set_date_created,
        add_meta,
        add_to_revision,
        create_revision,
        register,
        is_registered,
        unregister,
        get_registered_models,
    )

__version__ = VERSION = (2, 0, 10)
<|endoftext|>