@UserCannotOwnCourse 无法在 Google Classroom 中创建课程

发布于 2025-01-12 08:06:13 字数 6610 浏览 1 评论 0原文

我所拥有的:

  • 服务帐户
  • 已创建域委派(服务帐户的 ID)和 google 课堂权限
  • 创建了一个管理员帐户([电子邮件受保护])
  • 尝试创建一门模拟管理员帐户
  • Google for education 工作区

的课程问题:为什么我收到 @UserCannotOwnCourse 错误?

我的代码:

服务帐户 jwt:

function getAuthServiceAccount(dominio, impersonateEmail) => {
    return new Promise( async (resolve, reject) => {
        let credentials = getCredentials();
        const jwtParams = {
            email : credentials.client_email,
            key   : credentials.private_key,
            scopes : [
                ////// drive
                'https://www.googleapis.com/auth/drive.file',
                'https://www.googleapis.com/auth/drive',
                'https://www.googleapis.com/auth/drive.metadata',
                'https://www.googleapis.com/auth/drive.appdata',
                'https://www.googleapis.com/auth/drive.apps.readonly',
                'https://www.googleapis.com/auth/drive.metadata.readonly',
                'https://www.googleapis.com/auth/drive.photos.readonly',
                'https://www.googleapis.com/auth/drive.readonly',
                ///// classroom
                'https://www.googleapis.com/auth/classroom.courses.readonly',
                'https://www.googleapis.com/auth/classroom.courses',
                'https://www.googleapis.com/auth/classroom.profile.emails',
                'https://www.googleapis.com/auth/classroom.profile.photos',
                'https://www.googleapis.com/auth/classroom.rosters',
                'https://www.googleapis.com/auth/classroom.coursework.me',
                'https://www.googleapis.com/auth/classroom.coursework.me.readonly',
                'https://www.googleapis.com/auth/classroom.coursework.students',
                'https://www.googleapis.com/auth/classroom.coursework.students.readonly',
                'https://www.googleapis.com/auth/classroom.announcements',
                'https://www.googleapis.com/auth/classroom.announcements.readonly',
                'https://www.googleapis.com/auth/classroom.topics',
                'https://www.googleapis.com/auth/classroom.topics.readonly',
                /////// admin directory
                'https://www.googleapis.com/auth/admin.directory.customer',
                'https://www.googleapis.com/auth/admin.directory.customer.readonly',
                'https://www.googleapis.com/auth/admin.directory.domain',
                'https://www.googleapis.com/auth/admin.directory.domain.readonly',
                'https://www.googleapis.com/auth/admin.directory.orgunit',
                'https://www.googleapis.com/auth/admin.directory.orgunit.readonly',
                'https://www.googleapis.com/auth/admin.directory.user',
                'https://www.googleapis.com/auth/admin.directory.user.alias',
                'https://www.googleapis.com/auth/admin.directory.user.alias.readonly',
                'https://www.googleapis.com/auth/admin.directory.user.readonly',
                'https://www.googleapis.com/auth/admin.directory.user.security',
                'https://www.googleapis.com/auth/admin.directory.userschema',
                'https://www.googleapis.com/auth/admin.directory.userschema.readonly',
                'https://www.googleapis.com/auth/admin.directory.group',
                'https://www.googleapis.com/auth/admin.directory.group.member',
                'https://www.googleapis.com/auth/admin.directory.group.member.readonly',
                'https://www.googleapis.com/auth/admin.directory.group.readonly',
                'https://www.googleapis.com/auth/admin.directory.rolemanagement',
                'https://www.googleapis.com/auth/admin.directory.rolemanagement.readonly',
                'https://www.googleapis.com/auth/admin.reports.audit.readonly'
            ]
        };
        if(impersonateEmail) {
            jwtParams.subject = impersonateEmail;
        }
        const jwtClient = new google.auth.JWT(jwtParams);
        jwtClient.authorize(function (err, tokens) {
            if (err) {
                return resolve(false);
            } else {
                jwtClient.dominio = dominio;
                return resolve(jwtClient);
            }
        });
    });
};

创建课程:

function create_course(auth, courseName, room, ownerEmail) {
    return new Promise( async (resolve, reject) => {
        const classroom = google.classroom('v1');
        const data = {
            auth : auth,
            resource : {
                name        : courseName,
                section     : room,
                room        : room,
                ownerId     : ownerEmail,
                courseState : 'ACTIVE'
            }
        };
        classroom.courses.create(data, async (err, response) => {
            if(err) {
                return resolve({msj : `Error!!!`, err : err});
            }
            return resolve({msj : 'course created!', id : response.data.id, code : response.data.enrollmentCode });
        });
    });
}

调用:


let ownerEmail = '[email protected]'; // << NOT the admin email I'm impersonating with

const _AUTH = await getAuthServiceAccount('mydomain.edu', '[email protected]'); // << email to impersonate (subject)
let res = await create_course(_AUTH, 'Math', 'Room 123', ownerEmail);

我收到此错误:

{
    code: 403,
    message: '@UserCannotOwnCourse Please check that the user account exists. If you are attempting to create a course for another user, ensure that you are admin of their domain.',
    errors: [ 
{
    message: '@UserCannotOwnCourse Please check that the user account exists. If you are attempting to create a course for another user, ensure that you are admin of their domain.',
    domain: 'global',
    reason: 'forbidden'
  } 
],
    status: 'PERMISSION_DENIED'
  }

这确实是管理员:

在此处输入图像描述

