def get(self, pin): # get PIN record pin_code = request.values['pin_code'] try: pin_record = Pin.query.filter(Pin.pin == pin, Pin.code == pin_code).one() except NoResultFound: abort(404) # make sure it hasn't expired if pin_record.creation_timestamp < datetime.datetime.utcnow() - datetime.timedelta(minutes = 30): return {'status': 'error', 'message': 'PIN has expired.'} # if we haven't yet created a key, create one now and return it if pin_record.enter_timestamp and not pin_record.key_created: try: controller = Resource.query.filter(Resource.id == pin_record.controller_id).one() except NoResultFound: return {'status': 'error', 'message': 'Controller not found.'} # create key (_, secret_key) = create_key(pin_record.user_id, controller.organization_id, None, controller.id) pin_record.key_created = True db.session.commit() return {'status': 'ok', 'controller_path': controller.path(), 'secret_key': secret_key} # otherwise no change since before else: return {'status': 'ok'}
def post(self): # create a key for a controller if 'access_as_controller_id' in request.values: try: access_as_controller_id = int(request.values['access_as_controller_id']) except ValueError: abort(400) try: r = Resource.query.filter(Resource.id == access_as_controller_id, not_(Resource.deleted)).one() except NoResultFound: abort(400) if access_level(r.query_permissions()) < ACCESS_LEVEL_WRITE: # require write access to the controller to create a key for it abort(403) organization_id = r.root().id if current_user.is_anonymous: # handle special case of creating a key using a user-associated key (controllers aren't allowed to create keys) key = find_key(request.authorization.password) if key.access_as_user_id: creation_user_id = key.access_as_user_id else: creation_user_id = None abort(403) else: creation_user_id = current_user.id (k, key_text) = create_key(creation_user_id, organization_id, None, access_as_controller_id, key_text=request.values.get('key')) return {'status': 'ok', 'id': k.id, 'secret_key': key_text} # create a key for a users # fix(later): handle case of creating a user-associated key using a user-associated key (see code above) elif 'access_as_user_id' in request.values: access_as_user_id = request.values['access_as_user_id'] try: User.query.filter(User.id == access_as_user_id, not_(User.deleted)).one() except NoResultFound: abort(400) organization_id = request.values['organization_id'] # fix(soon): instead check that (1) access_as_user_id is a member of org and (2) current user has admin access to org; # current check is too strict if current_user.is_anonymous or current_user.role != current_user.SYSTEM_ADMIN: abort(403) (k, key_text) = create_key(current_user.id, organization_id, access_as_user_id, None) return {'status': 'ok', 'id': k.id, 'secret_key': key_text}
def controller_key_resource(user_resource, organization_resource, controller_resource): """A Key that accesses data as a controller. This can be used to make authenticated requests. This generates a random secret key. The secret key in plaintext form is added to the object in a property called "text" (that property is not part of the Key model). """ key, key_text = create_key(user_resource.id, organization_resource.id, None, controller_resource.id) # Stash the key text on the object so the caller can use it for authentication key.text = key_text return key
def _bootstrap_controller_auth(app_config: Dict[str, str]): """Create an organization, controller folder, and API key.""" org_name = app_config.get('TERRAWARE_ORGANIZATION_NAME') org_folder = app_config.get('TERRAWARE_ORGANIZATION_FOLDER') folder_name = app_config.get('TERRAWARE_CONTROLLER_FOLDER') secret_key = app_config.get('TERRAWARE_CONTROLLER_SECRET_KEY') if org_name and org_folder and folder_name and secret_key: org_resource = Resource.query.filter( Resource.name == org_folder, Resource.type == Resource.ORGANIZATION_FOLDER).one_or_none() if org_resource is not None: org_id = org_resource.id else: logger.info('Creating organization %s', org_name) org_id = create_organization(org_name, org_folder) controller_resource = Resource.query.filter( Resource.name == folder_name, Resource.type == Resource.CONTROLLER_FOLDER).one_or_none() if controller_resource is None: logger.info('Creating controller folder %s', folder_name) controller_resource = Resource(name=folder_name, type=Resource.CONTROLLER_FOLDER, parent_id=org_id) db.session.add(controller_resource) key_resource = find_key(secret_key) if key_resource is None: logger.info('Creating secret key for controller') admin_user_id = db.session.query(User.id).order_by( User.id).limit(1).scalar() (key_resource, _) = create_key(admin_user_id, org_id, None, controller_resource.id, secret_key) db.session.commit()