async def api_register_user(*, email, name, passwd): if not name or not name.strip(): raise APIValueError('name') if not email or not _RE_EMAIL.match(email): raise APIValueError('email') if not passwd or not _RE_SHA1.match(passwd): raise APIValueError('passwd') users = await User.findAll('email=?', [email]) if len(users) > 0: raise APIValueError('register:failed', 'email', 'Email is already in used.') uid = next_id() sha1_passwd = '%s:%s' % (uid, passwd) user = User(id=uid, name=name.strip(), email=email, passwd=hashlib.sha1(sha1_passwd.encode('utf-8')).hexdigest(), image='http://www.gravatar.com/avatar/%s?d=mm&s=120' % hashlib.md5(email.encode('utf-8')).hexdigest()) await user.save() r = web.Response() r.set_cookie(COOKIE_NAME, user2cookie(user, 86400), max_age=86400, httponly=True) user.passwd = '******' r.content_type = 'application/json' r.body = json.dumps(user, ensure_ascii=False).encode('utf-8') return r
async def authenticate(*, email, passwd): if not email: raise APIValueError('email', '请填写邮箱地址') if not passwd: raise APIValueError('passwd', '请填写密码') users = await User.findAll('email=?', [email]) if len(users) == 0: raise APIValueError('email', '邮箱不存在') user = users[0] # check passwd: sha1 = hashlib.sha1() sha1.update(user.id.encode('utf-8')) sha1.update(b':') sha1.update(passwd.encode('utf-8')) if user.passwd != sha1.hexdigest(): raise APIValueError('passwd', '密码错误') # authenticate ok, set cookie: r = web.Response() r.set_cookie(COOKIE_NAME, user2cookie(user, 86400), max_age=86400, httponly=True) user.passwd = '******' r.content_type = 'application/json' r.body = json.dumps(user, ensure_ascii=False).encode('utf-8') return r
def api_ceate_user(*, name, password): ''' Create user. Request url: [POST /api/users] Post data: name: user name password: user password ''' if not name or not name.strip(): raise APIValueError('name') if not password or not password.strip(): raise APIValueError('password') name = name.strip() password = hashlib.sha1(password.strip().encode('utf-8')).hexdigest() users = yield from User.findall(where="name='%s'" % name) if len(users) > 0: raise APIError(errors.EUSER_ALREADY_EXISTS, 'User %s already exist' % name) user = User(id=uuid.uuid4().hex, name=name, password=password) yield from user.save() yield from log_event(logging.INFO, event_user, event_action_add, 'Add user %s' % name) return dict(retcode=0, user=user)
def api_update_vg(id, request, *, name): ''' Update volume group. Request url [POST /api/vgs/{id}] Post data: id: volume group id name: volume group name ''' if not name or not name.strip(): raise APIValueError('name:%s' % name) if not re.match(r'^[a-z_A-Z0-9]{1,20}', name): raise APIValueError("name") vg = yield from VG.find(id) if not vg: raise APIResourceNotFoundError('vg %s' % id) yield from _vg_rename(vg.name, name) vg.name = name yield from vg.update() yield from log_event(logging.INFO, event_vg, event_action_mod, 'Update volume group name to %s.' % (vg.name)) return dict(retcode=0, vg=vg)
async def api_update_blog(id, request, *, name, summary, content): check_admin(request) blog = await Blog.find(id) if not name or not name.strip(): raise APIValueError('name', 'name cannot be empty.') if not summary or not summary.strip(): raise APIValueError('summary', 'summary cannot be empty.') if not content or not content.strip(): raise APIValueError('content', 'content cannot be empty.') blog.name = name.strip() blog.summary = summary.strip() blog.content = content.strip() await blog.update() return blog
def post_comment(id, request, *, content): user = request.__user__ blog = yield from Blogs.find(id) if not content or not content.strip(): raise APIValueError('content', 'content can not be empty') if blog is None: raise APIValueError('BLOG', 'BLOG was not found, do not fu*k this site') new_content = content comment = Comment(blog_id=blog.id, user_id=user.id, user_name=user.name, user_image=user.image, content=new_content) yield from comment.save() return dict(status='success')
async def api_create_blog(request, *, name, summary, content): check_admin(request) if not name or not name.strip(): raise APIValueError('name', 'name cannot be empty.') if not summary or not summary.strip(): raise APIValueError('summary', 'summary cannot be empty.') if not content or not content.strip(): raise APIValueError('content', 'content cannot be empty.') blog = Blog(user_id=request.__user__.id, user_name=request.__user__.name, user_image=request.__user__.image, name=name.strip(), summary=summary.strip(), content=content.strip()) await blog.save() return blog
def api_create_vg(*, name, pv): ''' Create volume group. Request url [POST /api/vgs] Post data: name: volume group name pv: physical volume array in json format. example: [/dev/md0, /dev/md1...] ''' if not name or not name.strip(): raise APIValueError('name') if not re.match(r'^[a-z_A-Z0-9]{1,20}', name): raise APIValueError("name") vg = yield from VG.findall(where="name='%s'" % name) if vg: return dict(retcode=501, message='Volume group %s already exists' % name) pvs_name = json.loads(pv) for pv_name in pvs_name: if not os.path.exists(pv_name): return dict(retcode=502, message='Invalid pv %s' % pv_name) if len(pvs_name) == 0: return dict(retcode=503, message='No physical volume') vgs = yield from _vg_create(name, pvs_name) if vgs is None or len(vgs) == 0: return dict(retcode=504, message='Create volume group %s failure' % name) for vg in vgs: if vg.name != name: continue # save vg yield from vg.save() yield from log_event(logging.INFO, event_vg, event_action_add, 'Create volume group %s.' % (vg.name)) return dict(retcode=0, vg=vg) return dict(retcode=504, message='Create volume group %s failure' % name)
def api_lvm_create(*, name, vgname, size): ''' Create lvm. Request url:[POST /api/lvms] Post data: name: lvm name vgname: volume group name. reference:/api/vgs size: lvm size ends with unit, lvm size unit. [K, M, G, T, P]. example: 3.5T ''' if not name or not name.strip(): raise APIValueError('name') if not re.match(r'^[a-z_A-Z0-9]{1,20}', name): raise APIValueError("name") if not size or not size.strip(): raise APIValueError('size') if not size[-1] in ['K', 'M', 'G', 'T', 'P']: raise APIValueError('size unit value should be [K,M,G,T,P]') # validate vg vgs = yield from _vg_display() vgs_name = [vg.name for vg in vgs] if vgname not in vgs_name: raise APIResourceNotFoundError("volumne group '%s' not found" % vgname) lvms = yield from _lvm_create(name, vgname, size) if lvms is None or len(lvms) == 0: return dict(retcode=604, message='create lvm failure') for lvm in lvms: if lvm.name != name: continue # save lvm yield from lvm.save() yield from log_event(logging.INFO, event_lvm, event_action_add, 'Create LVM %s, size:%s.' % (lvm.name, size)) return dict(retcode=0, lvm=lvm) return dict(retcode=604, message='create lvm failure')
def api_create_blog(request, *, blog_title, blog_tag, summary, content): check_user_admin_flag(request) if not blog_title or not blog_title.strip(): raise APIValueError('blog_title', 'blog_title can not be empty') if not summary or not summary.strip(): raise APIValueError('summary', 'summary can not be empty') if not content or not content.strip(): raise APIValueError('content', 'content can not be empty') if not blog_tag or not blog_tag.strip(): blog_tag = '默认分类' # 注意 这里请求了request 的user 等信息 实际上是因为在上面进行了确认 blog = Blogs(user_id=request.__user__.id, user_name=request.__user__.name, user_image=request.__user__.image, blog_title=blog_title.strip(), summary=summary.strip(), content=content.strip(), tag=blog_tag) yield from blog.save() # 现在需要新增一个 保存后返回文章链接的功能 blogs = yield from Blogs.find_all(OrderBy='created_time desc') recent_blog = blogs[0] blog_url = '/index.html?item=' + recent_blog['id'] return {'new_url': blog_url}
def api_register_user(*, email, name, password): if not name or not name.strip(): raise APIValueError('name') if not password or not _re_sha1.match(password): raise APIValueError('password') if not email or not _re_email.match(email): raise APIValueError('email') users = yield from User.find_all('email=?', [email]) # 排除注册过的email if len(users) > 0: raise APIError('register failed ', 'email', 'The email has already existed') uid = next_id() row_password_string = '%s:%s' % (uid, password) # 这个email 是因为用了gravatar的服务 只要email在上面有头像 你的博客里面就可以出现了 虽然没有什么叼用 user = User(id=uid, name=name.strip(), email=email, password=hashlib.sha1( row_password_string.encode('utf-8')).hexdigest(), image='/static/images/default-user.jpg') # % hashlib.md5(email.encode('utf-8')).hexdigest() yield from user.save() r = web.Response() encode_str = user.name + '-' + user.email fake_string = base64.b64encode(encode_str.encode(encoding="utf-8")) r.set_cookie('FakeCookie', fake_string.decode('utf-8'), max_age=86400, httponly=False) r.set_cookie(COOKIE_NAME, user2cookie(user, 86400), max_age=86400, httponly=True) r.body = json.dumps(user, ensure_ascii=False).encode('utf-8') return r
def authenticate(*, email, password): if not email: raise APIValueError('email') if not password: raise APIValueError('password') users = yield from User.find_all('email=?', [email]) if len(users) == 0: raise APIValueError('email', 'email not found') user = users[0] sha1 = hashlib.sha1() # 这里根据加密方式还原 sha1.update(user.id.encode('utf-8')) sha1.update(':'.encode('utf-8')) sha1.update(password.encode('utf-8')) if user.password != sha1.hexdigest(): raise APIValueError('password', 'Invalid password') # 确认ok那么就开始设置cookie r = web.Response() # 这个http only 是为了防止跨域 xss 漏洞 # 很尴尬的是 我弃用jinja模板现在又要给他启用 否则我要启用session验证(原因是为了安全) encode_str = user.name + '-' + user.email fake_string = base64.b64encode(encode_str.encode(encoding="utf-8")) r.set_cookie('FakeCookie', fake_string.decode('utf-8'), max_age=86400, httponly=False) r.set_cookie(COOKIE_NAME, user2cookie(user, 86400), max_age=86400, httponly=True) # 我测试看能不能设置多个cookie 一个仅仅用于前端的某些显示使用 结果证实是可以的 我可以不用session验证啦 user.password = '******' r.content_type = 'application/json' r.body = json.dumps(user, ensure_ascii=False).encode('utf-8') # 有点意思 其实这里用dict 返回一样可以被jinja 模板给encode 被js 解析 return r
def api_update_lvm(id, request, *, name): ''' Update lvm. Request url [POST /api/lvms/{id}] Post data: id: lvm id name: lvm name ''' if not name or not name.strip(): raise APIValueError('name:%s' % name) if not re.match(r'^[a-z_A-Z0-9]{1,20}', name): raise APIValueError("name") lvm = yield from LVM.find(id) if not lvm: raise APIResourceNotFoundError('vg %s' % id) yield from _lvm_rename(lvm.path, name) lvm.name = name yield from lvm.update() yield from log_event(logging.INFO, event_lvm, event_action_mod, 'Update LVM name to %s.' % (lvm.name)) return dict(retcode=0, lvm=lvm)
async def api_create_comment(id, request, *, content): user = request.__user__ if user is None: raise APIPermissionError('Please signin first.') if not content or not content.strip(): raise APIValueError('content') blog = await Blog.find(id) if blog is None: raise APIResourceNotFoundError('Blog') comment = Comment(blog_id=blog.id, user_id=user.id, user_name=user.name, user_image=user.image, content=content.strip()) await comment.save() return comment
def api_update_user(id, request, *, password): ''' Update user. Request url: [POST /api/users/{id}] Post data: password: user new password ''' user = yield from User.find(id) if user is None: raise APIResourceNotFoundError(id) if not password or not password.strip(): raise APIValueError('Password can not be empty') user.password = hashlib.sha1(password.encode('utf-8')).hexdigest() yield from user.update() yield from log_event(logging.INFO, event_user, event_action_mod, 'Update user %s password' % user.name) return dict(retcode=0, user=user)
def api_create_target(*, name, tid, type, lun): ''' Create target. Request url:[POST /api/targets] Post data: name: target name tid: target id in numeric. ensure the tid is unique when exists multiple ipsan server type: 1-lvm; 2-disk; lun: lun device array. example: [/dev/vg0/lv0,...] ... ''' if name is None or not name.strip(): raise APIValueError('name') if not _re_target_name.match(name): raise APIValueError('name') if not type.isnumeric(): raise APIValueError("type") if not tid.isnumeric(): raise APIValueError("target id") tid = int(tid) if tid <= 0 or tid > 1000: # assume max tid is 1000 raise APIValueError("target id(number)") ct = int(type) # valid lun luns = json.loads(lun) if not luns or len(luns) == 0: raise APIValueError("lun") for lun in luns: if not os.path.exists(lun): raise APIValueError('Lun %s not exists' % lun) target = yield from Target.findall(where="tid=%s" % tid) if target and len(target) > 0: return dict(retcode=701, message='target id %s already exists' % tid) target = yield from Target.findall(where="name='%s'" % name) if target and len(target) > 0: return dict(retcode=700, message='target %s already exists' % name) # get tid from user input # tid = yield from _get_next_tid() # if tid is None: # return dict(retcode=703, message='too many targets in this server') name = _iqn % name cmd = _tgtadm_new_target % (str(tid), name) # create target r = subprocess.call(cmd.split(' ')) if r != 0: return dict(retcode=701, message='create target error') # enable all client to access target cmd = _tgtadm_acl_all % str(tid) r = subprocess.call(cmd.split(' ')) if r != 0: return dict(retcode=701, message='enable target ACL to all failure') # add lun lid = 0 #lun id start from 1 for lun in luns: lid += 1 cmd = _tgtadm_new_lun % (str(tid), str(lid), lun) r = subprocess.call(cmd.split(' ')) if r != 0: return dict(retcode=702, message='add lun %s to target error' % lun) targets = yield from _get_targets() for target in targets: if target.iqn == name: target.id = uuid.uuid4().hex yield from target.save() for lun in target.luns: lun.id = uuid.uuid4().hex lun.tid = target.id yield from lun.save() if ct == 2: r = yield from Disk.findall(where="device='%s'" % lun.name) if r and len(r) > 0: disk = r[0] disk.used_by = target.id disk.used_for = 2 # used for target yield from disk.update() # save target _save_target(target) yield from log_event(logging.INFO, event_target, event_action_add, 'Create target %s.' % (target.iqn)) return dict(retcode=0, target=target) # create target error return dict(retcode=701, target='create target error')
def api_create_array(*, name, level, chunk, disk, spare): ''' Create array. Request url[POST /api/arrays] Post data: name: array name. level: array level. support RAID0, RAID1, RAID5, RAID6, RAID10. chunk: array chunk size. such as 64K,128K, 256K,512K. power of 2. disks: disk device array in json format. such as [/dev/sdb, /dev/sdc, /dev/sdd...] spares: spare disk device array in json format. ''' if not re.match(r'^[a-z_A-Z0-9]{1,20}', name): raise APIValueError("name") array = yield from Array.findall(where="name='%s'" % name) if array: return dict(retcode=401, message='Array %s already exists' % name) data_devname= json.loads(disk) spare_devname = json.loads(spare) disks = [] spares = [] # valid disk for dev in data_devname: r = yield from Disk.findall(where="device='%s'" % dev) if not r or len(r) == 0: raise APIResourceNotFoundError('%s' % dev) disks.append(r[0]) for dev in spares: r = yield from Disk.findall(where="device='%s'" % dev) if not r or len(r) == 0: raise APIResourceNotFoundError('%s' % dev) spares.append(r[0]) if len(disks) == 0: return dict(retcode=403, message='No available data disk') if not level.isnumeric(): raise APIValueError('level') at_least_disk = {0: 2, 1: 2, 5: 3, 6: 3, 10: 2} level = int(level) if level not in at_least_disk: return dict(retcode=402, message='Invalid raid level %s' % level) if len(disks) < at_least_disk[level]: return dict(retcode=404, message='Raid %s need at least %s disks' % (level, at_least_disk[level])) array_device = yield from _array_create(level, data_devname, chunk, spare_devname) if array_device is None: return dict(retcode=405, message='Create array failure.No available device') array = Array(name=name, device=array_device, level=level, chunk_size=chunk, created_at=int(time.time())) array = yield from _array_detail(array) yield from array.save() # update array id of each array disk for disk in disks: disk.used_by = array.id disk.used_for = 1 # 1 for raid yield from disk.update() yield from log_event(logging.INFO, event_array, event_action_add, 'Create array %s.level:%s,data disk:%s,spare:%s' % (name, level, ','.join(data_devname), ','.join(spare_devname))) return dict(retcode=0, array=array)