注意:这适用于具有完全相同配置的另一个工作区,事实上在我管理的许多工作区中这有效,这是我第一次收到此错误。

What I have:

  • Service account
  • Domain delegation created (ID of service account) and google classroom permissions
  • Created a admin account ([email protected])
  • Trying to create a course impersonating with the admin account
  • Google for education workspace

Question: why am I getting @UserCannotOwnCourse error?

My Code:

Service account jwt:

function getAuthServiceAccount(dominio, impersonateEmail) => {
    return new Promise( async (resolve, reject) => {
        let credentials = getCredentials();
        const jwtParams = {
            email : credentials.client_email,
            key   : credentials.private_key,
            scopes : [
                ////// drive
                'https://www.googleapis.com/auth/drive.file',
                'https://www.googleapis.com/auth/drive',
                'https://www.googleapis.com/auth/drive.metadata',
                'https://www.googleapis.com/auth/drive.appdata',
                'https://www.googleapis.com/auth/drive.apps.readonly',
                'https://www.googleapis.com/auth/drive.metadata.readonly',
                'https://www.googleapis.com/auth/drive.photos.readonly',
                'https://www.googleapis.com/auth/drive.readonly',
                ///// classroom
                'https://www.googleapis.com/auth/classroom.courses.readonly',
                'https://www.googleapis.com/auth/classroom.courses',
                'https://www.googleapis.com/auth/classroom.profile.emails',
                'https://www.googleapis.com/auth/classroom.profile.photos',
                'https://www.googleapis.com/auth/classroom.rosters',
                'https://www.googleapis.com/auth/classroom.coursework.me',
                'https://www.googleapis.com/auth/classroom.coursework.me.readonly',
                'https://www.googleapis.com/auth/classroom.coursework.students',
                'https://www.googleapis.com/auth/classroom.coursework.students.readonly',
                'https://www.googleapis.com/auth/classroom.announcements',
                'https://www.googleapis.com/auth/classroom.announcements.readonly',
                'https://www.googleapis.com/auth/classroom.topics',
                'https://www.googleapis.com/auth/classroom.topics.readonly',
                /////// admin directory
                'https://www.googleapis.com/auth/admin.directory.customer',
                'https://www.googleapis.com/auth/admin.directory.customer.readonly',
                'https://www.googleapis.com/auth/admin.directory.domain',
                'https://www.googleapis.com/auth/admin.directory.domain.readonly',
                'https://www.googleapis.com/auth/admin.directory.orgunit',
                'https://www.googleapis.com/auth/admin.directory.orgunit.readonly',
                'https://www.googleapis.com/auth/admin.directory.user',
                'https://www.googleapis.com/auth/admin.directory.user.alias',
                'https://www.googleapis.com/auth/admin.directory.user.alias.readonly',
                'https://www.googleapis.com/auth/admin.directory.user.readonly',
                'https://www.googleapis.com/auth/admin.directory.user.security',
                'https://www.googleapis.com/auth/admin.directory.userschema',
                'https://www.googleapis.com/auth/admin.directory.userschema.readonly',
                'https://www.googleapis.com/auth/admin.directory.group',
                'https://www.googleapis.com/auth/admin.directory.group.member',
                'https://www.googleapis.com/auth/admin.directory.group.member.readonly',
                'https://www.googleapis.com/auth/admin.directory.group.readonly',
                'https://www.googleapis.com/auth/admin.directory.rolemanagement',
                'https://www.googleapis.com/auth/admin.directory.rolemanagement.readonly',
                'https://www.googleapis.com/auth/admin.reports.audit.readonly'
            ]
        };
        if(impersonateEmail) {
            jwtParams.subject = impersonateEmail;
        }
        const jwtClient = new google.auth.JWT(jwtParams);
        jwtClient.authorize(function (err, tokens) {
            if (err) {
                return resolve(false);
            } else {
                jwtClient.dominio = dominio;
                return resolve(jwtClient);
            }
        });
    });
};

Create course:

function create_course(auth, courseName, room, ownerEmail) {
    return new Promise( async (resolve, reject) => {
        const classroom = google.classroom('v1');
        const data = {
            auth : auth,
            resource : {
                name        : courseName,
                section     : room,
                room        : room,
                ownerId     : ownerEmail,
                courseState : 'ACTIVE'
            }
        };
        classroom.courses.create(data, async (err, response) => {
            if(err) {
                return resolve({msj : `Error!!!`, err : err});
            }
            return resolve({msj : 'course created!', id : response.data.id, code : response.data.enrollmentCode });
        });
    });
}

Invocation:


let ownerEmail = '[email protected]'; // << NOT the admin email I'm impersonating with

const _AUTH = await getAuthServiceAccount('mydomain.edu', '[email protected]'); // << email to impersonate (subject)
let res = await create_course(_AUTH, 'Math', 'Room 123', ownerEmail);

I get this error:

{
    code: 403,
    message: '@UserCannotOwnCourse Please check that the user account exists. If you are attempting to create a course for another user, ensure that you are admin of their domain.',
    errors: [ 
{
    message: '@UserCannotOwnCourse Please check that the user account exists. If you are attempting to create a course for another user, ensure that you are admin of their domain.',
    domain: 'global',
    reason: 'forbidden'
  } 
],
    status: 'PERMISSION_DENIED'
  }

It's really admin:

enter image description here

Note: This works in another workspace with the very same configuration, matter of fact in many workspaces I manage this works, this is the first time I get this error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文