cc1  v2.1
CC1 source code docs
 All Classes Namespaces Files Functions Variables Pages
key.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 # @COPYRIGHT_begin
3 #
4 # Copyright [2010-2014] Institute of Nuclear Physics PAN, Krakow, Poland
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 # @COPYRIGHT_end
19 
20 ##
21 # @package src.clm.views.user.key
22 # @alldecoratedby{src.clm.utils.decorators.user_log}
23 #
24 
25 import base64
26 import hashlib
27 import os
28 import re
29 import subprocess
30 
31 from clm.models.key import Key
32 from clm.utils.decorators import user_log
33 from clm.utils.exception import CLMException
34 
35 
36 @user_log(log=False)
37 ##
38 #
39 # Returns the requested Key's. Key must belong to the caller.
40 #
41 # @clmview_user
42 # @param_post{name,string} Requested Key's name
43 #
44 # @response{dict} Key.dict property of the requested key
45 #
46 def get(cm_id, caller_id, name):
47  try:
48  k = Key.objects.filter(user_id__exact=caller_id).filter(name__exact=name)[0]
49  except:
50  raise CLMException('ssh_key_get')
51 
52  return k.dict
53 
54 
55 @user_log(log=False)
56 ##
57 #
58 # Returns caller's Keys.
59 #
60 # @clmview_user
61 # @response{list(dict)} Key.dict property of each Key
62 #
63 def get_list(cm_id, caller_id):
64  return [k.dict for k in Key.objects.filter(user_id__exact=caller_id)]
65 
66 
67 @user_log(log=True)
68 ##
69 #
70 # Generates Key pair named @prm{name} for caller. Public part of that Key is
71 # stored in database with specified name, whereas content of the private Key
72 # part is returned. Neither public, nor private part of the key is saved to
73 # file. Private part of the key is never stored - it's only returned once.
74 #
75 # @clmview_user
76 # @param_post{name,string} Key's name
77 #
78 # @response{string} content of private Key's file
79 #
80 def generate(cm_id, caller_id, name):
81  keys_limit = False
82  try:
83  from clm.settings import SSH_KEYS_LIMIT
84  keys_limit = SSH_KEYS_LIMIT
85  except:
86  pass
87  if keys_limit and len(Key.objects.filter(user_id__exact=caller_id)) > keys_limit:
88  raise CLMException('ssh_key_limit')
89  if Key.objects.filter(user_id__exact=caller_id).filter(name__exact=name).exists():
90  raise CLMException('ssh_key_already_exist')
91  if subprocess.call(['ssh-keygen', '-q', '-f', '/tmp/' + str(caller_id) + '_' + name, '-N', '']) != 0:
92  raise CLMException('ssh_key_generate')
93  f_prv = open('/tmp/' + str(caller_id) + '_' + name, 'r')
94  f_pub = open('/tmp/' + str(caller_id) + '_' + name + '.pub', 'r')
95  k = Key()
96  k.user_id = caller_id
97  k.data = f_pub.read()
98  k.name = name
99  s = hashlib.md5(base64.b64decode(k.data.split()[1])).hexdigest()
100  k.fingerprint = ':'.join([s[i:i + 2] for i in xrange(0, 30, 2)])
101  try:
102  k.save()
103  except:
104  raise CLMException('ssh_key_generate')
105  finally:
106  private = f_prv.read()
107  os.remove('/tmp/' + str(caller_id) + '_' + name)
108  os.remove('/tmp/' + str(caller_id) + '_' + name + '.pub')
109 
110  return private
111 
112 
113 @user_log(log=True)
114 ##
115 #
116 # Adds given Key named @prm{name} with content @prm{key} to caller's keys list.
117 #
118 # @clmview_user
119 # @param_post{key,string} key's content
120 # @param_post{name,string} key's name
121 #
122 # @response{None}
123 #
124 def add(cm_id, caller_id, key, name):
125  keys_limit = False
126  try:
127  from clm.settings import SSH_KEYS_LIMIT
128  keys_limit = SSH_KEYS_LIMIT
129  except:
130  pass
131  if keys_limit and len(Key.objects.filter(user_id__exact=caller_id)) > keys_limit:
132  raise CLMException('ssh_key_limit')
133  k = Key()
134  k.user_id = caller_id
135  k.data = key
136  k.name = name
137  r = re.search('ssh-rsa (.*) (.*)', key)
138  if not r:
139  raise CLMException('ssh_key_format')
140  s = hashlib.md5(base64.b64decode(r.groups()[0])).hexdigest()
141  k.fingerprint = ':'.join([s[i:i + 2] for i in xrange(0, 30, 2)])
142  try:
143  k.save()
144  except:
145  raise CLMException('ssh_key_add')
146 
147 
148 @user_log(log=True)
149 ##
150 #
151 # Method deletes specified key named @prm{name}.
152 #
153 # @clmview_user
154 # @param_post{name,string} name of the Key to delete
155 # @response{None}
156 #
157 def delete(cm_id, caller_id, name):
158  try:
159  Key.objects.filter(user_id__exact=caller_id).filter(name__exact=name).delete()
160  except:
161  raise CLMException('ssh_key_delete')
162 
163 
164 @user_log(log=True)
165 ##
166 #
167 # Method removes key with id \c id.
168 #
169 # @clmview_user
170 # @param_post{key_ids,list(int)} list of Key ids to delete
171 #
172 # @response{dict} \n fields:
173 # @dictkey{status,string}
174 # @dictkey{data,dict}
175 #
176 def delete_by_id(cm_id, caller_id, key_ids):
177  results = []
178  for key_id in key_ids:
179  try:
180  Key.objects.filter(user_id__exact=caller_id).filter(id__exact=key_id).delete()
181  results.append({'status': 'ok', 'data': ''})
182  except:
183  results.append({'status': 'ssh_key_delete', 'data': ''})
184 
185  return results
186