def _as_dict(self): """ This for internal use only. The dict will not contain created_at, updated_at and id parameters :return: """ log.info("Extracting employee data from the database") _schema = schemas.get_schema('employee_schema') schema_data = model_helper.model_dictize( db_models=(self, ), db_extras=(EmployeeExtras.objects.filter(employee=self), ), schema=_schema) schema_data['employee_id'] = schema_data['employee_id'].upper() return schema_data
def get_schema_keys_given_role(action, role, schema_name="employee_schema"): """ Get schema keys for a given role type. and action (show/update) :param schema_name: str :param action: str :param role: str :return: set """ result = [] properties = schemas.get_schema(schema_name)['properties'] for _property, value in properties.items(): if role in value[action]: result.append(_property) return set(result)
def get(self, request, errors=None, data=None): """ View to show user profile. If profile_id=None, then the profile page for logged in user :param request: django request object :param errors: errors dict if any :param data: data dict if any :return: render edit page """ context = { "type": "profile", "user": request.user, "is_superuser": request.user.is_superuser, "role": request.user.role } extra_vars = dict() extra_vars["errors"] = errors if errors else dict() try: # check create access auth.employee_create(context) extra_vars['profile'] = data if data else dict( ) # if data some validation error extra_vars["schema"] = schemas.get_schema("employee_schema") extra_vars["action"] = "create" except err.NotAuthorizedError: messages.error(request, 'You are not authorized to perform this action') log.info("Logged in user not authorized to see the page") return abort( request, code=401, error_message="You are not authorized to see this page", error_title="Not Authorized") except (err.UserNotFound, err.NotFoundError) as e: log.info(e) return abort(request, code=404, error_message="User Not found.", error_title="Not Found") except Exception as e: log.error(e) return server_error(request, code=500, error_message="Server Error. Something wrong") return render(request, 'profile/edit.html', extra_vars)
def get_schema_groups(schema_name): """ Get schema grouop given schema group :param schema_name: str :return: tuple """ _schema = schemas.get_schema(schema_name) groups = dict() for _property in _schema['properties']: _gp = _schema['properties'][_property].get('group_label', '') if _gp in groups: groups[_gp].append(_property) else: groups[_gp] = [_property] return groups
def show_employee(app_context, data_dict): """ Show employee for the given employee id or employee unique identifier. Note: Access control is given is schema in show attribute - space separated string e.g. admin hr member all - admin: show to only to admin - admin hr: show admin and to hr - admin hr member: show admin and to hr and user profile (logged in user == requested user profile) - all: show to every logged in user :param app_context: dict :param data_dict: dict (containing employee_id oir id) :return: dict """ log.info("Show employee api...") auth.employee_show(app_context) _user = app_context.get('user') role = app_context.get('role') _id = data_dict.get('id', '') _schema = schemas.get_schema('employee_schema') log.info("Showing the employee data for id: {}".format(_id)) if not _id: raise err.ValidationError({"id": "id parameter is required."}) _employee = models.Employee.get_employee_by_id(_id) # If logged in user and requesting profile are not same if role == "member": if _user.id != _employee.id: role = "all" _data = _employee.as_dict() response = dict() for _property in _schema['properties']: _show = _schema['properties'][_property].get('show', "").split(" ") if role in _show: response[_property] = _data[_property] for x in ("id", "created_at", "updated_at", "avatar"): response[x] = _data[x] return response
def get(self, request, profile_id=None): """ View to show user profile. If profile_id=None, then the profile page for logged in user :return: render page """ if profile_id == request.user.id: return redirect('profile') context = { "type": "profile", "user": request.user, "is_superuser": request.user.is_superuser, "role": request.user.role } extra_vars = dict() try: user_data = api_action.get_actions( "show_employee", context, {"id": profile_id or request.user.username}) extra_vars['profile'] = user_data extra_vars["schema"] = schemas.get_schema("employee_schema") except err.NotAuthorizedError: messages.error(request, 'You are not authorized to perform this action') log.info("Logged in user not authorized to see the page") return abort( request, code=401, error_message="You are not authorized to see this page", error_title="Not Authorized") except (err.UserNotFound, err.NotFoundError) as e: messages.error(request, 'Requested user not available') log.info(e) return abort(request, code=404, error_message="User Not found.", error_title="Not Found") except Exception as e: log.error(e) return server_error(request, code=500, error_message="Server Error. Something wrong") return render(request, 'profile/read.html', extra_vars)
def get(self, request, profile_id=None, errors=None, data=None): """ This will fetch employee edit form :return: render page """ if profile_id == request.user.id: return redirect('profile_edit') context = { "type": "profile", "user": request.user, "is_superuser": request.user.is_superuser, "role": request.user.role } extra_vars = dict() extra_vars["errors"] = errors if errors else dict() try: if profile_id: # Trying to edit some others profile _employee = models.Employee.get_employee_by_id(profile_id) else: # Edit by logged user _employee = request.user context['employee'] = _employee # Check authorization auth.employee_update(context) # if data means some validation errors if not data: user_data = api_action.get_actions( "show_employee", context, {"id": profile_id or request.user.username}) else: data['id'] = profile_id or request.user.id user_data = data extra_vars['profile'] = user_data extra_vars["schema"] = schemas.get_schema("employee_schema") extra_vars["action"] = "edit" except err.NotAuthorizedError: messages.error(request, 'You are not authorized to perform this action') log.info("Logged in user not authorized to see the page") return abort( request, code=401, error_message="You are not authorized to see this page", error_title="Not Authorized") except (err.UserNotFound, err.NotFoundError) as e: log.info(e) return abort(request, code=404, error_message="User Not found.", error_title="Not Found") except Exception as e: log.error(e) return server_error(request, code=500, error_message="Server Error. Something wrong") return render(request, 'profile/edit.html', extra_vars)
def create_employee(app_context, data_dict): """ Used to create employee and user together. Two database tables that are to be populated is Employee and Profile. The given data is validated against json schema and custom validators. If any of the items in schema are not in the table column, those data goes to the extras table according to the group given in the schema. Allowed groups in employee schema are (profile, employee - these are the table names). Access: - Admin/Super User can add a new employee. - Only super user can add user as admin role - For all the other types of employee are added as member. Schema: Schema used to create employee: employee (see register.py). :param app_context: dict (contains user information) :param data_dict: dic :return: dict success message or show_employee - api """ log.info("Checking authorization") auth.employee_create(app_context) _employee_id = data_dict.get('employee_id', '') _files = app_context.get('files', '') _show_employee = u.core_convert_to_bool( data_dict.pop('show_employee', True)) if data_dict.get('skills', ''): _skills = data_dict['skills'] if isinstance(_skills, str): # Hack for multipart/form-data?? Dont know if this is the right way # TODO: need to create a data insert pre processing pipeline data_dict['skills'] = [ s.strip().title() for s in _skills.split(",") ] log.info("Validating the given data for employee create") # Validate the data vs schema and model validate schemas.validate("employee_schema", data_dict) _properties = schemas.get_schema('employee_schema')['properties'] log.info("Creating a employee for employee id: {}".format(_employee_id)) try: with model_transaction.atomic(): employee_model = models.Employee() employee_model.username = _employee_id _extras = [] for _key in _properties: _val = data_dict.get(_key, '') if hasattr(employee_model, _key): setattr(employee_model, _key, _val) else: log.info( "Adding to extras key - employee: {}".format(_key)) _extras.append( model_helper.create_extras_table_values( extras_model=models.EmployeeExtras, connecting_key="employee", connecting_model=employee_model, key=_key, value=_val)) if _files and _files.get('upload_avatar', ''): log.info("Found avatar create..") _uploaded_avatar = _files['upload_avatar'] validators.validate_avatar_file(_uploaded_avatar) employee_model.avatar = _uploaded_avatar employee_model.save() for _md in _extras: _md.save() except Exception as e: log.error(e) raise e if _show_employee: result = show_employee(app_context, {"id": _employee_id}) else: result = { "message": "Employee with id: {} has been created successfully".format( _employee_id) } email.send_email_create_employee(to=[data_dict.get('work_email').lower()]) return result
def update_employee(app_context, data_dict): """ Update employee profile. Parameter should contain id - representing unique id of the employee of id as employee id. Only admin/hr can alter employee fields or logged in user can alter their fields. Note: Access control is given in schema in update attribute - space separated string e.g. admin hr member all - admin: Only admin can update - admin hr: Only admin and to hr can update - admin hr member: admin , hr and member can update (logged in user == requested user profile) - all: show to every logged in user :param app_context: dict :param data_dict: dict (containing fields to be updated) :return: dict success message or show_employee - api """ auth.is_authenticated(app_context) role = app_context.get('role') _show_employee = u.core_convert_to_bool( data_dict.pop('show_employee', True)) _id = data_dict.pop('id', None) _files = app_context.get('files', '') _schema = schemas.get_schema('employee_schema') log.info("Updating an employee for an id: {}".format(_id)) if data_dict.get('skills', ''): _skills = data_dict['skills'] if isinstance(_skills, str): # Hack for multipart/form-data?? Dont know if this is the right way # TODO: need to create a data insert pre processing pipeline data_dict['skills'] = [ s.strip().title() for s in _skills.split(",") ] if role == "all": err.ValidationError({"InternalError": "This should not occur."}) if not _id: raise err.ValidationError({"id": "id parameter is required."}) try: with model_transaction.atomic(): _employee = models.Employee.get_employee_by_id(_id) # Check authorization auth.employee_update({ "role": app_context.get('role'), "user": app_context.get('user'), "employee": _employee }) # Internal user only _data = _employee._as_dict() log.info("Updating the data and validating") _data.update(data_dict) schemas.validate("employee_schema", _data) # Insert operation _emp_extras = models.EmployeeExtras.objects.filter( employee=_employee) _extras = [] for _key in data_dict: if _key in _schema['properties']: try: _property = _schema['properties'][_key] _update = _property.get('update', "").split(" ") if role not in _update: raise err.NotAuthorizedError( {_key: "Not authorized to update the value"}) if hasattr(_employee, _key): setattr(_employee, _key, data_dict.get(_key)) else: for _emp_ext in _emp_extras: if _emp_ext.key == _key: _emp_ext.value = data_dict.get(_key) _extras.append(_emp_ext) break except KeyError as e: log.warning(e) pass if 'upload_avatar' in _files: log.info("Found avatar update..") _uploaded_avatar = _files['upload_avatar'] if _uploaded_avatar: validators.validate_avatar_file(_uploaded_avatar) if _employee.avatar and os.path.isfile(_employee.avatar.path): os.remove(_employee.avatar.path) _employee.avatar = _uploaded_avatar _employee.save() for _md in _extras: _md.save() except Exception as e: log.error(e) raise e if _show_employee: result = show_employee(app_context, {"id": _employee.employee_id}) else: result = { "message": "Employee with id: {} has been updated successfully".format( _employee.employee_id) } return result