-1

Hi Im developing a system wherein we integrate google classroom. So Im using the classroom API when turning in student submission. I got an error that says permission denied. I read from other article too that it got permission denied when coursework/assignment itself is not created using the Google Script or using the Classroom API. So i created another coursework/assignment within that system using the classroom api. i tried the function modifyAttachment, it works well but when i used the turnIn function permission denied. Im using laravel framework.

My code:

        $appName = 'PROGRAMA';
        $client = new Google_Client();
        $client->setApplicationName($appName);
        $client->setScopes([
            Google_Service_Classroom::CLASSROOM_COURSES,
            Google_Service_Classroom::CLASSROOM_COURSES_READONLY,
            Google_Service_Classroom::CLASSROOM_COURSEWORK_ME,
            Google_Service_Classroom::CLASSROOM_COURSEWORK_STUDENTS,
            Google_Service_Classroom::CLASSROOM_COURSEWORK_STUDENTS_READONLY,
            Google_Service_Classroom::CLASSROOM_ROSTERS,
            Google_Service_Classroom::CLASSROOM_STUDENT_SUBMISSIONS_ME_READONLY,
            // Google_Service_Classroom::CLASSROOM_ANNOUNCEMENTS_READONLY,
            Google_Service_Classroom::CLASSROOM_COURSEWORKMATERIALS_READONLY,
            "https://www.googleapis.com/auth/drive",
            "https://www.googleapis.com/auth/drive.file",
            "https://www.googleapis.com/auth/classroom.coursework.me"                             
          ]);
        $client->setAuthConfig(storage_path().'/programa-classroom-43bf78f68328.json');
        
        // // this is needed only if you need to perform
        // // domain-wide admin actions, and this must be
        // // an admin account on the domain; it is not 
        // // necessary in your example but provided for others
        $client->setSubject('programa_dev@gbox.adnu.edu.ph');

        $service  = new Google_Service_Classroom($client);
        
        $driveservice = new Google_Service_Drive($client);

        $driveID = $service->courses_courseWork_studentSubmissions->listCoursesCourseWorkStudentSubmissions(session('courseInfo')['courseID'], 
        session('courseInfo')['courseWorkID'], $optParams = array("userId" => session('courseInfo')['userID']));

        $file = new Google_Service_Drive_DriveFile();
        $file->setName(session('courseInfo')['StudentName'] . '-' . session('courseInfo')['AssignmentTitle']);
        $assignWork = $request->file('courseAssignment');
        $filename = session('courseInfo')['StudentName'] . '-' .$assignWork->getClientOriginalName();
        $path = storage_path(). 'CourseWork/' . session('courseInfo')['AssignmentTitle'];
        $fileAssignment = $request->file('courseAssignment')->storeAs('public',$filename);
        $contents = Storage::disk('public')->path($filename);
        foreach($driveID as $row)
        {
            if($row->state == "CREATED")
            {
                $FileID = $row->assignmentSubmission['attachments'][0]['driveFile']["id"];
            }
            else
            {
                $result = $driveservice->files->create(
                    $file,
                    [
                    'data' => file_get_contents($contents),
                    'mimeType' => 'application/octet-stream',
                    'uploadType' => 'multipart '
                    ]
                );

                $FileID = $result->id;

                $modifyParams = array(
                    "addAttachments" => array(
                        "driveFile" => array(
                            "id" => $FileID
                        )
                    )
                );

            $data['modify'] = $service->courses_courseWork_studentSubmissions->modifyAttachments(session('courseInfo')['courseID'], 
            session('courseInfo')['courseWorkID'], session('courseInfo')['submissionID'], new Google_Service_Classroom_ModifyAttachmentsRequest($modifyParams));
            }
        }
        
    $data['turnIn'] = $service->courses_courseWork_studentSubmissions->turnIn(session('courseInfo')['courseID'], session('courseInfo')['courseWorkID'], 
        session('courseInfo')['submissionID'], new Google_Service_Classroom_TurnInStudentSubmissionRequest());

error message here

sky
  • 1
  • 2
  • Please edit your question and include [example] – Linda Lawton - DaImTo May 29 '21 at 16:31
  • Can you please confirm whether you are authenticating as a student that owns this student submission? That's the only account that should be able to execute this, so taking into account the error message you are getting, I guess that's the cause of your issue. – Iamblichus May 31 '21 at 07:21

3 Answers3

0

Lets see if i can explain your issue without seeing your code.

What you need to understand is the diffrence between private and public data. Public data is data that is not owned by anyone private data is owned by someone and you need that persons permission in order to access it.

If you check Classroom api each method is represented here.

Each method that accesses private user data will tell you what access you need in order to access it

enter image description here

When you wrote your application you added something called scopes, these define the scope of access your application needs in order to run. The error message you are getting means that you are trying to access a method that you have not been granted to use yet. So you need to fix theses and request authorization of the user again.

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • oh sorry i forgot to mention, we added those scopes already. we added a lot of scopes already. https://www.googleapis.com/auth/classroom.coursework.me https://www.googleapis.com/auth/classroom.coursework.students https://www.googleapis.com/auth/classroom.coursework.me and a lot more too... – sky May 29 '21 at 17:30
  • Yes but did you reauthorize your application. You need to remove previous authorization and request authorization of the user every time you change the scopes. – Linda Lawton - DaImTo May 29 '21 at 19:12
0

We solved the problem. My error was I was using the service account in executing the turnIn function that it should be the student that owns the submission. So we reauthenticate it for student and use that account in executing the turnIn function.

Thank you so much for those who helped.

sky
  • 1
  • 2
0

As the method documentation specify, courses.courseWork.studentSubmissions.turnIn can only be called by:

the student that owns the specified student submission.

If using a service account with domain-wide delegation, you should impersonate that student. Otherwise, the only option is executing this as the student that owns the submission.

Iamblichus
  • 18,540
  • 2
  • 11
  • 27