summaryrefslogtreecommitdiffstats
path: root/ipsilon/info/common.py
blob: a3a297f61199cc10b849fdd20e177f683a54a364 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/python
#
# Copyright (C) 2014 Ipsilon Project Contributors
#
# See the file named COPYING for the project license

from ipsilon.util.log import Log
from ipsilon.util.plugin import PluginInstaller, PluginLoader
from ipsilon.util.plugin import PluginObject, PluginConfig


class InfoProviderBase(PluginConfig, PluginObject):

    def __init__(self, *pargs):
        PluginConfig.__init__(self)
        PluginObject.__init__(self, *pargs)

    def get_user_attrs(self, user):
        raise NotImplementedError


class InfoMapping(Log):

    def __init__(self):
        self.standard_attributes = {
            'fullname': 'Full Name',
            'nickname': 'Nickname',
            'surname': 'Last Name',
            'firstname': 'First Name',
            'title': 'Title',
            'dob': 'Date of Birth',
            'email': 'E-mail Address',
            'gender': 'Gender',
            'postcode': 'Postal Code',
            'street': 'Street Address',
            'state': 'State or Province',
            'country': 'Country',
            'phone': 'Telephone Number',
            'language': 'Language',
            'timezone': 'Time Zone',
        }
        self.mapping = dict()

    def set_mapping(self, attrs_map):
        self.mapping = attrs_map

    def display_name(self, name):
        if name in self.standard_attributes:
            return self.standard_attributes[name]
        return name

    def map_attrs(self, attrs):
        s = dict()
        e = dict()
        for a in attrs:
            if a in self.mapping:
                s[self.mapping[a]] = attrs[a]
            else:
                e[a] = attrs[a]

        return s, e


FACILITY = 'info_config'


class Info(Log):

    def __init__(self, site):
        self._site = site

        plugins = PluginLoader(Info, FACILITY, 'InfoProvider')
        plugins.get_plugin_data()
        self._site[FACILITY] = plugins

        available = plugins.available.keys()
        self.debug('Available info providers: %s' % str(available))

        for item in plugins.enabled:
            self.debug('Login plugin in enabled list: %s' % item)
            if item not in plugins.available:
                self.debug('Info Plugin %s not found' % item)
                continue
            plugins.available[item].enable()

    def get_user_attrs(self, user, requested=None):
        plugins = self._site[FACILITY].available
        result = dict()

        for _, p in plugins.items():
            if requested is None:
                if not p.is_enabled:
                    continue
            else:
                if requested != p.name:
                    continue
            result = p.get_user_attrs(user)
            if result:
                break

        return result


class InfoProviderInstaller(object):

    def __init__(self):
        self.facility = FACILITY
        self.ptype = 'info'
        self.name = None

    def install_args(self, group):
        raise NotImplementedError

    def configure(self, opts):
        raise NotImplementedError


class InfoProviderInstall(object):

    def __init__(self):
        pi = PluginInstaller(InfoProviderInstall, FACILITY)
        self.plugins = pi.get_plugins()
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
=begin

= net/protocol.rb

written by Minero Aoki <aamine@dp.u-netsurf.ne.jp>

This library is distributed under the terms of the Ruby license.
You can freely distribute/modify this library.


== Net::Protocol

the abstruct class for Internet protocol

=== Super Class

Object

=== Class Methods

: new( address = 'localhost', port = nil )
  This method Creates a new protocol object.

: start( address = 'localhost', port = nil, *protoargs )
: start( address = 'localhost', port = nil, *protoargs ) {|proto| .... }
  This method creates a new Protocol object and opens a session.
  equals to Net::Protocol.new( address, port ).start( *protoargs )

: Proxy( address, port )
  This method creates a proxy class of its protocol.
  Arguments are address/port of proxy host.

=== Methods

: address
  the address of connecting server (FQDN).

: port
  connecting port number

: start( *args )
: start( *args ) {|proto| .... }
  This method starts protocol. If protocol was already started,
  do nothing and returns false.

  '*args' are specified in subclasses.

  When is called as iterator, gives Protocol object to block and
  close session when block finished.

: finish
  This method ends protocol. If you call this method before protocol starts,
  it only return false without doing anything.

: active?
  true if session have been started

=end

require 'socket'


module Net

  class Protocol

    Version = '1.1.25'


    class << self

      def start( address = 'localhost', port = nil, *args )
        instance = new( address, port )

        if iterator? then
          instance.start( *args ) { yield instance }
        else
          instance.start *args
          instance
        end
      end

      def Proxy( p_addr, p_port = nil )
        p_port ||= self.port
        klass = Class.new( self )
        klass.module_eval %-

          def initialize( addr, port )
            @proxyaddr = '#{p_addr}'
            @proxyport = '#{p_port}'
            super @proxyaddr, @proxyport
            @address = addr
            @port    = port
          end

          def connect( addr = nil, port = nil )
            super @proxyaddr, @proxyport
          end
          private :connect
            
          attr_reader :proxyaddr, :proxyport
        -
        def klass.proxy?
          true
        end

        klass
      end

      def proxy?
        false
      end


      private

      def protocol_param( name, val )
        module_eval %-
          def self.#{name.id2name}
            #{val}
          end
        -
      end
        
    end


    #
    # sub-class requirements
    #
    # protocol_param command_type
    # protocol_param port
    #
    # private method do_start  (optional)
    # private method do_finish (optional)
    #

    protocol_param :port,         'nil'
    protocol_param :command_type, 'nil'
    protocol_param :socket_type,  '::Net::Socket'


    def initialize( addr = nil, port = nil )
      @address = addr || 'localhost'
      @port    = port || type.port

      @active  = false
      @pipe    = nil

      @command = nil
      @socket  = nil
    end

    attr_reader :address, :port,
                :command, :socket

    def inspect
      "#<#{type} #{address}:#{port} open=#{active?}>"
    end


    def start( *args )
      return false if active?

      begin
        connect
        do_start *args
        @active = true
        yield self if iterator?
      ensure
        finish if iterator?
      end
    end

    def finish
      ret = active?

      do_finish
      disconnect
      @active = false

      ret
    end

    def active?
      @active
    end

    def set_pipe( arg )   # un-documented
      @pipe = arg
    end


    private


    def do_start
    end

    def do_finish
      @command.quit
    end


    def connect( addr = @address, port = @port )
      @socket  = type.socket_type.open( addr, port, @pipe )
      @command = type.command_type.new( @socket )
    end

    def disconnect
      @command = nil
      if @socket and not @socket.closed? then
        @socket.close
      end
      @socket  = nil
    end
    
  end

  Session = Protocol



  class Command

    def initialize( sock )
      @socket = sock
      @last_reply = nil
      @critical = false
    end

    attr_accessor :socket
    attr_reader :last_reply

    def inspect
      "#<#{type}>"
    end

    # abstract quit


    private

    # abstract get_reply()

    def check_reply( *oks )
      @last_reply = get_reply
      reply_must( @last_reply, *oks )
    end

    def reply_must( rep, *oks )
      oks.each do |i|
        if i === rep then
          return rep
        end
      end
      rep.error!
    end

    def getok( line, ok = SuccessCode )
      @socket.writeline line
      check_reply ok
    end


    def critical
      return if @critical
      @critical = true
      r = yield
      @critical = false
      r
    end

    def critical?
      @critical
    end