- added validate_key_type(), validate_key(), add_person(), set_primary_key(), delete()
[plcapi.git] / PLC / Keys.py
1 from types import StringTypes
2
3 from PLC.Faults import *
4 from PLC.Parameter import Parameter
5 from PLC.Debug import profile
6 from PLC.Table import Row, Table
7 import PLC
8 class Key(Row):
9     """
10     Representation of a row in the keys table. To use, instantiate with a 
11     dict of values. Update as you would a dict. Commit to the database 
12     with sync().
13     """
14     table_name = 'keys'
15     primary_key = 'key_id'
16     fields = {
17         'key_id': Parameter(int, "Key type"),
18         'key_type': Parameter(str, "Key type"),
19         'key': Parameter(str, "Key value"),
20         'is_blacklisted': Parameter(str, "Key has been blacklisted and is forever unusable"),
21         'person_id': Parameter(int, "Identifier of the account that created this key"),
22         'is_primary': Parameter(bool, "Is the primary key for this account")
23         }
24
25     def __init__(self, api, fields):
26         Row.__init__(self, fields)
27         self.api = api
28         
29    
30     def validate_key_type(self, key_type):
31         # 1. ssh is the only supported key type
32         if not key_type or not key_type in ['ssh']:
33                 raise PLCInvalidArgument, "Invalid key type"
34
35         return key_type
36
37     def validate_key(self, key):
38         # 1. key must not be blacklisted
39
40         # Remove leading and trailing spaces
41         key = key.strip()
42         # Make sure key is not blank 
43         if not len(key) > 0:
44                 raise PLCInvalidArgument, "Invalid key"
45
46         rows = self.api.db.selectall("SELECT is_blacklisted from keys" \
47                                      " WHERE key = '%s'" % key)
48         if rows:
49                 raise PLCInvalidArgument, "Key is blacklisted"  
50         return key
51     
52     def add_person(self, person, commit = True):
53         """
54         Associate key with person
55         """
56         
57         assert 'key_id' in self
58         assert isinstance(person, PLC.Persons.Person)
59         assert 'person_id' in person
60
61         person_id = person['person_id']
62         key_id = self['key_id']
63         
64         if not 'person_id' in self:
65                 assert key_id not in person['key_ids']
66                 
67                 self.api.db.do("INSERT INTO person_key (person_id, key_id)" \
68                                " VALUES (%d, %d)" % (person_id, key_id) )
69                 if commit:
70                         self.api.db.commit()
71
72                 self['person_id'] = person_id
73                 person['key_id'] = key_id 
74
75     def set_primary_key(self, person, commit = True):
76         """
77         Set the primary key for a person
78         """
79
80         assert 'key_id' in self
81         assert isinstance(person, PLC.Persons.Person)
82         assert 'person_id' in person
83
84         person_id = person['person_id']
85         key_id = self['key_id']
86         assert person_id in [self['person_id']]
87
88         self.api.db.do("UPDATE person_key SET is_primary = False" \
89                        " WHERE person_id = %d " % person_id)
90         self.api.db.do("UPDATE person_key SET is_primary = True" \
91                        " WHERE person_id = %d AND key_id = %d" \
92                        % (person_id, key_id) )
93
94         if commit:
95                 self.api.db.commit()
96         
97         self['is_primary'] = True
98         
99     def delete(self, commit = True):
100         """
101         Delete key from the database
102         """
103         assert 'key_id' in self
104         
105         for table in ['person_key', 'keys']:
106                 self.api.db.do("DELETE FROM %s WHERE key_id = %d" % \
107                  (table, self['key_id']), self)
108
109         if commit:
110                 self.api.db.commit()
111
112 class Keys(Table):
113     """
114     Representation of row(s) from the keys table in the
115     database.
116     """
117
118     def __init__(self, api, key_id_list = None):
119         self.api = api
120         
121         sql = "SELECT %s FROM keys LEFT JOIN person_key USING (%s) " % \
122                 (", ".join(Key.fields), Key.primary_key)
123         
124         if key_id_list:
125                 sql += " WHERE key_id IN (%s)" %  ", ".join(map(str, key_id_list))
126
127         rows = self.api.db.selectall(sql)
128         
129         for row in rows:        
130                 self[row['key_id']] = Key(api, row)
131                 
132